Init commit from tizen 2.4 56/41156/4 submit/tizen/20150611.115343
authorky85.kim <ky85.kim@samsung.com>
Thu, 11 Jun 2015 10:16:03 +0000 (19:16 +0900)
committerky85.kim <ky85.kim@samsung.com>
Thu, 11 Jun 2015 11:23:01 +0000 (20:23 +0900)
Change-Id: I9bdeee67d63fb2fedf5ea77944bf8f7000c88ba6

73 files changed:
AUTHORS [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
LICENSE [new file with mode: 0644]
NOTICE [new file with mode: 0644]
changelog [new file with mode: 0644]
client/CMakeLists.txt [new file with mode: 0644]
client/vc.c [new file with mode: 0644]
client/vc_client.c [new file with mode: 0644]
client/vc_client.h [new file with mode: 0644]
client/vc_dbus.c [new file with mode: 0644]
client/vc_dbus.h [new file with mode: 0644]
client/vc_mgr.c [new file with mode: 0644]
client/vc_mgr_client.c [new file with mode: 0644]
client/vc_mgr_client.h [new file with mode: 0644]
client/vc_mgr_dbus.c [new file with mode: 0644]
client/vc_mgr_dbus.h [new file with mode: 0644]
client/vc_setting.c [new file with mode: 0644]
client/vc_widget.c [new file with mode: 0644]
client/vc_widget_client.c [new file with mode: 0644]
client/vc_widget_client.h [new file with mode: 0644]
client/vc_widget_dbus.c [new file with mode: 0644]
client/vc_widget_dbus.h [new file with mode: 0644]
common/vc_command.c [new file with mode: 0644]
common/vc_command.h [new file with mode: 0644]
common/vc_config_mgr.c [new file with mode: 0644]
common/vc_config_mgr.h [new file with mode: 0644]
common/vc_config_parser.c [new file with mode: 0644]
common/vc_config_parser.h [new file with mode: 0644]
common/vc_defs.h [new file with mode: 0644]
common/vc_info_parser.c [new file with mode: 0644]
common/vc_info_parser.h [new file with mode: 0644]
common/vc_main.h [new file with mode: 0644]
doc/doxyfile [new file with mode: 0644]
doc/images/capi_uix_voice_control_service_state_diagram.png [new file with mode: 0644]
doc/images/capi_uix_voice_control_state_diagram.png [new file with mode: 0644]
doc/uix_vc_doc.h [new file with mode: 0644]
include/CMakeLists.txt [new file with mode: 0644]
include/voice-control-engine.pc.in [new file with mode: 0644]
include/voice-control-manager.pc.in [new file with mode: 0644]
include/voice-control-setting.pc.in [new file with mode: 0644]
include/voice-control-widget.pc.in [new file with mode: 0644]
include/voice-control.pc.in [new file with mode: 0644]
include/voice_control.h [new file with mode: 0644]
include/voice_control_authority.h [new file with mode: 0644]
include/voice_control_command.h [new file with mode: 0644]
include/voice_control_command_expand.h [new file with mode: 0644]
include/voice_control_common.h [new file with mode: 0644]
include/voice_control_key_defines.h [new file with mode: 0644]
include/voice_control_manager.h [new file with mode: 0644]
include/voice_control_plugin_engine.h [new file with mode: 0644]
include/voice_control_setting.h [new file with mode: 0644]
include/voice_control_widget.h [new file with mode: 0644]
packaging/voice-control-devel.manifest [new file with mode: 0644]
packaging/voice-control.manifest [new file with mode: 0644]
packaging/voice-control.spec [new file with mode: 0644]
server/CMakeLists.txt [new file with mode: 0644]
server/vcd_client_data.c [new file with mode: 0644]
server/vcd_client_data.h [new file with mode: 0644]
server/vcd_config.c [new file with mode: 0644]
server/vcd_config.h [new file with mode: 0644]
server/vcd_dbus.c [new file with mode: 0644]
server/vcd_dbus.h [new file with mode: 0644]
server/vcd_dbus_server.c [new file with mode: 0644]
server/vcd_dbus_server.h [new file with mode: 0644]
server/vcd_engine_agent.c [new file with mode: 0644]
server/vcd_engine_agent.h [new file with mode: 0644]
server/vcd_main.c [new file with mode: 0644]
server/vcd_main.h [new file with mode: 0644]
server/vcd_recorder.c [new file with mode: 0644]
server/vcd_recorder.h [new file with mode: 0644]
server/vcd_server.c [new file with mode: 0644]
server/vcd_server.h [new file with mode: 0644]
vc-config.xml [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..39d4ccc
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,4 @@
+Dongyeol Lee <dy3.lee@samsung.com>
+Kwangyoun Kim <ky85.kim@samsung.com>
+Sehwan Park <sehwan@samsung.com>
+WonNam Jang <wn.jang@samsung.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4807bfb
--- /dev/null
@@ -0,0 +1,55 @@
+#
+# Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+#
+# Licensed under the Apache License, Version 2.0 (the License);
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an AS IS BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+# @file        CMakeLists.txt
+# @author      Dongyeol Lee (dy3.lee@samsung.com)
+# @version     0.1
+# @brief
+
+# Check minimum CMake version
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+
+# Project name
+PROJECT(vc)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+SET(EXEC_PREFIX "${PREFIX}")
+SET(VERSION 0.2.7)
+
+# pkg config tool
+INCLUDE(FindPkgConfig)
+
+## Include common directory ##
+INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/common")
+INCLUDE_DIRECTORIES("${CMAKE_SOURCE_DIR}/include")
+
+## Dependent packages ##
+INCLUDE(FindPkgConfig)
+pkg_check_modules(pkgs REQUIRED  
+    aul capi-base-common capi-media-audio-io capi-media-sound-manager capi-network-bluetooth
+    dbus-1 dlog ecore ecore-x glib-2.0 libprivilege-control libxml-2.0 vconf
+)
+
+## API ##
+ADD_SUBDIRECTORY(include)
+
+## Client library ##
+ADD_SUBDIRECTORY(client)
+
+## Server daemon ##
+ADD_SUBDIRECTORY(server)
+
+## config ##
+INSTALL(FILES ${CMAKE_SOURCE_DIR}/vc-config.xml DESTINATION /usr/lib/voice/vc/1.0)
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.
diff --git a/NOTICE b/NOTICE
new file mode 100644 (file)
index 0000000..9424bf6
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) 2012-2015 Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE file for Apache License terms and conditions.
diff --git a/changelog b/changelog
new file mode 100644 (file)
index 0000000..fa7af77
--- /dev/null
+++ b/changelog
@@ -0,0 +1,118 @@
+vc (0.2.7) -- Wed, 21 Jan 2015
+
+  * Add result message from engine (Wonnam Jang <wn.jang@samsung.com>)
+  * Change sequence for engine and recorder stop (Kwangyoun Kim <ky85.kim@samsung.com>)
+  * Add authority feature (Kwangyoun Kim <ky85.kim@samsung.com>)
+
+vc (0.2.6) -- Mon, 08 Dec 2014
+  
+  * Update API (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Support Multi-results (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Improve command structure (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add cancel by sound interrupt (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.2.5) -- Thu, 20 Sep 2014
+
+  * Add audio session (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add new list command APIs (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Update command operation (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Apply list api for clients (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.2.4) -- Mon, 11 Aug 2014
+
+  * Add audio in type selection (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add retry code for info files (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add console app (Kwangyoun Kim <ky85.kim@samsung.com>)
+
+vc (0.2.3) -- Thu, 24 Jul 2014
+
+  * Fix recognition cancel bug (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.2.2) -- Thu, 03 Jul 2014
+
+  * Update engine API for silence (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Support only text result (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Fix bug on default config valid check (Kwangyoun Kim <ky85.kim@samsung.com>)
+  * Fix security issue (Kwangyoun Kim <ky85.kim@samsung.com>)
+
+vc (0.2.1) -- Wed, 28 May 2014
+
+  * Fix crash issue of result (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Fix multi-language bug (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Update test app for multi-language (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Apply exclusive option (Kwangyoun Kim <ky85.kim@samsung.com>)
+
+vc (0.2.0) -- Fri, 23 May 2014
+
+  * Add manager client(Dongyeol Lee <dy3.lee@samsung.com>)
+  * Support to select conflict results by manager (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Support to add rule of client recognition request (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Update widget result callback (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add sevice state (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Update XML file of runtime command and info(Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add exclusive command option (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add system command group and remove interrupt command group (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add non-fixed command type (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Remove trigger mode (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Remove wakeup command (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Remove speech-to-text feature (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Remove floating button (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3-11) -- Fri, 07 Feb 2013
+
+  * Support wakeup command (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Support speech-to-text feature (Dongyeol Lee <dy3.lee@samsung.com>)
+  * Add test application for voice control (Kwangyoun Kim <ky85.kim@samsung.com>)
+  * Clean up CMakeList (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3-10) -- Wed, 16 Oct 2013
+
+  * Clean up code (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3-9) -- Tue, 10 Sep 2013
+
+  * Fix bug on floating button state (Kwangyoun Kim <ky85.kim@samsung.com>)
+
+vc (0.1.3-8) -- Fri, 09 Aug 2013
+
+  * Add new trigger both floating button and continuous recongtion (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3-7) -- Thu, 25 Jul 2013
+
+  * Fix to change to get commands from client (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3-6) -- Tue, 09 Apr 2013
+
+  * Fix bug of request set command (Kwangyoun Kim <ky85.kim@samsung.com>)
+
+vc (0.1.3-5) -- Thu, 04 Apr 2013
+
+  * Fix bug of recording fail (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3-4) -- Wed, 03 Apr 2013
+
+  * Add time out in recording (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3-3) -- Wed, 03 Apr 2013
+
+  * Add mute sound in recording state (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3-2) -- Wed, 27 Mar 2013
+
+  * Fix bs issue to tranfer command from client to server (Dongyeol Lee <dy3.lee@samsung.com>)
+  
+vc (0.1.3-1) -- Thu, 14 Mar 2013
+
+  * Support key generation (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.3) -- Fri, 08 Mar 2013
+
+  * Support multi-language command (Dongyeol Lee <dy3.lee@samsung.com>)
+
+vc (0.1.2) -- Thu, 28 Feb 2013
+
+  * Upload initial version (Kwangyoun Kim <ky85.kim@samsung.com>)
+
+vc (0.1.1) -- Thu, 26 Apr 2012
+
+  * Initial Release (Dongyeol Lee <dy3.lee@samsung.com>)
diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt
new file mode 100644 (file)
index 0000000..33c0e15
--- /dev/null
@@ -0,0 +1,66 @@
+SET(SRCS 
+       vc.c
+       vc_client.c
+       vc_dbus.c
+       ../common/vc_command.c
+       ../common/vc_config_mgr.c
+       ../common/vc_config_parser.c
+       ../common/vc_info_parser.c
+)
+
+SET(SETTING_SRCS
+       vc_setting.c
+       ../common/vc_config_mgr.c
+       ../common/vc_config_parser.c
+)
+
+SET(WIDGET_SRCS
+       vc_widget.c
+       vc_widget_client.c
+       vc_widget_dbus.c
+       ../common/vc_command.c
+       ../common/vc_config_mgr.c
+       ../common/vc_config_parser.c
+       ../common/vc_info_parser.c
+)
+
+SET(MANAGER_SRCS
+       vc_mgr.c
+       vc_mgr_client.c
+       vc_mgr_dbus.c
+       ../common/vc_command.c
+       ../common/vc_config_mgr.c
+       ../common/vc_config_parser.c
+       ../common/vc_info_parser.c
+)
+
+#INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR})
+#INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include)
+#INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/common)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+## voice control library ##
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRCS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS})
+
+## voice control setting library ##
+ADD_LIBRARY("${PROJECT_NAME}_setting" SHARED ${SETTING_SRCS})
+TARGET_LINK_LIBRARIES("${PROJECT_NAME}_setting" ${pkgs_LDFLAGS})
+
+## voice control widget library ##
+ADD_LIBRARY("${PROJECT_NAME}_widget" SHARED ${WIDGET_SRCS})
+TARGET_LINK_LIBRARIES("${PROJECT_NAME}_widget" ${pkgs_LDFLAGS})
+
+## voice control manager library ##
+ADD_LIBRARY("${PROJECT_NAME}_manager" SHARED ${MANAGER_SRCS})
+TARGET_LINK_LIBRARIES("${PROJECT_NAME}_manager" ${pkgs_LDFLAGS})
+
+## Install library files ##
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries)
+INSTALL(TARGETS "${PROJECT_NAME}_setting" DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries)
+INSTALL(TARGETS "${PROJECT_NAME}_widget" DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries)
+INSTALL(TARGETS "${PROJECT_NAME}_manager" DESTINATION ${LIBDIR} COMPONENT RuntimeLibraries)
diff --git a/client/vc.c b/client/vc.c
new file mode 100644 (file)
index 0000000..a513569
--- /dev/null
@@ -0,0 +1,1925 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_client.h"
+#include "vc_command.h"
+#include "vc_config_mgr.h"
+#include "vc_dbus.h"
+#include "vc_info_parser.h"
+#include "vc_main.h"
+#include "voice_control.h"
+#include "voice_control_authority.h"
+#include "voice_control_command.h"
+#include "voice_control_command_expand.h"
+
+
+static bool g_is_daemon_started = false;
+
+static Ecore_Timer* g_connect_timer = NULL;
+
+static vc_h g_vc = NULL;
+
+static Ecore_Event_Handler* g_focus_in_hander = NULL;
+static Ecore_Event_Handler* g_focus_out_hander = NULL;
+
+Eina_Bool __vc_notify_state_changed(void *data);
+Eina_Bool __vc_notify_error(void *data);
+
+
+static const char* __vc_get_error_code(vc_error_e err)
+{
+       switch(err) {
+               case VC_ERROR_NONE:                     return "VC_ERROR_NONE";                 break;
+               case VC_ERROR_OUT_OF_MEMORY:            return "VC_ERROR_OUT_OF_MEMORY";        break;
+               case VC_ERROR_IO_ERROR:                 return "VC_ERROR_IO_ERROR";             break;
+               case VC_ERROR_INVALID_PARAMETER:        return "VC_ERROR_INVALID_PARAMETER";    break;
+               case VC_ERROR_TIMED_OUT:                return "VC_ERROR_TIMED_OUT";            break;
+               case VC_ERROR_RECORDER_BUSY:            return "VC_ERROR_RECORDER_BUSY";        break;
+               case VC_ERROR_INVALID_STATE:            return "VC_ERROR_INVALID_STATE";        break;
+               case VC_ERROR_INVALID_LANGUAGE:         return "VC_ERROR_INVALID_LANGUAGE";     break;
+               case VC_ERROR_ENGINE_NOT_FOUND:         return "VC_ERROR_ENGINE_NOT_FOUND";     break;
+               case VC_ERROR_OPERATION_FAILED:         return "VC_ERROR_OPERATION_FAILED";     break;
+               default:                                return "Invalid error code";            break;
+       }
+       return NULL;
+}
+
+static int __vc_convert_config_error_code(vc_config_error_e code)
+{
+       if (code == VC_CONFIG_ERROR_NONE)                       return VC_ERROR_NONE;
+       if (code == VC_CONFIG_ERROR_OUT_OF_MEMORY)              return VC_ERROR_OUT_OF_MEMORY;
+       if (code == VC_CONFIG_ERROR_IO_ERROR)                   return VC_ERROR_IO_ERROR;
+       if (code == VC_CONFIG_ERROR_INVALID_PARAMETER)          return VC_ERROR_INVALID_PARAMETER;
+       if (code == VC_CONFIG_ERROR_INVALID_STATE)              return VC_ERROR_INVALID_STATE;
+       if (code == VC_CONFIG_ERROR_INVALID_LANGUAGE)           return VC_ERROR_INVALID_LANGUAGE;
+       if (code == VC_CONFIG_ERROR_ENGINE_NOT_FOUND)           return VC_ERROR_ENGINE_NOT_FOUND;
+       if (code == VC_CONFIG_ERROR_OPERATION_FAILED)           return VC_ERROR_OPERATION_FAILED;
+
+       return VC_ERROR_NONE;
+}
+
+static void __vc_lang_changed_cb(const char* before_lang, const char* current_lang)
+{
+       SECURE_SLOG(LOG_DEBUG, TAG_VCC, "Lang changed : Before lang(%s) Current lang(%s)", 
+               before_lang, current_lang);
+
+       vc_current_language_changed_cb callback;
+       void* lang_user_data;
+       vc_client_get_current_lang_changed_cb(g_vc, &callback, &lang_user_data);
+
+       if (NULL != callback) {
+               vc_client_use_callback(g_vc);
+               callback(before_lang, current_lang, lang_user_data);
+               vc_client_not_use_callback(g_vc);
+               SLOG(LOG_DEBUG, TAG_VCC, "Language changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCC, "[WARNING] Language changed callback is null");
+       }
+
+       return;
+}
+
+static void __vc_service_state_changed_cb(int before_state, int current_state)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "Service State changed : Before(%d) Current(%d)", 
+               before_state, current_state);
+
+       /* Save service state */
+       vc_client_set_service_state(g_vc, (vc_service_state_e)current_state);
+
+       vc_service_state_changed_cb service_callback = NULL;
+       void* service_user_data;
+       vc_client_get_service_state_changed_cb(g_vc, &service_callback, &service_user_data);
+
+       if (NULL != service_callback) {
+               vc_client_use_callback(g_vc);
+               service_callback((vc_service_state_e)before_state, (vc_service_state_e)current_state, service_user_data);
+               vc_client_not_use_callback(g_vc);
+               SLOG(LOG_DEBUG, TAG_VCC, "Service state changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCC, "[WARNING] State changed callback is NULL");
+       }
+
+       return;
+}
+
+int vc_initialize()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Initialize");
+
+       /* check handle */
+       if (true == vc_client_is_valid(g_vc)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Already initialized");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (0 < vc_client_get_count()) {
+               SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Already initialized");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (0 != vc_dbus_open_connection()) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to open connection");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (0 != vc_client_create(&g_vc)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to create client!!!!!");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       int ret = vc_config_mgr_initialize(g_vc->handle);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to init config manager : %s", 
+                       __vc_get_error_code(__vc_convert_config_error_code(ret)));
+               vc_client_destroy(g_vc);
+               return __vc_convert_config_error_code(ret);
+       }
+
+       ret = vc_config_mgr_set_lang_cb(g_vc->handle, __vc_lang_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set config changed : %d", ret);
+               vc_config_mgr_finalize(g_vc->handle);
+               vc_client_destroy(g_vc);
+               return __vc_convert_config_error_code(ret);
+       }
+
+       ret = vc_config_mgr_set_service_state_cb(g_vc->handle, __vc_service_state_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set service change callback : %d", ret);
+               vc_config_mgr_unset_lang_cb(g_vc->handle);
+               vc_config_mgr_finalize(g_vc->handle);
+               vc_client_destroy(g_vc);
+               return __vc_convert_config_error_code(ret);
+       }
+
+       int service_state = -1;
+       if (0 != vc_config_mgr_get_service_state(&service_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get service state");
+               vc_config_mgr_finalize(g_vc->handle);
+               vc_client_destroy(g_vc);
+               return __vc_convert_config_error_code(ret);
+       }
+
+       vc_client_set_service_state(g_vc, service_state);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "[Success] pid(%d)", g_vc->handle);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+
+static void __vc_internal_unprepare()
+{
+       /* return authority */
+       vc_auth_state_e state = VC_AUTH_STATE_NONE;
+       if (0 != vc_client_get_auth_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state");
+       }
+
+       if (VC_AUTH_STATE_NONE != state) {
+               if (0 != vc_auth_disable()) {
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to auth disable");
+               }
+       }
+
+       int ret = vc_dbus_request_finalize(g_vc->handle);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request finalize : %s", __vc_get_error_code(ret));
+       }
+
+       g_is_daemon_started = false;
+
+       ecore_event_handler_del(g_focus_in_hander);
+       ecore_event_handler_del(g_focus_out_hander);
+
+       vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_FOREGROUND);
+       vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_BACKGROUND);
+
+       return;
+}
+
+int vc_deinitialize()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Deinitialize");
+
+       if (false == vc_client_is_valid(g_vc)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] NOT initialized");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_state_e state;
+       vc_client_get_client_state(g_vc, &state);
+
+       /* check state */
+       switch (state) {
+       case VC_STATE_READY:
+               __vc_internal_unprepare();
+               /* no break. need to next step*/
+       case VC_STATE_INITIALIZED:
+               if (NULL != g_connect_timer) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "Connect Timer is deleted");
+                       ecore_timer_del(g_connect_timer);
+               }
+
+               vc_config_mgr_unset_service_state_cb(g_vc->handle);
+               vc_config_mgr_unset_lang_cb(g_vc->handle);
+               vc_config_mgr_finalize(g_vc->handle);
+
+               /* Free client resources */
+               vc_client_destroy(g_vc);
+               g_vc = NULL;
+               break;
+       case VC_STATE_NONE:
+               break;
+       default:
+               break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "Success: destroy");
+
+       if (0 != vc_dbus_close_connection()) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to close connection");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+
+static Eina_Bool __notify_auth_changed_cb(void *data)
+{
+       vc_auth_state_changed_cb callback = NULL;
+       void* user_data;
+
+       vc_client_get_auth_state_changed_cb(g_vc, &callback, &user_data);
+
+       vc_auth_state_e before = -1;
+       vc_auth_state_e current = -1;
+       
+       vc_client_get_before_auth_state(g_vc, &before, &current);
+
+       if (NULL != callback) {
+               vc_client_use_callback(g_vc);
+               callback(before, current, user_data);
+               vc_client_not_use_callback(g_vc);
+               SLOG(LOG_DEBUG, TAG_VCC, "Auth state changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCC, "[WARNING] Auth state changed callback is null");
+       }
+
+       return EINA_FALSE;
+
+
+}
+
+static Eina_Bool __vc_x_event_window_focus_in(void *data, int type, void *event) 
+{ 
+       Ecore_X_Event_Window_Focus_In *e;
+
+       e = event;
+
+       int xid = -1;
+       if (0 != vc_client_get_xid(g_vc, &xid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get current xid");
+               return ECORE_CALLBACK_PASS_ON;
+       }
+
+       if (e->win == (Ecore_X_Window)xid) {
+               SLOG(LOG_DEBUG, TAG_VCC, "Focus in : pid(%d) xid(%d)", getpid(), xid);
+               int ret = vc_config_mgr_set_foreground(getpid(), true);
+               if (0 != ret) {
+                       ret = vc_config_convert_error_code((vc_config_error_e)ret);
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set focus in : %s", __vc_get_error_code(ret));
+               }
+               /* set authority valid */
+               vc_auth_state_e state = VC_AUTH_STATE_NONE;
+               if (0 != vc_client_get_auth_state(g_vc, &state)) {
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state");
+               }
+               if (VC_AUTH_STATE_INVALID == state) {
+                       vc_client_set_auth_state(g_vc, VC_AUTH_STATE_VALID);
+                       
+                       /* notify auth changed cb */
+                       ecore_timer_add(0, __notify_auth_changed_cb, NULL);
+               }
+       }
+
+       return ECORE_CALLBACK_PASS_ON;
+} 
+
+static Eina_Bool __vc_x_event_window_focus_out(void *data, int type, void *event) 
+{ 
+       Ecore_X_Event_Window_Focus_In *e;
+
+       e = event;
+
+       int xid = -1;
+       if (0 != vc_client_get_xid(g_vc, &xid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get current xid");
+               return ECORE_CALLBACK_PASS_ON;
+       }
+
+       if (e->win == (Ecore_X_Window)xid) {
+               SLOG(LOG_DEBUG, TAG_VCC, "Focus out : pid(%d) xid(%d)", getpid(), xid);
+               int ret = vc_config_mgr_set_foreground(getpid(), false);
+               if (0 != ret) {
+                       ret = vc_config_convert_error_code((vc_config_error_e)ret);
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set focus out : %s", __vc_get_error_code(ret));
+               }
+               /* set authority valid */
+               vc_auth_state_e state = VC_AUTH_STATE_NONE;
+               if (0 != vc_client_get_auth_state(g_vc, &state)) {
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state");
+               }
+               if (VC_AUTH_STATE_VALID == state) {
+                       vc_client_set_auth_state(g_vc, VC_AUTH_STATE_INVALID);
+
+                       /* notify authority changed cb */
+                       ecore_timer_add(0, __notify_auth_changed_cb, NULL);
+               }
+       }
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+static void __vc_fork_vc_daemon()
+{
+       int pid, i;
+       pid = fork();
+
+       switch(pid) {
+       case -1:
+               SLOG(LOG_ERROR, TAG_VCC, "Fail to create daemon");
+               break;
+       case 0:
+               setsid();
+               for (i = 0;i < _NSIG;i++)
+                       signal(i, SIG_DFL);
+
+               execl(VC_DAEMON_PATH, VC_DAEMON_PATH, NULL);
+               break;
+       default:
+               break;
+       }
+       return;
+}
+       
+static Eina_Bool __vc_connect_daemon(void *data)
+{
+       /* Send hello */
+       if (0 != vc_dbus_request_hello()) {
+               if (false == g_is_daemon_started) {
+                       g_is_daemon_started = true;
+                       __vc_fork_vc_daemon();
+               }
+               return EINA_TRUE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Connect daemon");
+
+       /* request initialization */
+       int ret = -1;
+       int mgr_pid = -1;
+       ret = vc_dbus_request_initialize(g_vc->handle, &mgr_pid);
+       if (VC_ERROR_ENGINE_NOT_FOUND == ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to initialize : %s", __vc_get_error_code(ret));
+
+               vc_client_set_error(g_vc, VC_ERROR_ENGINE_NOT_FOUND);
+               ecore_timer_add(0, __vc_notify_error, g_vc);
+
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, "  ");
+               return EINA_FALSE;
+
+       } else if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to initialize :%s", __vc_get_error_code(ret));
+
+               vc_client_set_error(g_vc, VC_ERROR_TIMED_OUT);
+               ecore_timer_add(0, __vc_notify_error, g_vc);
+
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, "  ");
+               return EINA_FALSE;
+       } else {
+               /* Success to connect */
+       }
+
+       g_connect_timer = NULL;
+
+       g_focus_in_hander = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_IN, __vc_x_event_window_focus_in, NULL);
+       g_focus_out_hander = ecore_event_handler_add(ECORE_X_EVENT_WINDOW_FOCUS_OUT, __vc_x_event_window_focus_out, NULL);
+
+       vc_client_set_client_state(g_vc, VC_STATE_READY);
+       ecore_timer_add(0, __vc_notify_state_changed, g_vc);
+
+       vc_client_set_mgr_pid(g_vc, mgr_pid);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, "  ");
+
+       return EINA_FALSE;
+}
+
+int vc_prepare()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Prepare");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'CREATED'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       g_is_daemon_started = false;
+
+       g_connect_timer = ecore_timer_add(0, __vc_connect_daemon, NULL);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_unprepare()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Unprepare");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       __vc_internal_unprepare();
+
+       vc_client_set_client_state(g_vc, VC_STATE_INITIALIZED);
+       ecore_timer_add(0, __vc_notify_state_changed, g_vc);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_foreach_supported_languages(vc_supported_language_cb callback, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Foreach Supported Language");
+
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is NULL");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       ret = vc_config_mgr_get_language_list(callback, user_data);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get languages : %s", __vc_get_error_code(ret));
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+
+
+int vc_get_current_language(char** language)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Get Current Language");
+
+       if (NULL == language) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is NULL");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       ret = vc_config_mgr_get_default_language(language);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get current languages : %s", __vc_get_error_code(ret));
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+int vc_get_state(vc_state_e* state)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Get State");
+
+       if (NULL == state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e temp;
+       if (0 != vc_client_get_client_state(g_vc, &temp)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       *state = temp;
+
+       switch(*state) {
+               case VC_STATE_NONE:             SLOG(LOG_DEBUG, TAG_VCC, "Current state is 'None'");            break;
+               case VC_STATE_INITIALIZED:      SLOG(LOG_DEBUG, TAG_VCC, "Current state is 'Created'");         break;
+               case VC_STATE_READY:            SLOG(LOG_DEBUG, TAG_VCC, "Current state is 'Ready'");           break;
+               default:                        SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid state");              break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_get_service_state(vc_service_state_e* state)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Get Service State");
+
+       if (NULL == state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e temp;
+       if (0 != vc_client_get_client_state(g_vc, &temp)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* get service state */
+       vc_service_state_e service_state;
+       if (0 != vc_client_get_service_state(g_vc, &service_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get service state");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       *state = service_state;
+
+       switch(*state) {
+       case VC_SERVICE_STATE_NONE:             SLOG(LOG_DEBUG, TAG_VCC, "Current service state is 'None'");            break;
+       case VC_SERVICE_STATE_READY:            SLOG(LOG_DEBUG, TAG_VCC, "Current service state is 'Ready'");           break;
+       case VC_SERVICE_STATE_RECORDING:        SLOG(LOG_DEBUG, TAG_VCC, "Current service state is 'Recording'");       break;
+       case VC_SERVICE_STATE_PROCESSING:       SLOG(LOG_DEBUG, TAG_VCC, "Current service state is 'Processing'");      break;
+       default:                                SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid state");                      break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+
+#if 0 
+int vc_set_window_id(int wid)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Set Window id");
+
+       if (0 >= wid) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is invalid");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (0 != vc_client_set_xid(g_vc, wid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not valid");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check if current xid is top window */
+       int ret = -1;
+       if ((Ecore_X_Window)wid == ecore_x_window_focus_get()) {
+               /* Set current pid */
+               ret = vc_config_mgr_set_foreground(getpid(), true);
+               if (0 != ret) {
+                       ret = vc_config_convert_error_code((vc_config_error_e)ret);
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set focus in : %s", __vc_get_error_code(ret));
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+int vc_get_window_id(int* wid)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Get Window id");
+
+       if (NULL == wid) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is NULL");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (0 != vc_client_get_xid(g_vc, wid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not valid");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+#endif
+
+/**
+* @brief Checks whether the command format is supported.
+* @since_tizen 2.4
+*
+* @param[in] format The command format
+* @param[out] support The result status @c true = supported, @c false = not supported
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*/
+#if 0 
+int vc_is_command_format_supported(vc_cmd_format_e format, bool* support)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Is command format supported");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check support */
+       bool non_fixed_support = false;
+       if (0 != vc_config_mgr_get_nonfixed_support(&non_fixed_support)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get nonfixed support info");
+       }
+
+       switch (format) {
+       case VC_CMD_FORMAT_FIXED:                       *support = true;                break;
+       case VC_CMD_FORMAT_FIXED_AND_EXTRA:     *support = non_fixed_support;   break;
+       case VC_CMD_FORMAT_EXTRA_AND_FIXED:     *support = non_fixed_support;   break;
+       default:                                        *support = false;               break;
+       }
+
+       SLOG(LOG_ERROR, TAG_VCC, "[DEBUG] Format(%d) support(%s)", format, *support ? "true" : "false");
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return VC_ERROR_NONE;
+}
+#endif
+
+int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type)
+{ 
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Set Command list");
+
+       if (NULL == vc_cmd_list) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check type */
+       if ((VC_COMMAND_TYPE_FOREGROUND != type) && (VC_COMMAND_TYPE_BACKGROUND != type)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid command type: input type is %d", type);
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_cmd_list_s* list = NULL;
+       list = (vc_cmd_list_s*)vc_cmd_list;
+
+       int ret = 0;
+       if (0 != vc_cmd_parser_save_file(getpid(), (vc_cmd_type_e)type, list->list)) {
+               ret = VC_ERROR_INVALID_PARAMETER;
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to save command list : %s", __vc_get_error_code(ret));
+       } else {
+               int count = 0;
+               do {
+                       ret = vc_dbus_request_set_command(g_vc->handle, (vc_cmd_type_e)type);
+                       if (0 != ret) {
+                               if (VC_ERROR_TIMED_OUT != ret) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request set command to daemon : %s", __vc_get_error_code(ret));
+                                       break;
+                               } else {
+                                       SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request set command : %s", __vc_get_error_code(ret));
+                                       usleep(10000);
+                                       count++;
+                                       if (VC_RETRY_COUNT == count) {
+                                               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                               break;
+                                       }
+                               }
+                       }
+               } while(0 != ret);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+int vc_unset_command_list(int type)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Unset Command list");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int count = 0;
+       int ret = -1;
+       while (0 != ret) {
+               ret = vc_dbus_request_unset_command(g_vc->handle, (vc_cmd_type_e)type);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request unset command to daemon : %s", __vc_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request unset command : %s", __vc_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       ret = vc_cmd_parser_delete_file(getpid(), (vc_cmd_type_e)type);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] cmd_type(%d), Fail to delete command list : %s", type, __vc_get_error_code(ret));
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+#if 0
+int vc_get_exclusive_command_option(bool* value)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Get exclusive command");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = vc_client_get_exclusive_cmd(g_vc, value);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set exclusive option : %d", ret);
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return ret;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+int vc_set_exclusive_command_option(bool value)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Set exclusive command");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = vc_client_set_exclusive_cmd(g_vc, value);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set exclusive option : %d", ret);
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return ret;
+       }
+
+       /* Check if current xid is top window */
+       int count = 0;
+       do {
+               ret = vc_dbus_request_set_exclusive_command(g_vc->handle, value);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request set exclusive command to daemon : %s", __vc_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request set exclusive command : %s", __vc_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       } while (0 != ret);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+#endif
+
+#if 0
+int vc_request_start(bool stop_by_silence)
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Request start");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: client state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_client_get_service_state(g_vc, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret;
+       int count = 0;
+
+       /* Request */
+       ret = -1;
+       count = 0;
+       while (0 != ret) {
+               ret = vc_dbus_request_start(g_vc->handle, stop_by_silence);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to start request start : %s", __vc_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry start request start : %s", __vc_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] start interrupt");
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+int vc_request_stop()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Request stop");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: client state is not 'Ready'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_client_get_service_state(g_vc, &service_state);
+       if (service_state != VC_SERVICE_STATE_RECORDING) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: service state is not 'RECORDING'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       int count = 0;
+       /* do request */
+       while (0 != ret) {
+               ret = vc_dbus_request_stop(g_vc->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_DEBUG, TAG_VCC, "[ERROR] Fail to stop request : %s", __vc_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry stop request : %s", __vc_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] Stop interrupt");
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+int vc_request_cancel()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Request cancel Interrupt");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'Ready'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_client_get_service_state(g_vc, &service_state);
+       if (service_state != VC_SERVICE_STATE_RECORDING && service_state != VC_SERVICE_STATE_PROCESSING) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: service state is not 'RECORDING' or 'PROCESSING'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       int count = 0;
+       while (0 != ret) {
+               ret = vc_dbus_request_cancel(g_vc->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_DEBUG, TAG_VCC, "[ERROR] Fail to cancel request : %s", __vc_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry cancel request : %s", __vc_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] Cancel interrupt");
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+#endif
+
+Eina_Bool __vc_notify_error(void *data)
+{
+       vc_h vc = (vc_h)data;
+
+       vc_error_cb callback = NULL;
+       void* user_data;
+       int reason;
+
+       vc_client_get_error_cb(vc, &callback, &user_data);
+       vc_client_get_error(vc, &reason);
+
+       if (NULL != callback) {
+               vc_client_use_callback(vc);
+               callback(reason, user_data);
+               vc_client_not_use_callback(vc);
+               SLOG(LOG_DEBUG, TAG_VCC, "Error callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCC, "[WARNING] Error callback is null");
+       }  
+
+       return EINA_FALSE;
+}
+
+int __vc_cb_error(int pid, int reason)
+{
+       if (0 != vc_client_get_handle(pid, &g_vc)) {
+               SLOG(LOG_ERROR, TAG_VCC, "Handle is not valid");
+               return -1;
+       }
+
+       vc_client_set_error(g_vc, reason);
+       ecore_timer_add(0, __vc_notify_error, g_vc);
+
+       return 0;
+}
+
+Eina_Bool __vc_notify_state_changed(void *data)
+{
+       vc_h vc = (vc_h)data;
+
+       vc_state_changed_cb changed_callback = NULL;
+       void* user_data;
+
+       vc_client_get_state_changed_cb(vc, &changed_callback, &user_data);
+
+       vc_state_e current_state;
+       vc_state_e before_state;
+
+       vc_client_get_before_state(vc, &current_state, &before_state);
+
+       if (NULL != changed_callback) {
+               vc_client_use_callback(vc);
+               changed_callback(before_state, current_state, user_data);
+               vc_client_not_use_callback(vc);
+               SLOG(LOG_DEBUG, TAG_VCC, "State changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCC, "[WARNING] State changed callback is null");
+       }
+
+       return EINA_FALSE;
+}
+
+static Eina_Bool __vc_notify_result(void *data)
+{
+       char* temp_text;
+       int event;
+       vc_cmd_list_h vc_cmd_list = NULL;
+
+       vc_result_cb callback = NULL;
+       void* user_data = NULL;
+
+       vc_client_get_result_cb(g_vc, &callback, &user_data);
+
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Client result callback is NULL");
+               return EINA_FALSE;
+       }
+
+       if (0 != vc_cmd_list_create(&vc_cmd_list)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to create command list");
+               return EINA_FALSE;
+       }
+
+       vc_info_parser_get_result(&temp_text, &event, NULL, getpid(),  vc_cmd_list, false);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "Result info : result text(%s) event(%d)", temp_text, event);
+
+       vc_cmd_print_list(vc_cmd_list);
+
+       vc_client_use_callback(g_vc);
+       callback(event, vc_cmd_list, temp_text, user_data);
+       vc_client_not_use_callback(g_vc);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "Client result callback called");      
+
+       vc_cmd_list_destroy(vc_cmd_list, true);
+
+       /* Release result */
+       if (NULL != temp_text)  free(temp_text);
+
+       return EINA_FALSE;
+}
+
+void __vc_cb_result()
+{
+       ecore_timer_add(0, __vc_notify_result, NULL);
+
+       return;
+}
+
+int vc_set_result_cb(vc_result_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set result callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set result callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_result_cb(g_vc, callback, user_data);
+       
+       return 0;
+}
+
+int vc_unset_result_cb()
+{
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset result callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset result callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_result_cb(g_vc, NULL, NULL);
+
+       return 0;
+}
+
+int vc_set_service_state_changed_cb(vc_service_state_changed_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set result callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set result callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_service_state_changed_cb(g_vc, callback, user_data);
+       
+       return 0;
+}
+
+int vc_unset_service_state_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset result callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset result callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_service_state_changed_cb(g_vc, NULL, NULL);
+
+       return 0;
+}
+
+int vc_set_state_changed_cb(vc_state_changed_cb callback, void* user_data)
+{
+       if (callback == NULL)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set state changed callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set state changed callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_state_changed_cb(g_vc, callback, user_data);
+
+       return 0;
+}
+
+int vc_unset_state_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset state changed callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset state changed callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_state_changed_cb(g_vc, NULL, NULL);
+
+       return 0;
+}
+
+int vc_set_current_language_changed_cb(vc_current_language_changed_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set current language changed : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set current language changed : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_current_lang_changed_cb(g_vc, callback, user_data);
+
+       return 0;
+}
+
+int vc_unset_current_language_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset current language changed : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset current language changed : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_current_lang_changed_cb(g_vc, NULL, NULL);
+
+       return 0;
+}
+
+int vc_set_error_cb(vc_error_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set error callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Set error callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_error_cb(g_vc, callback,  user_data);
+
+       return 0;
+}
+
+int vc_unset_error_cb()
+{
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset error callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Unset error callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_client_set_error_cb(g_vc, NULL, NULL);
+
+       return 0;
+}
+
+/* Authority */
+int vc_auth_enable()
+{
+       /* check state */
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (VC_STATE_READY != state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Current state is not 'READY'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check already authority */
+       vc_auth_state_e auth_state = VC_AUTH_STATE_NONE;
+       if (0 != vc_client_get_auth_state(g_vc, &auth_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (VC_AUTH_STATE_NONE != auth_state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Already authority enabled");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* request authority */
+       int mgr_pid = -1;
+       if (0 != vc_client_get_mgr_pid(g_vc, &mgr_pid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get mgr info");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (0 != vc_dbus_request_auth_enable(g_vc->handle, mgr_pid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to authority enabled");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       /* set authority into handle */
+       int fg_pid = -1;
+       if (0 != vc_config_mgr_get_foreground(&fg_pid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get foreground");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (g_vc->handle == fg_pid) {
+               auth_state = VC_AUTH_STATE_VALID;
+       } else {
+               auth_state = VC_AUTH_STATE_INVALID;
+       }
+
+       if (0 != vc_client_set_auth_state(g_vc, auth_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set auth state");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       ecore_timer_add(0, __notify_auth_changed_cb, NULL);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] Auth enable");
+       
+       return VC_ERROR_NONE;
+}
+
+int vc_auth_disable()
+{
+       /* check state */
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (VC_STATE_READY != state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Current state is not 'READY'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check autority */
+       vc_auth_state_e auth_state = VC_AUTH_STATE_NONE;
+       if (0 != vc_client_get_auth_state(g_vc, &auth_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (VC_AUTH_STATE_NONE == auth_state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] No authority");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (0 != vc_auth_unset_state_changed_cb()) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to unset state changed cb");
+       }
+
+       /* request return authority by dbus */
+       int mgr_pid = -1;
+       if (0 != vc_client_get_mgr_pid(g_vc, &mgr_pid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get mgr info");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (0 != vc_dbus_request_auth_disable(g_vc->handle, mgr_pid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to authority disble");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       /* unset authority from handle */
+       if (0 != vc_client_set_auth_state(g_vc, VC_AUTH_STATE_NONE)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set auth state");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       ecore_timer_add(0, __notify_auth_changed_cb, NULL);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] Auth disable");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_auth_get_state(vc_auth_state_e* state)
+{
+       /* check state */
+       vc_state_e vc_state;
+       if (0 != vc_client_get_client_state(g_vc, &vc_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (VC_STATE_READY != vc_state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Current state is not 'READY'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* get autority */
+       vc_auth_state_e temp = VC_AUTH_STATE_NONE;
+       if (0 != vc_client_get_auth_state(g_vc, &temp)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       *state = temp;
+
+       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] Current auth state is %d", *state);
+       
+       return VC_ERROR_NONE;
+}
+
+int vc_auth_set_state_changed_cb(vc_auth_state_changed_cb callback, void* user_data)
+{
+       /* check parameter */
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] NULL Parameter");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check auth */
+       vc_auth_state_e auth_state;
+       if (0 != vc_client_get_auth_state(g_vc, &auth_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (VC_AUTH_STATE_NONE == auth_state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Auth is not enabled");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* set cb into handle */
+       if (0 != vc_client_set_auth_state_changed_cb(g_vc, callback, user_data)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to set auth state changed cb");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG,  TAG_VCC, "[SUCCESS] Set auth state changed cb");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_auth_unset_state_changed_cb()
+{
+       /* check auth */
+       vc_auth_state_e auth_state;
+       if (0 != vc_client_get_auth_state(g_vc, &auth_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (VC_AUTH_STATE_NONE == auth_state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Auto is not enabled");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* unset cb from handle */
+       if (0 != vc_client_unset_auth_state_changed_cb(g_vc)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to unset auth state changed cb");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] Unset auth state changed cb");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_auth_start()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Request start");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: client state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_client_get_service_state(g_vc, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check authority */
+       vc_auth_state_e auth_state = VC_AUTH_STATE_NONE;
+       if (0 != vc_client_get_auth_state(g_vc, &auth_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (VC_AUTH_STATE_VALID != auth_state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Not auth valid");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       /* get mgr_pid */
+       int mgr_pid = -1;
+       if (0 != vc_client_get_mgr_pid(g_vc, &mgr_pid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get mgr info");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       int ret;
+       int count = 0;
+       /* Request */
+       ret = -1;
+       count = 0;
+       while (0 != ret) {
+               ret = vc_dbus_request_auth_start(g_vc->handle, mgr_pid);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request auth start : %s", __vc_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request auth start : %s", __vc_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] request auth start");
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+int vc_auth_stop()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Request stop");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: client state is not 'Ready'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_client_get_service_state(g_vc, &service_state);
+       if (service_state != VC_SERVICE_STATE_RECORDING) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: service state is not 'RECORDING'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check authority */
+       vc_auth_state_e auth_state = VC_AUTH_STATE_NONE;
+       if (0 != vc_client_get_auth_state(g_vc, &auth_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (VC_AUTH_STATE_VALID != auth_state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Not auth valid");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       /* get mgr_pid */
+       int mgr_pid = -1;
+       if (0 != vc_client_get_mgr_pid(g_vc, &mgr_pid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get mgr info");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       int ret = -1;
+       int count = 0;
+       /* do request */
+       while (0 != ret) {
+               ret = vc_dbus_request_auth_stop(g_vc->handle, mgr_pid);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_DEBUG, TAG_VCC, "[ERROR] Fail to request auth stop: %s", __vc_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request auth stop: %s", __vc_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] request auth stop");
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
+
+int vc_auth_cancel()
+{
+       SLOG(LOG_DEBUG, TAG_VCC, "===== [Client] Request cancel");
+
+       vc_state_e state;
+       if (0 != vc_client_get_client_state(g_vc, &state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: Current state is not 'Ready'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_client_get_service_state(g_vc, &service_state);
+       if (service_state != VC_SERVICE_STATE_RECORDING && service_state != VC_SERVICE_STATE_PROCESSING) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Invalid State: service state is not 'RECORDING' or 'PROCESSING'");
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check authority */
+       vc_auth_state_e auth_state = VC_AUTH_STATE_NONE;
+       if (0 != vc_client_get_auth_state(g_vc, &auth_state)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get auth state");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (VC_AUTH_STATE_VALID != auth_state) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Not auth valid");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       /* get mgr_pid */
+       int mgr_pid = -1;
+       if (0 != vc_client_get_mgr_pid(g_vc, &mgr_pid)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to get mgr info");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       int ret = -1;
+       int count = 0;
+       while (0 != ret) {
+               ret = vc_dbus_request_auth_cancel(g_vc->handle, mgr_pid);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_DEBUG, TAG_VCC, "[ERROR] Fail to request auth cancel: %s", __vc_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCC, "[WARNING] retry request auth cancel: %s", __vc_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCC, "[SUCCESS] request auth cancel");
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "=====");
+       SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       return ret;
+}
diff --git a/client/vc_client.c b/client/vc_client.c
new file mode 100644 (file)
index 0000000..430e89b
--- /dev/null
@@ -0,0 +1,695 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_client.h"
+
+typedef struct {
+       /* base info */
+       vc_h    vc;
+       int     pid;
+       int     uid;            /*<< unique id = pid + handle */
+       int     xid;            /*<< main X window id */
+
+       vc_result_cb                    result_cb;
+       void*                           result_user_data;
+       vc_error_cb                     error_cb;
+       void*                           error_user_data;
+       vc_service_state_changed_cb     service_state_changed_cb;
+       void*                           service_state_changed_user_data;
+       vc_state_changed_cb             state_changed_cb;
+       void*                           state_changed_user_data;
+       vc_current_language_changed_cb  current_lang_changed_cb;
+       void*                           current_lang_changed_user_data;
+       
+#if 0
+       /* exclusive option */
+       bool                    exclusive_cmd;
+#endif
+
+       /* service state */
+       vc_service_state_e      service_state;
+
+       /* state */
+       vc_state_e      before_state;
+       vc_state_e      current_state;
+
+       /* mutex */
+       int     cb_ref_count;
+
+       /* error data */
+       int     reason;
+
+       /* Authority */
+       vc_auth_state_e         auth_before_state;
+       vc_auth_state_e         auth_current_state;
+       vc_auth_state_changed_cb        auth_state_changed_cb;
+       void*                           auth_state_changed_user_data;
+
+       int     mgr_pid;
+}vc_client_s;
+
+/* client list */
+static GSList *g_client_list = NULL;
+
+
+static vc_client_s* __client_get(vc_h vc)
+{
+       if (vc == NULL) {
+               return NULL;
+       }
+
+       vc_client_s *data = NULL;
+
+       int count = g_slist_length(g_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_client_list, i);
+
+               if (NULL != data) {
+                       if (vc->handle == data->vc->handle) {
+                               return data;
+                       }
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Fail to get client by vc");
+
+       return NULL;
+}
+
+int vc_client_create(vc_h* vc)
+{
+       vc_client_s *client = NULL;
+
+       client = (vc_client_s*)calloc(1, sizeof(vc_client_s));
+       if (NULL == client) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to allocate memory");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       vc_h temp = (vc_h)calloc(1, sizeof(struct vc_s));
+       if (NULL == temp) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to allocate memory");
+               free(client);
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       temp->handle = getpid(); 
+
+       /* initialize client data */
+       client->vc = temp;
+       client->pid = getpid(); 
+       client->uid = temp->handle;
+       client->xid = -1;
+
+       client->result_cb = NULL;
+       client->result_user_data = NULL;
+       client->service_state_changed_cb = NULL;
+       client->service_state_changed_user_data = NULL;
+       client->state_changed_cb = NULL;
+       client->state_changed_user_data = NULL;
+       client->current_lang_changed_cb = NULL;
+       client->current_lang_changed_user_data = NULL;
+       client->error_cb = NULL;
+       client->error_user_data = NULL;
+
+#if 0
+       client->exclusive_cmd = false;
+#endif
+
+       client->service_state = -1;
+
+       client->before_state = VC_STATE_INITIALIZED; 
+       client->current_state = VC_STATE_INITIALIZED; 
+
+       client->cb_ref_count = 0;
+
+       /* Authority */
+       client->auth_before_state = VC_AUTH_STATE_NONE;
+       client->auth_current_state = VC_AUTH_STATE_NONE;
+       client->auth_state_changed_cb = NULL;
+       client->auth_state_changed_user_data = NULL;
+
+       g_client_list = g_slist_append(g_client_list, client);
+
+       *vc = temp;
+
+       return 0;
+}
+
+int vc_client_destroy(vc_h vc)
+{
+       if (vc == NULL) {
+               SLOG(LOG_ERROR, TAG_VCC, "Input parameter is NULL");
+               return 0;
+       }       
+
+       vc_client_s *data = NULL;
+
+       int count = g_slist_length(g_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_client_list, i);
+
+               if (NULL != data) {
+                       if (vc->handle == data->vc->handle) {
+                               g_client_list =  g_slist_remove(g_client_list, data);
+
+                               while (0 != data->cb_ref_count)
+                               {
+                                       /* wait for release callback function */
+                               }
+                               free(data);
+                               free(vc);
+
+                               return 0;
+                       }
+               }
+       }
+
+       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] client Not found");
+
+       return -1;
+}
+
+bool vc_client_is_valid(vc_h vc)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) {
+               SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] vc is not valid");
+               return false;
+       }
+
+       return true;
+}
+
+bool vc_client_is_valid_by_uid(int uid)
+{
+       vc_client_s *data = NULL;
+
+       int count = g_slist_length(g_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_client_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) 
+                               return true;
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCC, "[DEBUG] Fail to get client by vc");
+
+       return false;
+}
+
+int vc_client_get_handle(int uid, vc_h* vc)
+{
+       vc_client_s *data = NULL;
+       
+       int count = g_slist_length(g_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_client_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) {
+                               *vc = data->vc;
+                               return 0;
+                       }
+               }
+       }
+       
+       return -1;
+}
+
+/* set/get callback function */
+int vc_client_set_result_cb(vc_h vc, vc_result_cb callback, void* user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->result_cb = callback;
+       client->result_user_data = user_data;
+
+       return 0;
+}
+
+int vc_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->result_cb;
+       *user_data = client->result_user_data;
+
+       return 0;       
+}
+
+int vc_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->service_state_changed_cb = callback;
+       client->service_state_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_client_get_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb* callback, void** user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->service_state_changed_cb;
+       *user_data = client->service_state_changed_user_data;
+
+       return 0;
+}
+
+int vc_client_set_state_changed_cb(vc_h vc, vc_state_changed_cb callback, void* user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->state_changed_cb = callback;
+       client->state_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_client_get_state_changed_cb(vc_h vc, vc_state_changed_cb* callback, void** user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->state_changed_cb;
+       *user_data = client->state_changed_user_data;
+
+       return 0;
+}
+
+int vc_client_set_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb callback, void* user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->current_lang_changed_cb = callback;
+       client->current_lang_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_client_get_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb* callback, void** user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->current_lang_changed_cb;
+       *user_data = client->current_lang_changed_user_data;
+
+       return 0;
+}
+
+int vc_client_set_error_cb(vc_h vc, vc_error_cb callback, void* user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->error_cb = callback;
+       client->error_user_data = user_data;
+
+       return 0;
+}
+
+int vc_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->error_cb;
+       *user_data = client->error_user_data;
+
+       return 0;
+}
+
+/* set/get option */
+int vc_client_set_service_state(vc_h vc, vc_service_state_e state)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->service_state = state;
+
+       return 0;
+}
+
+int vc_client_get_service_state(vc_h vc, vc_service_state_e* state)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *state = client->service_state;
+
+       return 0;
+}
+
+int vc_client_set_client_state(vc_h vc, vc_state_e state)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->before_state = client->current_state;
+       client->current_state = state;
+
+       return 0;
+}
+
+int vc_client_get_client_state(vc_h vc, vc_state_e* state)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *state = client->current_state;
+
+       return 0;
+}
+
+int vc_client_get_client_state_by_uid(int uid, vc_state_e* state)
+{
+       vc_client_s *data = NULL;
+
+       int count = g_slist_length(g_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_client_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) {
+                               *state = data->current_state;
+                               return 0;
+                       }
+               }
+       }
+
+       return -1;
+}
+
+int vc_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_state)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *before_state = client->before_state;
+       *state = client->current_state;
+
+       return 0;
+}
+
+int vc_client_set_xid(vc_h vc, int xid)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->xid = xid;
+
+       return 0;
+}
+
+int vc_client_get_xid(vc_h vc, int* xid)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *xid = client->xid;
+
+       return 0;
+}
+
+#if 0
+int vc_client_set_exclusive_cmd(vc_h vc, bool value)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->exclusive_cmd = value;
+
+       return 0;
+}
+
+int vc_client_get_exclusive_cmd(vc_h vc, bool* value)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *value = client->exclusive_cmd;
+
+       return 0;
+}
+#endif
+
+int vc_client_set_error(vc_h vc, int reason)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->reason = reason;
+
+       return 0;
+}
+
+int vc_client_get_error(vc_h vc, int* reason)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *reason = client->reason;
+
+       return 0;
+}
+
+
+/* utils */
+int vc_client_get_count()
+{
+       return g_slist_length(g_client_list);
+}
+
+int vc_client_use_callback(vc_h vc)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->cb_ref_count++;
+       return 0;
+}
+
+int vc_client_not_use_callback(vc_h vc)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->cb_ref_count--;
+       return 0;
+}
+
+/* Authority */
+int vc_client_set_auth_state_changed_cb(vc_h vc, vc_auth_state_changed_cb callback, void* user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->auth_state_changed_cb = callback;
+       client->auth_state_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_client_get_auth_state_changed_cb(vc_h vc, vc_auth_state_changed_cb* callback, void** user_data)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->auth_state_changed_cb;
+       *user_data = client->auth_state_changed_user_data;
+
+       return 0;
+}
+
+int vc_client_unset_auth_state_changed_cb(vc_h vc)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->auth_state_changed_cb = NULL;
+       client->auth_state_changed_user_data = NULL;
+
+       return 0;
+}
+
+int vc_client_set_auth_state(vc_h vc, vc_auth_state_e state)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->auth_before_state = client->auth_current_state;
+       client->auth_current_state = state;
+
+       return 0;
+}
+
+int vc_client_get_auth_state(vc_h vc, vc_auth_state_e* state)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *state = client->auth_current_state;
+
+       return 0;
+}
+
+int vc_client_get_before_auth_state(vc_h vc, vc_auth_state_e* before, vc_auth_state_e* current)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *before = client->auth_before_state;
+       *current = client->auth_current_state;
+
+       return 0;
+}
+
+int vc_client_set_mgr_pid(vc_h vc, int mgr_pid)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->mgr_pid = mgr_pid;
+
+       return 0;
+}
+
+int vc_client_get_mgr_pid(vc_h vc, int* mgr_pid)
+{
+       vc_client_s* client = __client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *mgr_pid = client->mgr_pid;
+
+       return 0;
+}
\ No newline at end of file
diff --git a/client/vc_client.h b/client/vc_client.h
new file mode 100644 (file)
index 0000000..6ae3c81
--- /dev/null
@@ -0,0 +1,127 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VC_CLIENT_H_
+#define __VC_CLIENT_H_
+
+#include "vc_info_parser.h"
+#include "vc_main.h"
+#include "voice_control.h"
+#include "voice_control_authority.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 
+* Common function 
+*/
+int vc_client_create(vc_h* vc);
+
+int vc_client_destroy(vc_h vc);
+
+bool vc_client_is_valid(vc_h vc);
+
+bool vc_client_is_valid_by_uid(int uid);
+
+int vc_client_get_handle(int uid, vc_h* vc);
+
+/* 
+* set/get callback function 
+*/
+int vc_client_set_result_cb(vc_h vc, vc_result_cb callback, void* user_data);
+
+int vc_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_data);
+
+int vc_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data);
+
+int vc_client_get_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb* callback, void** user_data);
+
+int vc_client_set_state_changed_cb(vc_h vc, vc_state_changed_cb callback, void* user_data);
+
+int vc_client_get_state_changed_cb(vc_h vc, vc_state_changed_cb* callback, void** user_data);
+
+int vc_client_set_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb callback, void* user_data);
+
+int vc_client_get_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb* callback, void** user_data);
+
+int vc_client_set_error_cb(vc_h vc, vc_error_cb callback, void* user_data);
+
+int vc_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data);
+
+
+/* 
+* set/get option 
+*/
+int vc_client_set_service_state(vc_h vc, vc_service_state_e state);
+
+int vc_client_get_service_state(vc_h vc, vc_service_state_e* state);
+
+int vc_client_set_client_state(vc_h vc, vc_state_e state);
+
+int vc_client_get_client_state(vc_h vc, vc_state_e* state);
+
+int vc_client_get_client_state_by_uid(int uid, vc_state_e* state);
+
+int vc_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_state);
+
+int vc_client_set_xid(vc_h vc, int xid);
+
+int vc_client_get_xid(vc_h vc, int* xid);
+
+#if 0
+int vc_client_set_exclusive_cmd(vc_h vc, bool value);
+
+int vc_client_get_exclusive_cmd(vc_h vc, bool* value);
+#endif
+
+int vc_client_set_error(vc_h vc, int reason);
+
+int vc_client_get_error(vc_h vc, int* reason);
+
+
+/* utils */
+int vc_client_get_count();
+
+int vc_client_use_callback(vc_h vc);
+
+int vc_client_not_use_callback(vc_h vc);
+
+/* Authority */
+int vc_client_set_auth_state_changed_cb(vc_h vc, vc_auth_state_changed_cb callback, void* user_data);
+
+int vc_client_get_auth_state_changed_cb(vc_h vc, vc_auth_state_changed_cb* callback, void** user_data);
+
+int vc_client_unset_auth_state_changed_cb(vc_h vc);
+
+int vc_client_set_auth_state(vc_h vc, vc_auth_state_e state);
+
+int vc_client_get_auth_state(vc_h vc, vc_auth_state_e* state);
+
+int vc_client_get_before_auth_state(vc_h vc, vc_auth_state_e* before, vc_auth_state_e* current);
+
+int vc_client_set_mgr_pid(vc_h vc, int mgr_pid);
+
+int vc_client_get_mgr_pid(vc_h vc, int* mgr_pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_CLIENT_H_ */
diff --git a/client/vc_dbus.c b/client/vc_dbus.c
new file mode 100644 (file)
index 0000000..d88e0cd
--- /dev/null
@@ -0,0 +1,1194 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_client.h"
+#include "vc_dbus.h"
+#include "vc_main.h"
+
+
+static int g_waiting_time = 3000;
+
+static Ecore_Fd_Handler* g_fd_handler = NULL;
+
+static DBusConnection* g_conn = NULL;
+
+
+extern int __vc_cb_error(int pid, int reason);
+
+extern void __vc_cb_result();
+
+
+static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
+{
+       DBusConnection* conn = (DBusConnection*)data;
+       DBusMessage* msg = NULL;
+       DBusMessage *reply = NULL;
+
+       if (NULL == conn)
+               return ECORE_CALLBACK_RENEW;
+
+       dbus_connection_read_write_dispatch(conn, 50);
+
+       msg = dbus_connection_pop_message(conn);
+
+       /* loop again if we haven't read a message */
+       if (NULL == msg) { 
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       char if_name[64];
+       snprintf(if_name, 64, "%s%d", VC_CLIENT_SERVICE_INTERFACE, getpid());
+
+       if (dbus_message_is_method_call(msg, if_name, VCD_METHOD_HELLO)) {
+               SLOG(LOG_DEBUG, TAG_VCC, "===== Get Hello");
+               int pid = 0;
+               int response = -1;
+
+               dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+                       dbus_error_free(&err);
+               }
+
+               if (pid > 0) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc get hello : pid(%d) ", pid);
+                       response = 1;
+
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc get hello : invalid pid ");
+               }
+
+               reply = dbus_message_new_method_return(msg);
+               
+               if (NULL != reply) {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &response, DBUS_TYPE_INVALID);
+
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc get hello : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc get hello : result(%d)", response);
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, ">>>> vc get hello : fail to create reply message");
+               }
+               
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+       } /* VCD_METHOD_HELLO */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_METHOD_RESULT)) {
+               SLOG(LOG_DEBUG, TAG_VCC, "===== Get Client Result");
+
+               __vc_cb_result();
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc get result : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc get result");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, ">>>> vc get result : fail to create reply message");
+               }
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+
+       }/* VCD_METHOD_RESULT */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_METHOD_ERROR)) {
+               SLOG(LOG_DEBUG, TAG_VCC, "===== Get Error");
+               int pid;
+               int reason;
+               char* err_msg;
+
+               dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &pid,
+                       DBUS_TYPE_INT32, &reason,
+                       DBUS_TYPE_STRING, &err_msg,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc Get Error message : Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc Get Error message : pid(%d), reason(%d), msg(%s)", pid, reason, err_msg);
+                       __vc_cb_error(pid, reason);
+               }
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc Error message : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc Error message");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, ">>>> vc Error message : fail to create reply message");
+               }
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCC, "=====");
+               SLOG(LOG_DEBUG, TAG_VCC, " ");
+       }/* VCD_METHOD_ERROR */
+
+       /* free the message */
+       dbus_message_unref(msg);
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+int vc_dbus_open_connection()
+{
+       if (NULL != g_conn) {
+               SLOG(LOG_WARN, TAG_VCC, "already existed connection ");
+               return 0;
+       }
+
+       DBusError err;
+       int ret;
+
+       /* initialise the error value */
+       dbus_error_init(&err);
+
+       /* connect to the DBUS system bus, and check for errors */
+       g_conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCC, "Dbus Connection Error (%s)", err.message); 
+               dbus_error_free(&err); 
+       }
+
+       if (NULL == g_conn) {
+               SLOG(LOG_ERROR, TAG_VCC, "Fail to get dbus connection ");
+               return VC_ERROR_OPERATION_FAILED; 
+       }
+
+       int pid = getpid();
+
+       char service_name[64];
+       memset(service_name, '\0', 64);
+       snprintf(service_name, 64, "%s%d", VC_CLIENT_SERVICE_NAME, pid);
+
+       SLOG(LOG_DEBUG, TAG_VCC, "service name is %s", service_name);
+
+       /* register our name on the bus, and check for errors */
+       ret = dbus_bus_request_name(g_conn, service_name, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "Name Error (%s)", err.message); 
+               dbus_error_free(&err); 
+       }
+
+       if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+               SLOG(LOG_ERROR, TAG_VCC, "fail dbus_bus_request_name()");
+               return -2;
+       }
+
+       if( NULL != g_fd_handler ) {
+               SLOG(LOG_WARN, TAG_VCC, "The handler already exists.");
+               return 0;
+       }
+
+       char rule[128];
+       snprintf(rule, 128, "type='signal',interface='%s%d'", VC_CLIENT_SERVICE_INTERFACE, pid);
+
+       /* add a rule for which messages we want to see */
+       dbus_bus_add_match(g_conn, rule, &err); 
+       dbus_connection_flush(g_conn);
+
+       if (dbus_error_is_set(&err)) 
+       { 
+               SLOG(LOG_ERROR, TAG_VCC, "Match Error (%s)", err.message);
+               dbus_error_free(&err);
+               return VC_ERROR_OPERATION_FAILED; 
+       }
+
+       int fd = 0;
+       if (1 != dbus_connection_get_unix_fd(g_conn, &fd)) {
+               SLOG(LOG_ERROR, TAG_VCC, "fail to get fd from dbus ");
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "Get fd from dbus : %d", fd);
+       }
+
+       g_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)listener_event_callback, g_conn, NULL, NULL);
+
+       if (NULL == g_fd_handler) {
+               SLOG(LOG_ERROR, TAG_VCC, "fail to get fd handler from ecore ");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       return 0;
+}
+
+int vc_dbus_close_connection()
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid = getpid();
+
+       char service_name[64];
+       memset(service_name, '\0', 64);
+       snprintf(service_name, 64, "%s%d", VC_CLIENT_SERVICE_NAME, pid);
+
+       dbus_bus_release_name (g_conn, service_name, &err);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       dbus_connection_close(g_conn);
+
+       g_fd_handler = NULL;
+       g_conn = NULL;
+
+       return 0;
+}
+
+int vc_dbus_reconnect()
+{
+       bool connected = dbus_connection_get_is_connected(g_conn);
+       SECURE_SLOG(LOG_DEBUG, TAG_VCC, "[DBUS] %s", connected ? "Connected" : "Not connected");
+
+       if (false == connected) {
+               vc_dbus_close_connection();
+
+               if (0 != vc_dbus_open_connection()) {
+                       SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Fail to reconnect");
+                       return -1;
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCC, "[DBUS] Reconnect");
+       }
+       return 0;
+}
+
+int vc_dbus_request_hello()
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_METHOD_HELLO);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> Request vc hello : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } 
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg = NULL;
+       int result = 0;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, 500, &err);
+       
+       if (dbus_error_is_set(&err)) {
+               dbus_error_free(&err);
+       }
+
+       dbus_message_unref(msg);
+
+       if (NULL != result_msg) {
+               dbus_message_unref(result_msg);
+               result = 0;
+       } else {
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+
+int vc_dbus_request_initialize(int pid, int* mgr_pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_METHOD_INITIALIZE);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc initialize : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc initialize : pid(%d)", pid);
+       }
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               int tmp = -1;
+               dbus_message_get_args(result_msg, &err, 
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INT32, &tmp,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       *mgr_pid = tmp;
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc initialize : result = %d mgr = %d", result, *mgr_pid);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc initialize : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCC, "<<<< Result message is NULL ");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_finalize(int pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_METHOD_FINALIZE);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc finalize : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc finalize : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err, 
+                               DBUS_TYPE_INT32, &result,
+                               DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc finalize : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc finalize : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCC, "<<<< Result message is NULL ");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_set_exclusive_command(int pid, bool value)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_METHOD_SET_EXCLUSIVE_CMD);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc set exclusive command : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc set exclusive command : pid(%d)", pid);
+       }
+
+       int temp = value;
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INT32, &temp,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc set exclusive command : result = %d", result);
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc set exclusive command : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCC, "<<<< Result message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_set_command(int pid, vc_cmd_type_e cmd_type)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_METHOD_SET_COMMAND);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc set command : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc set command : pid(%d)", pid);
+       }
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INT32, &cmd_type,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc set command : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc set command : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCC, "<<<< Result message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;  
+}
+
+int vc_dbus_request_unset_command(int pid, vc_cmd_type_e cmd_type)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_METHOD_UNSET_COMMAND);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc unset command : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc unset command : pid(%d), type(%d)", pid, cmd_type);
+       }
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INT32, &cmd_type,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc unset command : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc unset command : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCC, "<<<< Result message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+#if 0
+int vc_dbus_request_start(int pid, int silence)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_METHOD_REQUEST_START);               
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc start : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc start : pid(%d), silence(%d)", pid, silence);
+       }
+
+       DBusMessageIter args;
+       dbus_message_iter_init_append(msg, &args);
+
+       /* Append result*/
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &(pid));
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &(silence));
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc start : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc start : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "<<<< Result Message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_stop(int pid)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_METHOD_REQUEST_STOP);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc stop : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc stop : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc stop : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc stop : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "<<<< Result Message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_cancel(int pid)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  /* object name of the signal */
+               VC_SERVER_SERVICE_INTERFACE,    /* interface name of the signal */
+               VC_METHOD_REQUEST_CANCEL);      /* name of the signal */
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc cancel : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc cancel : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc cancel : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc cancel : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "<<<< Result Message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+#endif
+
+/* Authority */
+int vc_dbus_request_auth_enable(int pid, int mgr_pid)
+{
+       DBusMessage* msg;
+
+       char service_name[64] = {0,};
+       char object_path[64] = {0,};
+       char target_if_name[128] = {0,};
+
+       snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, mgr_pid);
+       snprintf(object_path, 64, "%s", VC_MANAGER_SERVICE_OBJECT_PATH);
+       snprintf(target_if_name, 128, "%s%d", VC_MANAGER_SERVICE_INTERFACE, mgr_pid);
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               service_name,
+               object_path,    /* object name of the signal */
+               target_if_name, /* interface name of the signal */
+               VC_METHOD_AUTH_ENABLE); /* name of the signal */
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc auth enable : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc auth enable : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc auth enable : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc auth enable : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "<<<< Result Message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_auth_disable(int pid, int mgr_pid)
+{
+       DBusMessage* msg;
+
+       char service_name[64] = {0,};
+       char object_path[64] = {0,};
+       char target_if_name[128] = {0,};
+
+       snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, mgr_pid);
+       snprintf(object_path, 64, "%s", VC_MANAGER_SERVICE_OBJECT_PATH);
+       snprintf(target_if_name, 128, "%s%d", VC_MANAGER_SERVICE_INTERFACE, mgr_pid);
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               service_name,
+               object_path,    /* object name of the signal */
+               target_if_name, /* interface name of the signal */
+               VC_METHOD_AUTH_DISABLE);        /* name of the signal */
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc auth disable : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc auth disable : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc auth disable : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc auth disable : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "<<<< Result Message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_auth_start(int pid, int mgr_pid)
+{
+       DBusMessage* msg;
+
+       char service_name[64] = {0,};
+       char object_path[64] = {0,};
+       char target_if_name[128] = {0,};
+
+       snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, mgr_pid);
+       snprintf(object_path, 64, "%s", VC_MANAGER_SERVICE_OBJECT_PATH);
+       snprintf(target_if_name, 128, "%s%d", VC_MANAGER_SERVICE_INTERFACE, mgr_pid);
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               service_name,
+               object_path,    
+               target_if_name, 
+               VC_METHOD_AUTH_START);          
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc auth start : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc auth start : pid(%d)", pid);
+       }
+
+       DBusMessageIter args;
+       dbus_message_iter_init_append(msg, &args);
+
+       /* Append result*/
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &(pid));
+       
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc auth start : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc auth start : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "<<<< Result Message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_auth_stop(int pid, int mgr_pid)
+{
+       DBusMessage* msg;
+
+       char service_name[64] = {0,};
+       char object_path[64] = {0,};
+       char target_if_name[128] = {0,};
+
+       snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, mgr_pid);
+       snprintf(object_path, 64, "%s", VC_MANAGER_SERVICE_OBJECT_PATH);
+       snprintf(target_if_name, 128, "%s%d", VC_MANAGER_SERVICE_INTERFACE, mgr_pid);
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               service_name,
+               object_path,    
+               target_if_name, 
+               VC_METHOD_AUTH_STOP);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc auth stop : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc auth stop : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc auth stop : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc auth stop : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "<<<< Result Message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_dbus_request_auth_cancel(int pid, int mgr_pid)
+{
+       DBusMessage* msg;
+
+       char service_name[64] = {0,};
+       char object_path[64] = {0,};
+       char target_if_name[128] = {0,};
+
+       snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, mgr_pid);
+       snprintf(object_path, 64, "%s", VC_MANAGER_SERVICE_OBJECT_PATH);
+       snprintf(target_if_name, 128, "%s%d", VC_MANAGER_SERVICE_INTERFACE, mgr_pid);
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               service_name,
+               object_path,    /* object name of the signal */
+               target_if_name, /* interface name of the signal */
+               VC_METHOD_AUTH_CANCEL); /* name of the signal */
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCC, ">>>> vc auth cancel : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, ">>>> vc auth cancel : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCC, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCC, "<<<< vc auth cancel : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCC, "<<<< vc auth cancel : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCC, "<<<< Result Message is NULL");
+               vc_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
diff --git a/client/vc_dbus.h b/client/vc_dbus.h
new file mode 100644 (file)
index 0000000..f8780a1
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __VC_DBUS_H_
+#define __VC_DBUS_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int vc_dbus_open_connection();
+
+int vc_dbus_close_connection();
+
+
+int vc_dbus_request_hello();
+
+int vc_dbus_request_initialize(int pid, int* mgr_pid);
+
+int vc_dbus_request_finalize(int pid);
+
+int vc_dbus_request_set_exclusive_command(int pid, bool value);
+
+int vc_dbus_request_set_command(int pid, vc_cmd_type_e cmd_type);
+
+int vc_dbus_request_unset_command(int pid, vc_cmd_type_e cmd_type);
+
+#if 0
+int vc_dbus_request_start(int pid, int silence);
+
+int vc_dbus_request_stop(int pid);
+
+int vc_dbus_request_cancel(int pid);
+#endif
+
+/* Authority */
+int vc_dbus_request_auth_enable(int pid, int mgr_pid);
+
+int vc_dbus_request_auth_disable(int pid, int mgr_pid);
+
+int vc_dbus_request_auth_start(int pid, int mgr_pid);
+
+int vc_dbus_request_auth_stop(int pid, int mgr_pid);
+
+int vc_dbus_request_auth_cancel(int pid, int mgr_pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_DBUS_H_ */
diff --git a/client/vc_mgr.c b/client/vc_mgr.c
new file mode 100644 (file)
index 0000000..f1d7121
--- /dev/null
@@ -0,0 +1,2131 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <aul.h>
+
+#include "vc_info_parser.h"
+#include "vc_config_mgr.h"
+#include "vc_command.h"
+#include "vc_main.h"
+#include "vc_mgr_client.h"
+#include "vc_mgr_dbus.h"
+#include "voice_control.h"
+#include "voice_control_command.h"
+#include "voice_control_command_expand.h"
+#include "voice_control_common.h"
+#include "voice_control_manager.h"
+
+
+#define VC_MANAGER_CONFIG_HANDLE       100000
+
+static bool g_m_is_daemon_started = false;
+
+static Ecore_Timer* g_m_connect_timer = NULL;
+
+static vc_h g_vc_m = NULL;
+
+static GSList* g_demandable_client_list = NULL;
+
+
+static Eina_Bool __vc_mgr_notify_state_changed(void *data);
+static Eina_Bool __vc_mgr_notify_error(void *data);
+static Eina_Bool __vc_mgr_notify_result(void *data);
+
+static const char* __vc_mgr_get_error_code(vc_error_e err)
+{
+       switch(err) {
+               case VC_ERROR_NONE:                     return "VC_ERROR_NONE";                 break;
+               case VC_ERROR_OUT_OF_MEMORY:            return "VC_ERROR_OUT_OF_MEMORY";        break;
+               case VC_ERROR_IO_ERROR:                 return "VC_ERROR_IO_ERROR";             break;
+               case VC_ERROR_INVALID_PARAMETER:        return "VC_ERROR_INVALID_PARAMETER";    break;
+               case VC_ERROR_TIMED_OUT:                return "VC_ERROR_TIMED_OUT";            break;
+               case VC_ERROR_RECORDER_BUSY:            return "VC_ERROR_RECORDER_BUSY";        break;
+               case VC_ERROR_INVALID_STATE:            return "VC_ERROR_INVALID_STATE";        break;
+               case VC_ERROR_INVALID_LANGUAGE:         return "VC_ERROR_INVALID_LANGUAGE";     break;
+               case VC_ERROR_ENGINE_NOT_FOUND:         return "VC_ERROR_ENGINE_NOT_FOUND";     break;
+               case VC_ERROR_OPERATION_FAILED:         return "VC_ERROR_OPERATION_FAILED";     break;
+               default:                                return "Invalid error code";            break;
+       }
+       return NULL;
+}
+
+static void __vc_mgr_lang_changed_cb(const char* before_lang, const char* current_lang)
+{
+       SECURE_SLOG(LOG_DEBUG, TAG_VCM, "Lang changed : Before lang(%s) Current lang(%s)", 
+               before_lang, current_lang);
+
+       vc_current_language_changed_cb callback = NULL;
+       void* lang_user_data;
+       vc_mgr_client_get_current_lang_changed_cb(g_vc_m, &callback, &lang_user_data);
+
+       if (NULL != callback) {
+               vc_mgr_client_use_callback(g_vc_m);
+               callback(before_lang, current_lang, lang_user_data);
+               vc_mgr_client_not_use_callback(g_vc_m);
+               SLOG(LOG_DEBUG, TAG_VCM, "Language changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCM, "[WARNING] Language changed callback is null");
+       }
+
+       return;
+}
+
+static void __vc_mgr_service_state_changed_cb(int before_state, int current_state)
+{
+       SECURE_SLOG(LOG_DEBUG, TAG_VCM, "Service State changed : Before(%d) Current(%d)", 
+               before_state, current_state);
+
+       /* Save service state */
+       vc_mgr_client_set_service_state(g_vc_m, (vc_service_state_e)current_state);
+
+       vc_service_state_changed_cb callback = NULL;
+       void* service_user_data;
+       vc_mgr_client_get_service_state_changed_cb(g_vc_m, &callback, &service_user_data);
+
+       if (NULL != callback) {
+               vc_mgr_client_use_callback(g_vc_m);
+               callback((vc_service_state_e)before_state, (vc_service_state_e)current_state, service_user_data);
+               vc_mgr_client_not_use_callback(g_vc_m);
+               SLOG(LOG_DEBUG, TAG_VCM, "Service state changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCM, "[WARNING] Service state changed callback is null");
+       }
+
+       return;
+}
+
+static void __vc_mgr_foreground_changed_cb(int previous, int current)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "Foreground changed : Before(%d) Current(%d)", previous, current);
+
+       /* get authorized valid app */
+       int pid;
+       if (0 != vc_mgr_client_get_valid_authorized_client(g_vc_m, &pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get authorized valid app");
+               return;
+       }
+
+       /* compare & set valid */
+       if (current != pid) {
+               SLOG(LOG_DEBUG, TAG_VCM, "Authority(%d) changed to invalid", pid);
+
+               /* set authorized valid */
+               if (true == vc_mgr_client_is_authorized_client(g_vc_m, current)) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "Authority(%d) change to valid", current);
+                       vc_mgr_client_set_valid_authorized_client(g_vc_m, current);
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "No valid Authority");
+                       vc_mgr_client_set_valid_authorized_client(g_vc_m, -1);
+               }
+       }
+}
+
+int vc_mgr_initialize()
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Initialize");
+
+       /* check handle */
+       if (true == vc_mgr_client_is_valid(g_vc_m)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Already initialized");
+               return VC_ERROR_NONE;
+       }
+
+       if (0 != vc_mgr_dbus_open_connection()) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to open connection");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (0 != vc_mgr_client_create(&g_vc_m)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to create client!!!!!");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       int ret = vc_config_mgr_initialize(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to init config manager : %d", ret);
+               vc_mgr_client_destroy(g_vc_m);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       ret = vc_config_mgr_set_lang_cb(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE, __vc_mgr_lang_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set callback : %d", ret);
+               vc_config_mgr_finalize(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
+               vc_mgr_client_destroy(g_vc_m);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+       
+       ret = vc_config_mgr_set_service_state_cb(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE, __vc_mgr_service_state_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set service change callback : %d", ret);
+               vc_config_mgr_unset_lang_cb(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
+               vc_config_mgr_finalize(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
+               vc_mgr_client_destroy(g_vc_m);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       ret = vc_config_mgr_set_foreground_cb(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE, __vc_mgr_foreground_changed_cb);
+
+       int service_state = -1;
+       if (0 != vc_config_mgr_get_service_state(&service_state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get service state");
+               vc_config_mgr_finalize(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
+               vc_mgr_client_destroy(g_vc_m);
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       vc_mgr_client_set_service_state(g_vc_m, service_state);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "[Success] pid(%d)", g_vc_m->handle);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return VC_ERROR_NONE;
+}
+
+static void __vc_mgr_internal_unprepare()
+{
+       int ret = vc_mgr_dbus_request_finalize(g_vc_m->handle);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request finalize : %s", __vc_mgr_get_error_code(ret));
+       }
+
+       g_m_is_daemon_started = false;
+
+       vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_SYSTEM);
+       vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_EXCLUSIVE);
+
+       return;
+}
+
+int vc_mgr_deinitialize()
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Deinitialize");
+
+       if (false == vc_mgr_client_is_valid(g_vc_m)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] NOT initialized");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_state_e state;
+       vc_mgr_client_get_client_state(g_vc_m, &state);
+
+       /* check state */
+       switch (state) {
+       case VC_STATE_READY:
+               __vc_mgr_internal_unprepare();
+               /* no break. need to next step*/
+       case VC_STATE_INITIALIZED:
+               if (NULL != g_m_connect_timer) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "Connect Timer is deleted");
+                       ecore_timer_del(g_m_connect_timer);
+               }
+
+               vc_config_mgr_unset_service_state_cb(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
+               vc_config_mgr_unset_lang_cb(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
+               vc_config_mgr_finalize(g_vc_m->handle + VC_MANAGER_CONFIG_HANDLE);
+
+               /* Free client resources */
+               vc_mgr_client_destroy(g_vc_m);
+               g_vc_m = NULL;
+               break;
+       case VC_STATE_NONE:
+               break;
+       default:
+               break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "Success: destroy");
+
+       if (0 != vc_mgr_dbus_close_connection()) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to close connection");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return VC_ERROR_NONE;
+}
+
+static void* __fork_vc_daemon()
+{
+       int pid, i;
+       pid = fork();
+
+       switch(pid) {
+       case -1:
+               SLOG(LOG_ERROR, TAG_VCM, "Fail to create daemon");
+               break;
+       case 0:
+               setsid();
+               for (i = 0;i < _NSIG;i++)
+                       signal(i, SIG_DFL);
+
+               execl(VC_DAEMON_PATH, VC_DAEMON_PATH, NULL);
+               break;
+       default:
+               break;
+       }
+
+       return (void*) 1;
+}
+
+static Eina_Bool __vc_mgr_connect_daemon(void *data)
+{
+       /* Send hello */
+       if (0 != vc_mgr_dbus_request_hello()) {
+               if (false == g_m_is_daemon_started) {
+                       g_m_is_daemon_started = true;
+
+                       pthread_t thread;
+                       int thread_id;
+                       thread_id = pthread_create(&thread, NULL, __fork_vc_daemon, NULL);
+                       if (thread_id < 0) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to make thread");
+                               g_m_connect_timer = NULL;
+                               return EINA_FALSE;
+                       }
+
+                       pthread_detach(thread);
+               }
+               return EINA_TRUE;
+       }
+
+       g_m_connect_timer = NULL;
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Connect daemon");
+
+       /* request initialization */
+       int ret = -1;
+       ret = vc_mgr_dbus_request_initialize(g_vc_m->handle);
+
+       if (VC_ERROR_ENGINE_NOT_FOUND == ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to initialize : %s", __vc_mgr_get_error_code(ret));
+
+               vc_mgr_client_set_error(g_vc_m, VC_ERROR_ENGINE_NOT_FOUND);
+               ecore_timer_add(0, __vc_mgr_notify_error, g_vc_m);
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, "  ");
+               return EINA_FALSE;
+
+       } else if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "[WARNING] Fail to connection. Retry to connect : %s", __vc_mgr_get_error_code(ret));
+               return EINA_TRUE;
+       } else {
+               /* Success to connect */
+       }
+
+       SECURE_SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Connected daemon");
+
+       vc_mgr_client_set_client_state(g_vc_m, VC_STATE_READY);
+
+       vc_state_changed_cb changed_callback = NULL;
+       void* user_data = NULL;
+
+       vc_mgr_client_get_state_changed_cb(g_vc_m, &changed_callback, &user_data);
+
+       vc_state_e current_state;
+       vc_state_e before_state;
+
+       vc_mgr_client_get_before_state(g_vc_m, &current_state, &before_state);
+
+       if (NULL != changed_callback) {
+               vc_mgr_client_use_callback(g_vc_m);
+               changed_callback(before_state, current_state, user_data);
+               vc_mgr_client_not_use_callback(g_vc_m);
+               SLOG(LOG_DEBUG, TAG_VCM, "State changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCM, "[WARNING] State changed callback is null");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, "  ");
+
+       return EINA_FALSE;
+}
+
+int vc_mgr_prepare()
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Prepare");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'CREATED'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       g_m_is_daemon_started = false;
+
+       g_m_connect_timer = ecore_timer_add(0, __vc_mgr_connect_daemon, NULL);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_mgr_unprepare()
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Unprepare");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       __vc_mgr_internal_unprepare();
+
+       vc_mgr_client_set_client_state(g_vc_m, VC_STATE_INITIALIZED);
+       ecore_timer_add(0, __vc_mgr_notify_state_changed, g_vc_m);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_mgr_foreach_supported_languages(vc_supported_language_cb callback, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Foreach Supported Language");
+
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       ret = vc_config_mgr_get_language_list(callback, user_data);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get languages : %s", __vc_mgr_get_error_code(ret));
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_mgr_get_current_language(char** language)
+{
+       if (NULL == language) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       ret = vc_config_mgr_get_default_language(language);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get current languages : %s", __vc_mgr_get_error_code(ret));
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "[Get current language] language : %s", *language);
+       }
+
+       return ret;
+}
+
+int vc_mgr_get_state(vc_state_e* state)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Get State");
+
+       if (NULL == state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e temp;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &temp)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       *state = temp;
+
+       switch(*state) {
+               case VC_STATE_NONE:             SLOG(LOG_DEBUG, TAG_VCM, "Current state is 'None'");            break;
+               case VC_STATE_INITIALIZED:      SLOG(LOG_DEBUG, TAG_VCM, "Current state is 'Created'");         break;
+               case VC_STATE_READY:            SLOG(LOG_DEBUG, TAG_VCM, "Current state is 'Ready'");           break;
+               default:                        SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid state");              break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_mgr_get_service_state(vc_service_state_e* state)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Get Service State");
+
+       if (NULL == state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e client_state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &client_state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (client_state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Current state is not 'READY'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* get service state */
+       vc_service_state_e service_state;
+       if (0 != vc_mgr_client_get_service_state(g_vc_m, &service_state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get service state");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       *state = service_state;
+
+       switch(*state) {
+               case VC_SERVICE_STATE_NONE:             SLOG(LOG_DEBUG, TAG_VCM, "Current service state is 'None'");            break;
+               case VC_SERVICE_STATE_READY:            SLOG(LOG_DEBUG, TAG_VCM, "Current service state is 'Ready'");           break;
+               case VC_SERVICE_STATE_RECORDING:        SLOG(LOG_DEBUG, TAG_VCM, "Current service state is 'Recording'");       break;
+               case VC_SERVICE_STATE_PROCESSING:       SLOG(LOG_DEBUG, TAG_VCM, "Current service state is 'Processing'");      break;
+               default:                                SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid state");                      break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_mgr_set_demandable_client_rule(const char* rule)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set Demandable client rule");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       ret = vc_info_parser_set_demandable_client(rule);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] rule is NOT valid");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       if (0 != vc_info_parser_get_demandable_clients(&g_demandable_client_list)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get demandable clients");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+       
+       return 0;
+
+       /*
+       int count = 0;
+       ret = -1;
+       while (0 != ret) {
+               ret = vc_mgr_dbus_request_demandable_client(g_vc_m->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request set client rule to daemon : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry request set client rule : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return 0;
+       */
+}
+
+int vc_mgr_unset_demandable_client_rule()
+{
+       vc_info_parser_set_demandable_client(NULL);
+
+       int count = 0;
+       int ret = -1;
+       while (0 != ret) {
+               ret = vc_mgr_dbus_request_demandable_client(g_vc_m->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request unset client rule to daemon : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry request unset client rule : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       return 0;
+}
+
+int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool* support)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Is command type supported");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check support */
+       bool non_fixed_support = false;
+       if (0 != vc_config_mgr_get_nonfixed_support(&non_fixed_support)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get nonfixed support info");
+       }
+
+       switch (format) {
+       case VC_CMD_FORMAT_FIXED:                       *support = true;                break;
+       case VC_CMD_FORMAT_FIXED_AND_EXTRA:     *support = non_fixed_support;   break;
+       case VC_CMD_FORMAT_EXTRA_AND_FIXED:     *support = non_fixed_support;   break;
+       default:                                        *support = false;               break;
+       }
+
+       SLOG(LOG_ERROR, TAG_VCM, "[DEBUG] Format(%d) support(%s)", format, *support ? "true" : "false");
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list)
+{ 
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set Command list");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_cmd_list_s* list = NULL;
+       list = (vc_cmd_list_s*)vc_cmd_list;
+
+       int system_ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_TYPE_SYSTEM, list->list);
+       int exclsive_ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_TYPE_EXCLUSIVE, list->list);
+       int ret = 0;
+
+       if (0 != system_ret && 0 != exclsive_ret) {
+               ret = VC_ERROR_INVALID_PARAMETER;
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to save command group : %s", __vc_mgr_get_error_code(ret));
+       } else {
+               int count = 0;
+               do {
+                       ret = vc_mgr_dbus_request_set_command(g_vc_m->handle);
+                       if (0 != ret) {
+                               if (VC_ERROR_TIMED_OUT != ret) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request set command to daemon : %s", __vc_mgr_get_error_code(ret));
+                                       break;
+                               } else {
+                                       SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry request set command : %s", __vc_mgr_get_error_code(ret));
+                                       usleep(10000);
+                                       count++;
+                                       if (VC_RETRY_COUNT == count) {
+                                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                               break;
+                                       }
+                               }
+                       }
+               } while(0 != ret);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return ret;
+}
+
+int vc_mgr_unset_command_list()
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Unset Command list");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Current state is not 'READY'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int count = 0;
+       int ret = -1;
+       while (0 != ret) {
+               ret = vc_mgr_dbus_request_unset_command(g_vc_m->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request unset command to daemon : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry request unset command : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       }
+
+       vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_SYSTEM);
+       vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_EXCLUSIVE);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return 0;
+}
+
+int vc_mgr_set_audio_type(const char* audio_id)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Set audio type");
+
+       if (NULL == audio_id) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret;
+       int count = 0;
+
+       /* Request */
+       ret = -1;
+       count = 0;
+       while (0 != ret) {
+               ret = vc_mgr_dbus_request_set_audio_type(g_vc_m->handle, audio_id);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set audio type : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry to set audio type : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set audio type");
+                       /* Save */
+                       vc_mgr_client_set_audio_type(g_vc_m, audio_id);
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return ret;
+}
+
+int vc_mgr_get_audio_type(char** audio_id)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Get audio type");
+
+       if (NULL == audio_id) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       char* temp = NULL;
+
+       vc_mgr_client_get_audio_type(g_vc_m, &temp);
+
+       if (NULL == temp) {
+               /* Not initiallized */
+               int ret = -1;
+               int count = 0;
+               while (0 != ret) {
+                       ret = vc_mgr_dbus_request_get_audio_type(g_vc_m->handle, &temp);
+                       if (0 != ret) {
+                               if (VC_ERROR_TIMED_OUT != ret) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get audio type : %s", __vc_mgr_get_error_code(ret));
+                                       break;
+                               } else {
+                                       SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry to get audio type : %s", __vc_mgr_get_error_code(ret));
+                                       usleep(10000);
+                                       count++;
+                                       if (VC_RETRY_COUNT == count) {
+                                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                               break;
+                                       }
+                               }
+                       } else {
+                               SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Get audio type : %s", temp);
+                               /* Save */
+                               vc_mgr_client_set_audio_type(g_vc_m, temp);
+                       }
+               }
+       }
+
+       if (NULL != temp) {
+               *audio_id = strdup(temp);
+               free(temp);
+               temp = NULL;
+       }
+
+       return 0;
+}
+
+int vc_mgr_get_current_commands(vc_cmd_list_h* vc_cmd_list)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Foreach current commands");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (NULL == vc_cmd_list) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid Parameter");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_list_h temp_list = NULL;
+       if (0 != vc_cmd_list_create(&temp_list)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to create list");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       *vc_cmd_list = temp_list;
+
+       int fg_pid = 0;
+       int mgr_pid = 0;
+       int count = 0;
+       int ret = -1;
+
+       /* Get foreground pid */
+       if (0 != vc_config_mgr_get_foreground(&fg_pid)) {
+               /* There is no foreground app for voice control */
+               SLOG(LOG_WARN, TAG_VCM, "[Manager WARNING] No foreground pid for voice control");
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] Foreground pid(%d)", fg_pid);
+       }
+
+       if (0 != vc_mgr_client_get_pid(g_vc_m, &mgr_pid)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] Fail to get manager pid");
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] Manager pid(%d)", mgr_pid);
+       }
+
+       /* Get system command */
+       ret = vc_cmd_parser_append_commands(mgr_pid, VC_COMMAND_TYPE_SYSTEM, temp_list);
+       if (0 != ret) {
+               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] No system commands");
+       }
+
+       /* Request */
+       ret = -1;
+       count = 0;
+       while (0 != ret) {
+               ret = vc_mgr_dbus_request_set_client_info(g_vc_m->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set client info : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry to set client info : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set client info");
+               }
+       }
+
+       GSList *iter = NULL;
+       GSList* client_info_list = NULL;
+       vc_client_info_s *client_info = NULL;
+       bool is_fgpid = false;
+
+       if (0 != vc_info_parser_get_client_info(&client_info_list)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] No client");
+               return 0;
+       }
+       
+       if (VC_NO_FOREGROUND_PID != fg_pid) {
+               iter = g_slist_nth(client_info_list, 0);
+               while (NULL != iter) {
+                       client_info = iter->data;
+                       if (NULL != client_info) {
+                               if (fg_pid == client_info->pid) {
+                                       is_fgpid = true;
+                                       break;
+                               }
+                       }
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       /* Get foreground commands and widget */
+       if (true == is_fgpid) {
+               /* Get handle */
+               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] fore cmd(%d)", client_info->fg_cmd);
+
+               /* Get foreground command */
+               if (true == client_info->fg_cmd) {
+                       ret = vc_cmd_parser_append_commands(fg_pid, VC_COMMAND_TYPE_FOREGROUND, temp_list);
+                       if (0 != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[Client Data ERROR] Fail to get the fg command list");
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "[Manager] No foreground commands");
+               }
+
+               /* Check exclusive option */
+               if (true == client_info->exclusive_cmd) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "[Manager] Exclusive command is ON");
+
+                       /* Set background command for exclusive option */
+                       if (true == client_info->bg_cmd) {
+                               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] Set background command");
+                               ret = vc_cmd_parser_append_commands(client_info->pid, VC_COMMAND_TYPE_BACKGROUND, temp_list);
+                               if (0 != ret) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[Client Data ERROR] Fail to get the bg command list : pid(%d)", client_info->pid);
+                               }
+                       }
+
+                       /* need to release client info */
+                       iter = g_slist_nth(client_info_list, 0);
+
+                       while (NULL != iter) {
+                               client_info = iter->data;
+                               if (NULL != client_info) {
+                                       free(client_info);
+                               }
+                               client_info_list = g_slist_remove_link(client_info_list, iter);
+                               iter = g_slist_nth(client_info_list, 0);
+                       }
+
+                       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+                       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+                       return 0;
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] No foreground app");
+       }
+
+       /* Get background commands */
+       if (0 < g_slist_length(client_info_list)) {
+               iter = g_slist_nth(client_info_list, 0);
+
+               while (NULL != iter) {
+                       client_info = iter->data;
+
+                       if (NULL != client_info) {
+                               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] Pid(%d) Back cmd(%d)", client_info->pid, client_info->bg_cmd);
+                               if (true == client_info->bg_cmd) {
+                                       ret = vc_cmd_parser_append_commands(client_info->pid, VC_COMMAND_TYPE_BACKGROUND, temp_list);
+                                       if (0 != ret) {
+                                               SLOG(LOG_ERROR, TAG_VCM, "[Client Data ERROR] Fail to get the bg command list : pid(%d)", client_info->pid);
+                                       } 
+                               }
+                               free(client_info);
+                       }
+                       client_info_list = g_slist_remove_link(client_info_list, iter);
+
+                       iter = g_slist_nth(client_info_list, 0);
+               }
+       } else {
+               /* NO client */
+               SLOG(LOG_DEBUG, TAG_VCM, "[Manager] No background commands");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return 0;
+}
+
+int vc_mgr_start(bool stop_by_silence, bool exclusive_command_option)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request start");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_exclusive_command(g_vc_m, exclusive_command_option);
+
+       bool start_by_client = false;
+       if (0 != vc_mgr_client_get_start_by_client(g_vc_m, &start_by_client)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get start by client");
+       }
+
+       int ret;
+       int count = 0;
+
+       /* Request */
+       ret = -1;
+       count = 0;
+       while (0 != ret) {
+               ret = vc_mgr_dbus_request_start(g_vc_m->handle, stop_by_silence, exclusive_command_option, start_by_client);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to start request start : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry start request start : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       vc_mgr_client_set_exclusive_command(g_vc_m, false);
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] start recognition");
+                       vc_mgr_client_set_service_state(g_vc_m, VC_SERVICE_STATE_RECORDING);
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return ret;
+}
+
+int vc_mgr_stop()
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request stop");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: client state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_RECORDING) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'RECORDING'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       int count = 0;
+       /* do request */
+       while (0 != ret) {
+               ret = vc_mgr_dbus_request_stop(g_vc_m->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to stop request : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry stop request : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Stop recognition");
+                       vc_mgr_client_set_service_state(g_vc_m, VC_SERVICE_STATE_PROCESSING);
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return ret;
+}
+
+int vc_mgr_cancel()
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Request cancel");
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: client state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_RECORDING && service_state != VC_SERVICE_STATE_PROCESSING) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'RECORDING' or 'PROCESSING'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       int count = 0;
+       while (0 != ret) {
+               ret = vc_mgr_dbus_request_cancel(g_vc_m->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_DEBUG, TAG_VCM, "[ERROR] Fail to cancel request : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry cancel request : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Cancel recognition");
+                       vc_mgr_client_set_service_state(g_vc_m, VC_SERVICE_STATE_READY);
+               }
+       }
+
+       vc_mgr_client_set_exclusive_command(g_vc_m, false);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return ret;
+}
+
+int vc_mgr_get_recording_volume(float* volume)
+{
+       if (NULL == volume) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_service_state_e service_state = -1;
+       if (0 != vc_mgr_client_get_service_state(g_vc_m, &service_state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (VC_SERVICE_STATE_RECORDING != service_state) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: Service state is not 'RECORDING'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       FILE* fp = fopen(VC_RUNTIME_INFO_AUDIO_VOLUME, "rb");
+       if (!fp) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to open Volume File");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       int readlen = fread((void*)volume, sizeof(*volume), 1, fp);
+       fclose(fp);
+
+       if (0 == readlen)
+               *volume = 0.0f;
+
+       return 0;
+}
+
+int vc_mgr_set_selected_results(vc_cmd_list_h vc_cmd_list)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "===== [Manager] Select result");
+
+       vc_service_state_e service_state = -1;
+       vc_mgr_client_get_service_state(g_vc_m, &service_state);
+       if (service_state != VC_SERVICE_STATE_PROCESSING) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Invalid State: service state is not 'PROCESSING'");
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (NULL != vc_cmd_list) {
+               int event = 0;
+               char* result_text = NULL;
+
+               vc_mgr_client_get_all_result(g_vc_m, &event, &result_text);
+               
+               vc_info_parser_set_result(result_text, event, NULL, vc_cmd_list, false);
+
+               if (NULL != result_text) {
+                       free(result_text);
+                       result_text = NULL;
+               }
+       }
+       
+       int ret;
+       int count = 0;
+
+       /* Request */
+       ret = -1;
+       count = 0;
+       while (0 != ret) {
+               ret = vc_mgr_dbus_send_result_selection(g_vc_m->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to send result selection : %s", __vc_mgr_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCM, "[WARNING] retry send result selection : %s", __vc_mgr_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] result selection");
+               }
+       }
+
+       vc_mgr_client_unset_all_result(g_vc_m);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "=====");
+       SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       return 0;
+}
+
+static Eina_Bool __vc_mgr_set_select_result(void *data)
+{
+       vc_mgr_set_selected_results(NULL);
+       return EINA_FALSE;
+}
+
+static Eina_Bool __vc_mgr_notify_all_result(void *data)
+{
+       char* temp_text = NULL;
+       int event;
+       char* temp_message = NULL;
+       vc_cmd_list_h vc_cmd_list = NULL;
+
+       vc_mgr_all_result_cb all_callback = NULL;
+       void* all_user_data = NULL;
+
+       vc_mgr_client_get_all_result_cb(g_vc_m, &all_callback, &all_user_data);
+       if (NULL == all_callback) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] All result callback is NULL");
+               return EINA_FALSE;
+       }
+
+       if (0 != vc_cmd_list_create(&vc_cmd_list)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to create command list");
+               return EINA_FALSE;
+       }
+
+       vc_info_parser_get_result(&temp_text, &event, &temp_message, -1, vc_cmd_list, vc_mgr_client_get_exclusive_command(g_vc_m));
+
+       SLOG(LOG_DEBUG, TAG_VCM, "Result info : result text(%s) event(%d) result_message(%s)", temp_text, event, temp_message);
+
+       vc_cmd_print_list(vc_cmd_list);
+
+       bool cb_ret;
+
+       vc_mgr_client_use_callback(g_vc_m);
+       cb_ret = all_callback(event, vc_cmd_list, temp_text, temp_message, all_user_data);
+       vc_mgr_client_not_use_callback(g_vc_m);
+
+       if (true == vc_mgr_client_get_exclusive_command(g_vc_m)) {
+               /* exclusive */
+               vc_result_cb callback = NULL;
+               void* user_data = NULL;
+
+               vc_mgr_client_get_result_cb(g_vc_m, &callback, &user_data);
+               if (NULL == callback) {
+                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Client result callback is NULL");
+                       return EINA_FALSE;
+               }
+
+               vc_mgr_client_use_callback(g_vc_m);
+               callback(event, vc_cmd_list, temp_text, user_data);
+               vc_mgr_client_not_use_callback(g_vc_m);
+               SLOG(LOG_DEBUG, TAG_VCM, "Exclusive result callback called");
+
+               /* Release result */
+               if (NULL != temp_text)  free(temp_text);
+
+               /* Release list */
+               vc_cmd_list_destroy(vc_cmd_list, true);
+
+               vc_mgr_client_set_exclusive_command(g_vc_m, false);
+
+               return EINA_FALSE;
+       }
+
+       int count = 0;
+       vc_cmd_list_get_count(vc_cmd_list, &count);
+       if (0 < count) {
+               if (true == cb_ret) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "Callback result is true");
+                       ecore_idler_add(__vc_mgr_set_select_result, NULL);
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "Callback result is false");
+                       /* need to select conflicted result */
+
+                       vc_mgr_client_set_all_result(g_vc_m, event, temp_text);
+               }
+       } else {
+               ecore_idler_add(__vc_mgr_set_select_result, NULL);
+               vc_mgr_client_set_exclusive_command(g_vc_m, false);
+               vc_mgr_client_unset_all_result(g_vc_m);
+       }
+
+       /* Release result */
+       if (NULL != temp_text)  free(temp_text);
+
+       /* Release list */
+       vc_cmd_list_destroy(vc_cmd_list, true);
+
+       return EINA_FALSE;
+}
+
+static Eina_Bool __vc_mgr_notify_result(void *data)
+{
+       char* temp_text;
+       int event;
+       vc_cmd_list_h vc_cmd_list = NULL;
+
+       vc_result_cb callback = NULL;
+       void* user_data = NULL;
+
+       vc_mgr_client_get_result_cb(g_vc_m, &callback, &user_data);
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Client result callback is NULL");
+               return EINA_FALSE;
+       }
+
+       if (0 != vc_cmd_list_create(&vc_cmd_list)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to create command list");
+               return EINA_FALSE;
+       }
+
+       vc_info_parser_get_result(&temp_text, &event, NULL, getpid(), vc_cmd_list, false);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "Result : result text(%s) event(%d)", temp_text, event);
+
+       vc_cmd_print_list(vc_cmd_list);
+
+       vc_mgr_client_use_callback(g_vc_m);
+       callback(event, vc_cmd_list, temp_text, user_data);
+       vc_mgr_client_not_use_callback(g_vc_m);
+       SLOG(LOG_DEBUG, TAG_VCM, "Result callback called");
+
+       vc_cmd_list_destroy(vc_cmd_list, true);
+
+       /* Release result */
+       if (NULL != temp_text)  free(temp_text);
+
+       return EINA_FALSE;
+}
+
+void __vc_mgr_cb_all_result()
+{
+       if (false == vc_mgr_client_get_exclusive_command(g_vc_m)) {
+               __vc_mgr_notify_all_result(NULL);
+       } else {
+               __vc_mgr_notify_result(0);
+       }
+
+       return;
+}
+
+void __vc_mgr_cb_system_result()
+{
+       __vc_mgr_notify_result(NULL);
+       return;
+}
+
+static Eina_Bool __vc_mgr_speech_detected(void *data)
+{
+       vc_mgr_begin_speech_detected_cb callback = NULL;
+       void* user_data = NULL;
+
+       vc_mgr_client_get_speech_detected_cb(g_vc_m, &callback, &user_data);
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Client speech detected callback is NULL");
+               return EINA_FALSE;
+       }
+
+       vc_mgr_client_use_callback(g_vc_m);
+       callback(user_data);
+       vc_mgr_client_not_use_callback(g_vc_m);
+       SLOG(LOG_DEBUG, TAG_VCM, "Speech detected callback called");
+
+       return EINA_FALSE;
+}
+
+void __vc_mgr_cb_speech_detected()
+{
+       __vc_mgr_speech_detected(NULL);
+
+       return;
+}
+
+int vc_mgr_set_all_result_cb(vc_mgr_all_result_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set result callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set result callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_all_result_cb(g_vc_m, callback, user_data);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "[SUCCESS] Set all result callback");
+       
+       return 0;
+}
+
+int vc_mgr_unset_all_result_cb()
+{
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset result callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset result callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_all_result_cb(g_vc_m, NULL, NULL);
+
+       return 0;
+}
+
+int vc_mgr_set_result_cb(vc_result_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set result callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set result callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_result_cb(g_vc_m, callback, user_data);
+       
+       return 0;
+}
+
+int vc_mgr_unset_result_cb()
+{
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset result callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset result callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_result_cb(g_vc_m, NULL, NULL);
+
+       return 0;
+}
+
+static Eina_Bool __vc_mgr_notify_error(void *data)
+{
+       vc_h vc_m = (vc_h)data;
+
+       vc_error_cb callback = NULL;
+       void* user_data = NULL;
+       int reason;
+
+       vc_mgr_client_get_error_cb(vc_m, &callback, &user_data);
+       vc_mgr_client_get_error(vc_m, &reason);
+
+       if (NULL != callback) {
+               vc_mgr_client_use_callback(vc_m);
+               callback(reason, user_data);
+               vc_mgr_client_not_use_callback(vc_m);
+               SLOG(LOG_DEBUG, TAG_VCM, "Error callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCM, "[WARNING] Error callback is null");
+       }  
+
+       return EINA_FALSE;
+}
+
+int __vc_mgr_cb_error(int pid, int reason)
+{
+       if (0 != vc_mgr_client_get_handle(pid, &g_vc_m)) {
+               SLOG(LOG_ERROR, TAG_VCM, "Handle is not valid");
+               return -1;
+       }
+
+       vc_mgr_client_set_error(g_vc_m, reason);
+       __vc_mgr_notify_error(g_vc_m);
+
+       return 0;
+}
+
+static Eina_Bool __vc_mgr_notify_state_changed(void *data)
+{
+       vc_state_changed_cb changed_callback = NULL;
+       void* user_data;
+
+       vc_mgr_client_get_state_changed_cb(g_vc_m, &changed_callback, &user_data);
+
+       vc_state_e current_state;
+       vc_state_e before_state;
+
+       vc_mgr_client_get_before_state(g_vc_m, &current_state, &before_state);
+
+       if (NULL != changed_callback) {
+               vc_mgr_client_use_callback(g_vc_m);
+               changed_callback(before_state, current_state, user_data);
+               vc_mgr_client_not_use_callback(g_vc_m);
+               SLOG(LOG_DEBUG, TAG_VCM, "State changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCM, "[WARNING] State changed callback is null");
+       }
+
+       return EINA_FALSE;
+}
+
+int vc_mgr_set_state_changed_cb(vc_state_changed_cb callback, void* user_data)
+{
+       if (callback == NULL)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set state changed callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set state changed callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_state_changed_cb(g_vc_m, callback, user_data);
+
+       return 0;
+}
+
+int vc_mgr_unset_state_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_state_changed_cb(g_vc_m, NULL, NULL);
+
+       return 0;
+}
+
+int vc_mgr_set_service_state_changed_cb(vc_service_state_changed_cb callback, void* user_data)
+{
+       if (callback == NULL)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set state changed callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set state changed callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_service_state_changed_cb(g_vc_m, callback, user_data);
+
+       return 0;
+}
+
+int vc_mgr_unset_service_state_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_service_state_changed_cb(g_vc_m, NULL, NULL);
+       return 0;
+}
+
+int vc_mgr_set_speech_detected_cb(vc_mgr_begin_speech_detected_cb callback, void* user_data)
+{
+       if (callback == NULL)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set state changed callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set speech detected callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_speech_detected_cb(g_vc_m, callback, user_data);
+
+       return 0;
+}
+
+int vc_mgr_unset_speech_detected_cb()
+{
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset state changed callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_speech_detected_cb(g_vc_m, NULL, NULL);
+       return 0;
+}
+
+int vc_mgr_set_current_language_changed_cb(vc_current_language_changed_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set current language changed : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set current language changed : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_current_lang_changed_cb(g_vc_m, callback, user_data);
+
+       return 0;
+}
+
+int vc_mgr_unset_current_language_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset current language changed : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset current language changed : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_current_lang_changed_cb(g_vc_m, NULL, NULL);
+
+       return 0;
+}
+
+int vc_mgr_set_error_cb(vc_error_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set error callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Set error callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_error_cb(g_vc_m, callback,  user_data);
+
+       return 0;
+}
+
+int vc_mgr_unset_error_cb()
+{
+       vc_state_e state;
+       if (0 != vc_mgr_client_get_client_state(g_vc_m, &state)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset error callback : A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Unset error callback : Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_mgr_client_set_error_cb(g_vc_m, NULL, NULL);
+
+       return 0;
+}
+
+static bool __vc_mgr_check_demandable_client(int pid)
+{
+       if (0 == g_slist_length(g_demandable_client_list)) {
+               SLOG(LOG_WARN, TAG_VCM, "[WARNING] No demandable clients");
+               return false;
+       }
+
+       char appid[128] = {'\0', };
+       aul_app_get_appid_bypid(pid, appid, sizeof(appid));
+
+       if (0 >= strlen(appid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] No appid");
+               return false;
+       }
+       SLOG(LOG_DEBUG, TAG_VCM, "[CHECK] Appid - %s", appid);
+
+       GSList *iter = NULL;
+       vc_demandable_client_s* temp_client;
+       iter = g_slist_nth(g_demandable_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (NULL != temp_client->appid) {
+                               if (!strcmp(temp_client->appid, appid)) {
+                                       SLOG(LOG_DEBUG, TAG_VCM, "pid(%d) is available", pid);
+                                       return true;
+                               }
+                       }
+               }
+
+               iter = g_slist_next(iter);
+       }
+
+       return false;
+}
+
+/* Authority */
+int __vc_mgr_request_auth_enable(int pid)
+{
+       if (false == __vc_mgr_check_demandable_client(pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Not demandable client");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* check already authorized */
+       if (true == vc_mgr_client_is_authorized_client(g_vc_m, pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Already authorized");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* add authorized list */
+       if (0 != vc_mgr_client_add_authorized_client(g_vc_m, pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to add authorized client");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       /* foreground check */
+       int fore_pid = 0;
+       if (0 != vc_config_mgr_get_foreground(&fore_pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to get foreground");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       if (pid == fore_pid) {
+               vc_mgr_client_set_valid_authorized_client(g_vc_m, pid);
+       }
+       
+       return 0;
+}
+
+int __vc_mgr_request_auth_disable(int pid)
+{
+       /* check authorized */
+       if (false == vc_mgr_client_is_authorized_client(g_vc_m, pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] No authorized");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* remove authorized list */
+       if (0 != vc_mgr_client_remove_authorized_client(g_vc_m, pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to remove authorized client");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       /* check authority valid */
+       if (true == vc_mgr_client_is_valid_authorized_client(g_vc_m, pid)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "Valid authorized client is removed");
+               if (0 != vc_mgr_client_set_valid_authorized_client(g_vc_m, -1)) {
+                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set valid authorized client");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+       }
+
+       return 0;
+}
+
+static Eina_Bool __request_auth_start(void* data)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "Request Start");
+
+       if (0 != vc_mgr_client_set_start_by_client(g_vc_m, true)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set start by client");
+       }
+
+       if (0 != vc_mgr_start(true, false)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Request start is failed");
+               /* TODO - Error handling? */
+       }
+
+       if (0 != vc_mgr_client_set_start_by_client(g_vc_m, false)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to set start by client");
+       }
+
+
+       return EINA_FALSE;
+}
+
+int __vc_mgr_request_auth_start(int pid)
+{
+       /* check authorized */
+       if (false == vc_mgr_client_is_valid_authorized_client(g_vc_m, pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] No valid authorized client");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* add timer for start recording */
+       ecore_timer_add(0, __request_auth_start, NULL);
+       
+       return 0;
+}
+
+static Eina_Bool __request_auth_stop(void* data)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "Request Stop");
+
+       if (0 != vc_mgr_stop()) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Request stop is failed");
+               /* TODO - Error handling? */
+       }
+
+       return EINA_FALSE;
+}
+
+int __vc_mgr_request_auth_stop(int pid)
+{
+       /* check authorized */
+       if (false == vc_mgr_client_is_valid_authorized_client(g_vc_m, pid)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] No valid authorized client");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* add timer for start recording */
+       ecore_timer_add(0, __request_auth_stop, NULL);
+
+       return 0;
+}
+
+static Eina_Bool __request_auth_cancel(void* data)
+{
+       SLOG(LOG_DEBUG, TAG_VCM, "Request Cancel");
+
+       if (0 != vc_mgr_cancel()) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Request cancel is failed");
+               /* TODO - Error handling? */
+       }
+
+       return EINA_FALSE;
+}
+
+int __vc_mgr_request_auth_cancel(int pid)
+{
+       /* check authorized */
+       if (false == vc_mgr_client_is_valid_authorized_client(g_vc_m, pid)) {
+               SLOG(LOG_ERROR,  TAG_VCM, "[ERROR] No valid authorized client");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       /* add timer for start recording */
+       ecore_timer_add(0, __request_auth_cancel, NULL);
+
+       return 0;
+}
\ No newline at end of file
diff --git a/client/vc_mgr_client.c b/client/vc_mgr_client.c
new file mode 100644 (file)
index 0000000..234c81e
--- /dev/null
@@ -0,0 +1,912 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_main.h"
+#include "vc_mgr_client.h"
+
+typedef struct {
+       /* base info */
+       vc_h    vc;
+       int     pid;
+       int     uid;            /*<< unique id = pid + handle */
+
+       vc_mgr_all_result_cb            all_result_cb;
+       void*                           all_result_user_data;
+       vc_result_cb                    result_cb;
+       void*                           result_user_data;
+
+       vc_error_cb                     error_cb;
+       void*                           error_user_data;
+       vc_service_state_changed_cb     service_state_changed_cb;
+       void*                           service_state_changed_user_data;
+       vc_state_changed_cb             state_changed_cb;
+       void*                           state_changed_user_data;
+       vc_mgr_begin_speech_detected_cb speech_detected_cb;
+       void*                           speech_detected_user_data;
+       vc_current_language_changed_cb  current_lang_changed_cb;
+       void*                           current_lang_changed_user_data;
+       
+       /* All result */
+       vc_result_event_e       all_result_event;
+       char*                   all_result_text;
+
+       /* exclusive command flag */
+       bool                    exclusive_cmd_option;
+
+       /* system result */
+       int                     result_event;
+       char*                   result_text;
+
+       /* service state */
+       vc_service_state_e      service_state;
+
+       /* state */
+       vc_state_e              before_state;
+       vc_state_e              current_state;
+
+       /* language */
+       char*                   before_language;
+       char*                   current_language;
+
+       /* audio type */
+       char*                   audio_id;
+
+       /* mutex */
+       int                     cb_ref_count;
+
+       /* error data */
+       int                     reason;
+
+       /* Authorized */
+       GSList*                 authorized_client_list;
+       int                     valid_authorized_pid;
+       bool                    start_by_client;
+}vc_mgr_client_s;
+
+typedef struct {
+       int pid;
+}vc_authorized_client_s;
+
+static GSList *g_mgr_client_list = NULL;
+
+static vc_mgr_client_s* __mgr_client_get(vc_h vc)
+{
+       if (vc == NULL) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Input parameter is NULL");
+               return NULL;
+       }
+
+       vc_mgr_client_s *data = NULL;
+
+       int count = g_slist_length(g_mgr_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_mgr_client_list, i);
+
+               if (NULL != data) {
+                       if (vc->handle == data->vc->handle) {
+                               return data;
+                       }
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] Fail to get client by vc");
+
+       return NULL;
+}
+
+int vc_mgr_client_create(vc_h* vc)
+{
+       vc_mgr_client_s *client = NULL;
+
+       client = (vc_mgr_client_s*)calloc(1, sizeof(vc_mgr_client_s));
+       if (NULL == client) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to allocate memory");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       vc_h temp = (vc_h)calloc(1, sizeof(struct vc_s));
+       if (NULL == temp) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to allocate memory");
+               free(client);
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       temp->handle = getpid(); 
+
+       /* initialize client data */
+       client->vc = temp;
+       client->pid = getpid(); 
+       client->uid = temp->handle;
+
+       client->all_result_cb = NULL;
+       client->all_result_user_data = NULL;
+       client->result_cb = NULL;
+       client->result_user_data = NULL;
+
+       client->error_cb = NULL;
+       client->error_user_data = NULL;
+       client->service_state_changed_cb = NULL;
+       client->service_state_changed_user_data = NULL;
+       client->state_changed_cb = NULL;
+       client->state_changed_user_data = NULL;
+       client->speech_detected_cb = NULL;
+       client->speech_detected_user_data = NULL;
+       client->current_lang_changed_cb = NULL;
+       client->current_lang_changed_user_data = NULL;
+
+       client->exclusive_cmd_option = false;
+
+       client->all_result_event = 0;
+       client->all_result_text = NULL;
+
+       client->result_event = -1;
+       client->result_text = NULL;
+
+       client->service_state = -1;
+
+       client->before_state = VC_STATE_INITIALIZED;
+       client->current_state = VC_STATE_INITIALIZED; 
+
+       client->before_language = NULL;
+       client->current_language = NULL;
+
+       client->audio_id = NULL;
+
+       client->cb_ref_count = 0;
+
+       /* Authoriry */
+       client->authorized_client_list = NULL;
+       client->valid_authorized_pid = -1;
+       client->start_by_client = false;
+
+       g_mgr_client_list = g_slist_append(g_mgr_client_list, client);
+
+       *vc = temp;
+
+       return 0;
+}
+
+int vc_mgr_client_destroy(vc_h vc)
+{
+       if (vc == NULL) {
+               SLOG(LOG_ERROR, TAG_VCM, "Input parameter is NULL");
+               return 0;
+       }       
+
+       vc_mgr_client_s *data = NULL;
+
+       int count = g_slist_length(g_mgr_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_mgr_client_list, i);
+
+               if (NULL != data) {
+                       if (vc->handle == data->vc->handle) {
+                               g_mgr_client_list =  g_slist_remove(g_mgr_client_list, data);
+
+                               while (0 != data->cb_ref_count)
+                               {
+                                       /* wait for release callback function */
+                               }
+
+                               if (NULL != data->audio_id) {
+                                       free(data->audio_id);
+                               }
+
+                               if (NULL != data->all_result_text) {
+                                       free(data->all_result_text);
+                               }
+
+                               free(data);     data = NULL;
+                               free(vc);       vc = NULL;
+
+                               return 0;
+                       }
+               }
+       }
+
+       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] client Not found");
+
+       return -1;
+}
+
+bool vc_mgr_client_is_valid(vc_h vc)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) {
+               SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] vc is not valid");
+               return false;
+       }
+
+       return true;
+}
+
+bool vc_mgr_client_is_valid_by_uid(int uid)
+{
+       vc_mgr_client_s *data = NULL;
+
+       int count = g_slist_length(g_mgr_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_mgr_client_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) 
+                               return true;
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] Fail to get client by vc");
+
+       return false;
+}
+
+int vc_mgr_client_get_handle(int uid, vc_h* vc)
+{
+       vc_mgr_client_s *data = NULL;
+       
+       int count = g_slist_length(g_mgr_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_mgr_client_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) {
+                               *vc = data->vc;
+                               return 0;
+                       }
+               }
+       }
+       
+       return -1;
+}
+
+int vc_mgr_client_get_pid(vc_h vc, int* pid)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) {
+               SLOG(LOG_DEBUG, TAG_VCM, "[DEBUG] vc is not valid");
+               return -1;
+       }
+
+       *pid = client->pid;
+       return 0;
+}
+
+/* set/get callback function */
+int vc_mgr_client_set_all_result_cb(vc_h vc, vc_mgr_all_result_cb callback, void* user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->all_result_cb = callback;
+       client->all_result_user_data = user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_get_all_result_cb(vc_h vc, vc_mgr_all_result_cb* callback, void** user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->all_result_cb;
+       *user_data = client->all_result_user_data;
+
+       return 0;       
+}
+
+int vc_mgr_client_set_result_cb(vc_h vc, vc_result_cb callback, void* user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->result_cb = callback;
+       client->result_user_data = user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->result_cb;
+       *user_data = client->result_user_data;
+
+       return 0;       
+}
+
+int vc_mgr_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->service_state_changed_cb = callback;
+       client->service_state_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_get_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb* callback, void** user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->service_state_changed_cb;
+       *user_data = client->service_state_changed_user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_set_state_changed_cb(vc_h vc, vc_state_changed_cb callback, void* user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->state_changed_cb = callback;
+       client->state_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_get_state_changed_cb(vc_h vc, vc_state_changed_cb* callback, void** user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->state_changed_cb;
+       *user_data = client->state_changed_user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_set_speech_detected_cb(vc_h vc, vc_mgr_begin_speech_detected_cb callback, void* user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->speech_detected_cb = callback;
+       client->speech_detected_user_data = user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_get_speech_detected_cb(vc_h vc, vc_mgr_begin_speech_detected_cb* callback, void** user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->speech_detected_cb;
+       *user_data = client->speech_detected_user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_set_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb callback, void* user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->current_lang_changed_cb = callback;
+       client->current_lang_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_get_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb* callback, void** user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->current_lang_changed_cb;
+       *user_data = client->current_lang_changed_user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_set_error_cb(vc_h vc, vc_error_cb callback, void* user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->error_cb = callback;
+       client->error_user_data = user_data;
+
+       return 0;
+}
+
+int vc_mgr_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = client->error_cb;
+       *user_data = client->error_user_data;
+
+       return 0;
+}
+
+
+/* set/get option */
+int vc_mgr_client_set_service_state(vc_h vc, vc_service_state_e state)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->service_state = state;
+
+       return 0;
+}
+
+int vc_mgr_client_get_service_state(vc_h vc, vc_service_state_e* state)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *state = client->service_state;
+
+       return 0;
+}
+
+int vc_mgr_client_set_client_state(vc_h vc, vc_state_e state)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->before_state = client->current_state;
+       client->current_state = state;
+
+       return 0;
+}
+
+int vc_mgr_client_get_client_state(vc_h vc, vc_state_e* state)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *state = client->current_state;
+
+       return 0;
+}
+
+int vc_mgr_client_get_client_state_by_uid(int uid, vc_state_e* state)
+{
+       vc_mgr_client_s *data = NULL;
+
+       int count = g_slist_length(g_mgr_client_list);
+       int i; 
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_mgr_client_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) {
+                               *state = data->current_state;
+                               return 0;
+                       }
+               }
+       }
+
+       return -1;
+}
+
+int vc_mgr_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_state)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *before_state = client->before_state;
+       *state = client->current_state;
+
+       return 0;
+}
+
+int vc_mgr_client_set_error(vc_h vc, int reason)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->reason = reason;
+
+       return 0;
+}
+
+int vc_mgr_client_get_error(vc_h vc, int* reason)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *reason = client->reason;
+
+       return 0;
+}
+
+int vc_mgr_client_set_exclusive_command(vc_h vc, bool value)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->exclusive_cmd_option = value;
+
+       return 0;
+}
+
+bool vc_mgr_client_get_exclusive_command(vc_h vc)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       return client->exclusive_cmd_option;
+}
+
+int vc_mgr_client_set_all_result(vc_h vc, int event, const char* result_text)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->all_result_event = event;
+
+       if (NULL != client->all_result_text) {
+               free(client->all_result_text);
+       }
+       client->all_result_text = strdup(result_text);
+
+       return 0;
+}
+
+int vc_mgr_client_get_all_result(vc_h vc, int* event, char** result_text)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *event = client->all_result_event;
+       if (NULL != result_text) {
+               if (NULL != client->all_result_text) {
+                       *result_text = strdup(client->all_result_text);
+               }
+       }
+
+       return 0;
+}
+
+int vc_mgr_client_unset_all_result(vc_h vc)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->all_result_event = -1;
+
+       if (NULL != client->all_result_text) {
+               free(client->all_result_text);
+               client->all_result_text = NULL;
+       }
+       
+       return 0;
+}
+
+int vc_mgr_client_set_audio_type(vc_h vc, const char* audio_id)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       if (NULL != audio_id) {
+               if (NULL != client->audio_id) {
+                       free(client->audio_id);
+                       client->audio_id = NULL;
+               }
+               client->audio_id = strdup(audio_id);
+       }
+
+       return 0;
+}
+
+int vc_mgr_client_get_audio_type(vc_h vc, char** audio_id)
+{
+       if (NULL == audio_id)   {
+               return -1;
+       }
+
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       if (NULL != client->audio_id)
+               *audio_id = strdup(client->audio_id);
+       else
+               *audio_id = NULL;
+
+       return 0;
+}
+
+/* utils */
+int vc_mgr_client_get_count()
+{
+       return g_slist_length(g_mgr_client_list);
+}
+
+int vc_mgr_client_use_callback(vc_h vc)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->cb_ref_count++;
+       return 0;
+}
+
+int vc_mgr_client_not_use_callback(vc_h vc)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->cb_ref_count--;
+       return 0;
+}
+
+/* Authority */
+int vc_mgr_client_add_authorized_client(vc_h vc, int pid)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_authorized_client_s *authorized_client = NULL;
+
+       authorized_client = (vc_authorized_client_s*)calloc(1, sizeof(vc_authorized_client_s));
+       if (NULL == authorized_client) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to make authorized client");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       authorized_client->pid = pid;
+
+       client->authorized_client_list = g_slist_append(client->authorized_client_list, authorized_client);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "Add authorized client - %d", pid);
+
+       return 0;
+}
+
+int vc_mgr_client_remove_authorized_client(vc_h vc, int pid)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_authorized_client_s *data = NULL;
+
+       int count = g_slist_length(client->authorized_client_list);
+       int i;
+
+       for (i = 0; i < count; i++) {
+               data = g_slist_nth_data(client->authorized_client_list, i);
+
+               if (NULL != data) {
+                       if (pid == data->pid) {
+                               client->authorized_client_list = g_slist_remove(client->authorized_client_list, data);
+
+                               free(data);
+                               data = NULL;
+
+                               SLOG(LOG_DEBUG, TAG_VCM, "Remove authorized client - %d", pid);
+                               return 0;
+                       }
+               }
+       }
+
+       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] client Not found");
+
+       return VC_ERROR_OPERATION_FAILED;
+}
+
+bool vc_mgr_client_is_authorized_client(vc_h vc, int pid)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_authorized_client_s *data = NULL;
+
+       int count = g_slist_length(client->authorized_client_list);
+       int i;
+
+       for (i = 0; i < count; i++) {
+               data = g_slist_nth_data(client->authorized_client_list, i);
+
+               if (NULL != data) {
+                       if (pid == data->pid) {
+                               SLOG(LOG_DEBUG, TAG_VCM, "Authorized client - %d", pid);
+                               return true;
+                       }
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "Un-Authorized client - %d", pid);
+
+       return false;
+}
+
+int vc_mgr_client_set_valid_authorized_client(vc_h vc, int pid)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->valid_authorized_pid = pid;
+
+       return 0;
+}
+
+int vc_mgr_client_get_valid_authorized_client(vc_h vc, int* pid)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *pid = client->valid_authorized_pid;
+
+       return 0;
+}
+
+bool vc_mgr_client_is_valid_authorized_client(vc_h vc, int pid)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       if (pid == client->valid_authorized_pid)
+               return true;
+       else
+               return false;
+}
+
+int vc_mgr_client_set_start_by_client(vc_h vc, bool option)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       client->start_by_client = option;
+
+       return 0;
+}
+
+int vc_mgr_client_get_start_by_client(vc_h vc, bool* option)
+{
+       vc_mgr_client_s* client = __mgr_client_get(vc);
+
+       /* check handle */
+       if (NULL == client)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *option = client->start_by_client;
+
+       return 0;
+}
\ No newline at end of file
diff --git a/client/vc_mgr_client.h b/client/vc_mgr_client.h
new file mode 100644 (file)
index 0000000..d30ab97
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VC_MANAGER_CLIENT_H_
+#define __VC_MANAGER_CLIENT_H_
+
+
+#include "vc_info_parser.h"
+#include "voice_control_manager.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 
+* Common function 
+*/
+int vc_mgr_client_create(vc_h* vc);
+
+int vc_mgr_client_destroy(vc_h vc);
+
+bool vc_mgr_client_is_valid(vc_h vc);
+
+bool vc_mgr_client_is_valid_by_uid(int uid);
+
+int vc_mgr_client_get_handle(int uid, vc_h* vc);
+
+int vc_mgr_client_get_pid(vc_h vc, int* pid);
+
+/* 
+* set/get callback function 
+*/
+int vc_mgr_client_set_all_result_cb(vc_h vc, vc_mgr_all_result_cb callback, void* user_data);
+
+int vc_mgr_client_get_all_result_cb(vc_h vc, vc_mgr_all_result_cb* callback, void** user_data);
+
+int vc_mgr_client_set_result_cb(vc_h vc, vc_result_cb callback, void* user_data);
+
+int vc_mgr_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_data);
+
+int vc_mgr_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data);
+
+int vc_mgr_client_get_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb* callback, void** user_data);
+
+int vc_mgr_client_set_state_changed_cb(vc_h vc, vc_state_changed_cb callback, void* user_data);
+
+int vc_mgr_client_get_state_changed_cb(vc_h vc, vc_state_changed_cb* callback, void** user_data);
+
+int vc_mgr_client_set_speech_detected_cb(vc_h vc, vc_mgr_begin_speech_detected_cb callback, void* user_data);
+
+int vc_mgr_client_get_speech_detected_cb(vc_h vc, vc_mgr_begin_speech_detected_cb* callback, void** user_data);
+
+int vc_mgr_client_set_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb callback, void* user_data);
+
+int vc_mgr_client_get_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb* callback, void** user_data);
+
+int vc_mgr_client_set_error_cb(vc_h vc, vc_error_cb callback, void* user_data);
+
+int vc_mgr_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data);
+
+
+/* 
+* set/get option 
+*/
+int vc_mgr_client_set_service_state(vc_h vc, vc_service_state_e state);
+
+int vc_mgr_client_get_service_state(vc_h vc, vc_service_state_e* state);
+
+int vc_mgr_client_set_client_state(vc_h vc, vc_state_e state);
+
+int vc_mgr_client_get_client_state(vc_h vc, vc_state_e* state);
+
+int vc_mgr_client_get_client_state_by_uid(int uid, vc_state_e* state);
+
+int vc_mgr_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_state);
+
+int vc_mgr_client_set_error(vc_h vc, int reason);
+
+int vc_mgr_client_get_error(vc_h vc, int* reason);
+
+int vc_mgr_client_set_exclusive_command(vc_h vc, bool value);
+
+bool vc_mgr_client_get_exclusive_command(vc_h vc);
+
+int vc_mgr_client_set_all_result(vc_h vc, int event, const char* result_text);
+
+int vc_mgr_client_get_all_result(vc_h vc, int* event, char** result_text);
+
+int vc_mgr_client_unset_all_result(vc_h vc);
+
+int vc_mgr_client_set_audio_type(vc_h vc, const char* audio_id);
+
+int vc_mgr_client_get_audio_type(vc_h vc, char** audio_id);
+
+
+/* utils */
+int vc_mgr_client_get_count();
+
+int vc_mgr_client_use_callback(vc_h vc);
+
+int vc_mgr_client_not_use_callback(vc_h vc);
+
+/* Authority */
+int vc_mgr_client_add_authorized_client(vc_h vc, int pid);
+
+int vc_mgr_client_remove_authorized_client(vc_h vc, int pid);
+
+bool vc_mgr_client_is_authorized_client(vc_h vc, int pid);
+
+int vc_mgr_client_set_valid_authorized_client(vc_h vc, int pid);
+
+int vc_mgr_client_get_valid_authorized_client(vc_h vc, int* pid);
+
+bool vc_mgr_client_is_valid_authorized_client(vc_h vc, int pid);
+
+int vc_mgr_client_set_start_by_client(vc_h vc, bool option);
+
+int vc_mgr_client_get_start_by_client(vc_h vc, bool* option);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_MANAGER_CLIENT_H_ */
diff --git a/client/vc_mgr_dbus.c b/client/vc_mgr_dbus.c
new file mode 100644 (file)
index 0000000..be13390
--- /dev/null
@@ -0,0 +1,1487 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_main.h"
+#include "vc_mgr_client.h"
+#include "vc_mgr_dbus.h"
+#include "vc_command.h"
+
+
+static int g_m_waiting_time = 3000;
+
+static Ecore_Fd_Handler* g_m_fd_handler = NULL;
+
+static DBusConnection* g_m_conn = NULL;
+
+
+extern void __vc_mgr_cb_all_result();
+
+extern void __vc_mgr_cb_system_result();
+
+extern void __vc_mgr_cb_speech_detected();
+
+extern int __vc_mgr_cb_error(int pid, int reason);
+
+/* Authority */
+extern int __vc_mgr_request_auth_enable(int pid);
+
+extern int __vc_mgr_request_auth_disable(int pid);
+
+extern int __vc_mgr_request_auth_start(int pid);
+
+extern int __vc_mgr_request_auth_stop(int pid);
+
+extern int __vc_mgr_request_auth_cancel(int pid);
+
+static Eina_Bool vc_mgr_listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
+{
+       DBusConnection* conn = (DBusConnection*)data;
+       DBusMessage* msg = NULL;
+       DBusMessage *reply = NULL;
+
+       if (NULL == conn)
+               return ECORE_CALLBACK_RENEW;
+
+       dbus_connection_read_write_dispatch(conn, 50);
+
+       msg = dbus_connection_pop_message(conn);
+
+       /* loop again if we haven't read a message */
+       if (NULL == msg) { 
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       char if_name[64];
+       snprintf(if_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, getpid());
+
+       if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_HELLO)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get Hello");
+               int pid = 0;
+               int response = -1;
+
+               dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+                       dbus_error_free(&err);
+               }
+
+               if (pid > 0) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc get hello : pid(%d) ", pid);
+                       response = 1;
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc get hello : invalid pid ");
+               }
+
+               reply = dbus_message_new_method_return(msg);
+               
+               if (NULL != reply) {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &response, DBUS_TYPE_INVALID);
+
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc get hello : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc get hello : result(%d)", response);
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc get hello : fail to create reply message");
+               }
+               
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+       } /* VCD_METHOD_HELLO */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_SPEECH_DETECTED)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get Speech detected");
+
+               __vc_mgr_cb_speech_detected();
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr get speech detected : fail to send reply");
+                       else
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr get speech detected");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr get speech detected : fail to create reply message");
+               }
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       }/* VCD_MANAGER_METHOD_SPEECH_DETECTED */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_ALL_RESULT)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get All Result");
+               
+               __vc_mgr_cb_all_result();
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr get all result : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr get all result");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr get all result : fail to create reply message");
+               }
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       }/* VCD_MANAGER_METHOD_ALL_RESULT */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_RESULT)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get System Result");
+
+               __vc_mgr_cb_system_result();
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr get system result : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr get system result");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr get system result : fail to create reply message");
+               }
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+
+       }/* VCD_MANAGER_METHOD_RESULT */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_MANAGER_METHOD_ERROR)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get Error");
+               int pid;
+               int reason;
+               char* err_msg;
+
+               dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &pid,
+                       DBUS_TYPE_INT32, &reason,
+                       DBUS_TYPE_STRING, &err_msg,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc Get Error message : Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc Get Error message : pid(%d), reason(%d), msg(%s)", pid, reason, err_msg);
+                       __vc_mgr_cb_error(pid, reason);
+               }
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc Error message : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc Error message");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc Error message : fail to create reply message");
+               }
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+       }/* VCD_MANAGER_METHOD_ERROR */
+
+       /* Authority */
+       else if (dbus_message_is_method_call(msg, if_name, VC_METHOD_AUTH_ENABLE)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get request auth enable");
+               int pid;
+               int ret = 0;
+
+               dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &pid,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc request auth enable : Get arguments error (%s)", err.message);
+                       dbus_error_free(&err);
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc request auth enable : pid(%d)", pid);
+                       ret = __vc_mgr_request_auth_enable(pid);
+               }
+
+               reply = dbus_message_new_method_return(msg);
+               
+               if (NULL != reply) {
+                       dbus_message_append_args(reply,
+                               DBUS_TYPE_INT32, &ret,
+                               DBUS_TYPE_INVALID);
+                       if (!dbus_connection_send(conn, reply ,NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth enable : fail to send reply");
+                       else
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc request auth enable : ret(%d)", ret);
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth enable : fail to create reply message");
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+       }/* VC_METHOD_AUTH_ENABLE */
+
+       else if (dbus_message_is_method_call(msg, if_name, VC_METHOD_AUTH_DISABLE)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get request auth disable");
+               int pid;
+               int ret = 0;
+
+               dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &pid,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc request auth disable : Get arguments error (%s)", err.message);
+                       dbus_error_free(&err);
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc request auth disable : pid(%d)", pid);
+                       ret = __vc_mgr_request_auth_disable(pid);
+               }
+
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       dbus_message_append_args(reply,
+                               DBUS_TYPE_INT32, &ret,
+                               DBUS_TYPE_INVALID);
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth disable : fail to send reply");
+                       else
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc request auth disable : ret(%d)", ret);
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth disable : fail to create reply message");
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+       }/* VC_METHOD_AUTH_DISABLE */
+
+       else if (dbus_message_is_method_call(msg, if_name, VC_METHOD_AUTH_START)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get request auth start");
+               int pid;
+               int ret = 0;
+
+               dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &pid,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc request auth start : Get arguments error (%s)", err.message);
+                       dbus_error_free(&err);
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc request auth start : pid(%d)", pid);
+                       ret = __vc_mgr_request_auth_start(pid);
+               }
+
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       dbus_message_append_args(reply,
+                               DBUS_TYPE_INT32, &ret,
+                               DBUS_TYPE_INVALID);
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth start : fail to send reply");
+                       else
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc request auth start : ret(%d)", ret);
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth start : fail to create reply message");
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+       }/* VC_METHOD_AUTH_START */
+
+       else if (dbus_message_is_method_call(msg, if_name, VC_METHOD_AUTH_STOP)) {
+               SLOG(LOG_DEBUG,TAG_VCM, "===== Get request auth stop");
+               int pid;
+               int ret = 0;
+
+               dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &pid,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc request auth stop : Get arguments error (%s)", err.message);
+                       dbus_error_free(&err);
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc request auth stop : pid(%d)", pid);
+                       ret = __vc_mgr_request_auth_stop(pid);
+               }
+
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       dbus_message_append_args(reply,
+                               DBUS_TYPE_INT32, &ret,
+                               DBUS_TYPE_INVALID);
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth stop : fail to send reply");
+                       else
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc request auth stop : ret(%d)", ret);
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth stop : fail to create reply message");
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+       }/* VC_METHOD_AUTH_STOP */
+
+       else if (dbus_message_is_method_call(msg, if_name, VC_METHOD_AUTH_CANCEL)) {
+               SLOG(LOG_DEBUG, TAG_VCM, "===== Get request auth cancel");
+               int pid;
+               int ret = 0;
+
+               dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &pid,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc request auth cancel : Get arguments error (%s)", err.message);
+                       dbus_error_free(&err);
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc request auth cancel : pid(%d)", pid);
+                       ret = __vc_mgr_request_auth_cancel(pid);
+               }
+
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       dbus_message_append_args(reply,
+                               DBUS_TYPE_INT32, &ret,
+                               DBUS_TYPE_INVALID);
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth cancel : fail to send reply");
+                       else
+                               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc request auth cancel : ret(%d)", ret);
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, ">>>> vc request auth cancel : fail to create reply message");
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCM, "=====");
+               SLOG(LOG_DEBUG, TAG_VCM, " ");
+       }/* VC_METHOD_AUTH_CANCEL */
+
+       /* free the message */
+       dbus_message_unref(msg);
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+int vc_mgr_dbus_open_connection()
+{
+       if (NULL != g_m_conn) {
+               SLOG(LOG_WARN, TAG_VCM, "already existed connection ");
+               return 0;
+       }
+
+       DBusError err;
+       int ret;
+
+       /* initialise the error value */
+       dbus_error_init(&err);
+
+       /* connect to the DBUS system bus, and check for errors */
+       g_m_conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCM, "Dbus Connection Error (%s)", err.message); 
+               dbus_error_free(&err); 
+       }
+
+       if (NULL == g_m_conn) {
+               SLOG(LOG_ERROR, TAG_VCM, "Fail to get dbus connection ");
+               return VC_ERROR_OPERATION_FAILED; 
+       }
+
+       int pid = getpid();
+
+       char service_name[64];
+       memset(service_name, '\0', 64);
+       snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, pid);
+
+       SLOG(LOG_DEBUG, TAG_VCM, "service name is %s", service_name);
+
+       /* register our name on the bus, and check for errors */
+       ret = dbus_bus_request_name(g_m_conn, service_name, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "Name Error (%s)", err.message); 
+               dbus_error_free(&err); 
+       }
+
+       if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+               SLOG(LOG_ERROR, TAG_VCM, "fail dbus_bus_request_name()");
+               return -2;
+       }
+
+       if (NULL != g_m_fd_handler) {
+               SLOG(LOG_WARN, TAG_VCM, "The handler already exists.");
+               return 0;
+       }
+
+       char rule[128];
+       snprintf(rule, 128, "type='signal',interface='%s%d'", VC_MANAGER_SERVICE_INTERFACE, pid);
+
+       /* add a rule for which messages we want to see */
+       dbus_bus_add_match(g_m_conn, rule, &err); 
+       dbus_connection_flush(g_m_conn);
+
+       if (dbus_error_is_set(&err)) 
+       { 
+               SLOG(LOG_ERROR, TAG_VCM, "Match Error (%s)", err.message);
+               dbus_error_free(&err);
+               return VC_ERROR_OPERATION_FAILED; 
+       }
+
+       int fd = 0;
+       if (1 != dbus_connection_get_unix_fd(g_m_conn, &fd)) {
+               SLOG(LOG_ERROR, TAG_VCM, "fail to get fd from dbus ");
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "Get fd from dbus : %d", fd);
+       }
+
+       g_m_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)vc_mgr_listener_event_callback, g_m_conn, NULL, NULL);
+
+       if (NULL == g_m_fd_handler) {
+               SLOG(LOG_ERROR, TAG_VCM, "fail to get fd handler from ecore ");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       return 0;
+}
+
+int vc_mgr_dbus_close_connection()
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid = getpid();
+
+       char service_name[64];
+       memset(service_name, '\0', 64);
+       snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, pid);
+
+       dbus_bus_release_name (g_m_conn, service_name, &err);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       dbus_connection_close(g_m_conn);
+
+       g_m_fd_handler = NULL;
+       g_m_conn = NULL;
+
+       return 0;
+}
+
+int vc_mgr_dbus_reconnect()
+{
+       bool connected = dbus_connection_get_is_connected(g_m_conn);
+       SECURE_SLOG(LOG_DEBUG, TAG_VCM, "[DBUS] %s", connected ? "Connected" : "Not connected");
+
+       if (false == connected) {
+               vc_mgr_dbus_close_connection();
+
+               if (0 != vc_mgr_dbus_open_connection()) {
+                       SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Fail to reconnect");
+                       return -1;
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCM, "[DBUS] Reconnect");
+       }
+       return 0;
+}
+
+int vc_mgr_dbus_request_hello()
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_METHOD_HELLO);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> Request vc hello : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } 
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg = NULL;
+       int result = 0;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, 500, &err);
+
+       if (dbus_error_is_set(&err)) {
+               dbus_error_free(&err);
+       }
+
+       dbus_message_unref(msg);
+
+       if (NULL != result_msg) {
+               dbus_message_unref(result_msg);
+               result = 0;
+       } else {
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+
+int vc_mgr_dbus_request_initialize(int pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_MANAGER_METHOD_INITIALIZE);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr initialize : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr initialize : pid(%d)", pid);
+       }
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err, 
+                       DBUS_TYPE_INT32, &result, 
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr initialize : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr initialize : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCM, "<<<< Result message is NULL ");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_mgr_dbus_request_finalize(int pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_MANAGER_METHOD_FINALIZE);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr finalize : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr finalize : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err, 
+                               DBUS_TYPE_INT32, &result,
+                               DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr finalize : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr finalize : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCM, "<<<< Result message is NULL ");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_mgr_dbus_request_set_command(int pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_MANAGER_METHOD_SET_COMMAND);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr set command : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr set command : pid(%d)", pid);
+       }
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr set command : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr set command : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCM, "<<<< Result message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;  
+}
+
+int vc_mgr_dbus_request_unset_command(int pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_MANAGER_METHOD_UNSET_COMMAND);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr unset command : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr unset command : pid(%d)", pid);
+       }
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr unset command : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr unset command : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCM, "<<<< Result message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_mgr_dbus_request_demandable_client(int pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_MANAGER_METHOD_SET_DEMANDABLE);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr set demandable client : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr set demandable client : pid(%d)", pid);
+       }
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr set demandable client : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr set demandable client : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCM, "<<<< Result message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_mgr_dbus_request_set_audio_type(int pid, const char* audio_type)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_MANAGER_METHOD_SET_AUDIO_TYPE);              
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr set audio type : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr set audio type : pid(%d), audio type(%s)", pid, audio_type);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_STRING, &(audio_type),
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr set audio type : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr set audio type : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_mgr_dbus_request_get_audio_type(int pid, char** audio_type)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_MANAGER_METHOD_GET_AUDIO_TYPE);              
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr get audio type : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr get audio type : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+       char* temp = NULL;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_STRING, &temp,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       if (NULL != audio_type && NULL != temp) {
+                               *audio_type = strdup(temp);
+                       }
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr get audio type : result = %d audio type = %s", result, temp);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr get audio type : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_mgr_dbus_request_set_client_info(int pid)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_MANAGER_METHOD_SET_CLIENT_INFO);             
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr set client info : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr set client info : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr set client info : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr set client info : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+#if 0
+int vc_mgr_dbus_request_start(int pid, int silence, bool exclusive_command_option)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_MANAGER_METHOD_START);               
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr start : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr start : pid(%d), silence(%d) exclusive(%d)", 
+                       pid, silence, exclusive_command_option);
+       }
+
+       int temp = exclusive_command_option;
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INT32, &(silence),
+               DBUS_TYPE_INT32, &(temp),
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr start : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr start : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+#endif
+
+int vc_mgr_dbus_request_start(int pid, int silence, bool exclusive_command_option, bool start_by_client)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_MANAGER_METHOD_START);               
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr start : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr start : pid(%d), silence(%d) exclusive(%d) start by client(%d)", 
+                       pid, silence, exclusive_command_option, start_by_client);
+       }
+
+       int exclusive = exclusive_command_option;
+       int by = start_by_client;
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INT32, &(silence),
+               DBUS_TYPE_INT32, &(exclusive),
+               DBUS_TYPE_INT32, &(by),
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr start : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr start : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_mgr_dbus_request_stop(int pid)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_MANAGER_METHOD_STOP);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc mgr stop : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc mgr stop : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc mgr stop : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc mgr stop : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_mgr_dbus_request_cancel(int pid)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  /* object name of the signal */
+               VC_SERVER_SERVICE_INTERFACE,    /* interface name of the signal */
+               VC_MANAGER_METHOD_CANCEL);      /* name of the signal */
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc cancel : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc cancel : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc cancel : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc cancel : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+static DBusMessage* __get_message(int pid, const char* method, int type)
+{
+       char service_name[64];
+       char object_path[64];
+       char target_if_name[128];
+
+       memset(service_name, '\0', 64);
+       memset(object_path, '\0', 64);
+       memset(target_if_name, '\0', 128);
+       
+       if (VC_COMMAND_TYPE_FOREGROUND == type || VC_COMMAND_TYPE_BACKGROUND == type) {
+               snprintf(service_name, 64, "%s%d", VC_CLIENT_SERVICE_NAME, pid);
+               snprintf(object_path, 64, "%s", VC_CLIENT_SERVICE_OBJECT_PATH);
+               snprintf(target_if_name, 128, "%s%d", VC_CLIENT_SERVICE_NAME, pid);
+       } else if (VC_COMMAND_TYPE_WIDGET == type) {
+               snprintf(service_name, 64, "%s%d", VC_WIDGET_SERVICE_NAME, pid);
+               snprintf(object_path, 64, "%s", VC_WIDGET_SERVICE_OBJECT_PATH);
+               snprintf(target_if_name, 128, "%s%d", VC_WIDGET_SERVICE_INTERFACE, pid);
+       } else {
+               return NULL;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCM, "[Dbus] Service(%s) object(%s) if(%s)", service_name, object_path, target_if_name);
+
+       return dbus_message_new_method_call(service_name, object_path, target_if_name, method);
+}
+
+int vc_mgr_dbus_send_result(int pid, int cmd_type, int result_id)
+{
+       DBusMessage* msg = NULL;
+
+       switch (cmd_type) {
+       case VC_COMMAND_TYPE_FOREGROUND:
+       case VC_COMMAND_TYPE_BACKGROUND:        
+               msg = __get_message(pid, VCD_METHOD_RESULT, cmd_type);
+               break;
+       case VC_COMMAND_TYPE_WIDGET:
+               msg = __get_message(pid, VCD_WIDGET_METHOD_RESULT, cmd_type);
+               break;
+       default:
+               SLOG(LOG_ERROR, TAG_VCM, "[Dbus ERROR] Command type is NOT valid(%d)", cmd_type);
+               return -1;
+       }
+
+       if (NULL == msg)
+               SLOG(LOG_ERROR, TAG_VCM, "[Dbus ERROR] Message is NULL");
+
+       dbus_message_append_args(msg, DBUS_TYPE_INT32, &result_id, DBUS_TYPE_INVALID);
+
+       dbus_message_set_no_reply(msg, TRUE);
+
+       /* send the message and flush the connection */
+       if (!dbus_connection_send(g_m_conn, msg, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[Dbus ERROR] Fail to send result message"); 
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "[Dbus] Success to send result");
+
+               dbus_connection_flush(g_m_conn);
+       }
+
+       dbus_message_unref(msg);
+
+       return 0;
+}
+
+int vc_mgr_dbus_send_result_selection(int pid)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  /* object name of the signal */
+               VC_SERVER_SERVICE_INTERFACE,    /* interface name of the signal */
+               VC_MANAGER_METHOD_RESULT_SELECTION);    /* name of the signal */
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCM, ">>>> vc result selection : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, ">>>> vc result selection : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       dbus_message_set_no_reply(msg, TRUE);
+       
+       if (1 != dbus_connection_send(g_m_conn, msg, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[Dbus ERROR] Fail to Send");
+               return -1;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "[Dbus] SUCCESS Send");
+               dbus_connection_flush(g_m_conn);
+               return 0;
+       }
+
+       /*
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_m_conn, msg, g_m_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCM, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCM, "<<<< vc result selection : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCM, "<<<< vc result selection : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCM, "<<<< Result Message is NULL");
+               vc_mgr_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+       */
+}
diff --git a/client/vc_mgr_dbus.h b/client/vc_mgr_dbus.h
new file mode 100644 (file)
index 0000000..e5bce76
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __VC_DBUS_H_
+#define __VC_DBUS_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int vc_mgr_dbus_open_connection();
+
+int vc_mgr_dbus_close_connection();
+
+
+int vc_mgr_dbus_request_hello();
+
+int vc_mgr_dbus_request_initialize(int pid);
+
+int vc_mgr_dbus_request_finalize(int pid);
+
+int vc_mgr_dbus_request_set_command(int pid);
+
+int vc_mgr_dbus_request_unset_command(int pid);
+
+int vc_mgr_dbus_request_demandable_client(int pid);
+
+int vc_mgr_dbus_request_set_audio_type(int pid, const char* audio_type);
+
+int vc_mgr_dbus_request_get_audio_type(int pid, char** audio_type);
+
+int vc_mgr_dbus_request_set_client_info(int pid);
+
+#if 0
+int vc_mgr_dbus_request_start(int pid, int silence, bool exclusive_command_option);
+#endif
+
+int vc_mgr_dbus_request_start(int pid, int silence, bool exclusive_command_option, bool start_by_client);
+
+int vc_mgr_dbus_request_stop(int pid);
+
+int vc_mgr_dbus_request_cancel(int pid);
+
+int vc_mgr_dbus_send_result(int pid, int cmd_type, int result_id);
+
+int vc_mgr_dbus_send_result_selection(int pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_DBUS_H_ */
diff --git a/client/vc_setting.c b/client/vc_setting.c
new file mode 100644 (file)
index 0000000..7ae5467
--- /dev/null
@@ -0,0 +1,398 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_config_mgr.h"
+#include "vc_main.h"
+#include "voice_control_common.h"
+#include "voice_control_setting.h"
+
+/** 
+* @brief Enumerations of mode.
+*/
+typedef enum {
+       VC_SETTING_STATE_NONE = 0,
+       VC_SETTING_STATE_READY
+}vc_setting_state_e;
+
+#define VC_SETTING_CONFIG_HANDLE       300000
+
+static vc_setting_state_e g_state = VC_SETTING_STATE_NONE;
+
+static vc_setting_enabled_changed_cb g_callback;
+
+static void* g_user_data;
+
+
+const char* vc_tag()
+{
+       return TAG_VCS;
+}
+
+void __config_lang_changed_cb(const char* before_lang, const char* current_lang)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "Lang changed : before(%s) current(%s)", before_lang, current_lang);
+}
+
+void __vc_setting_state_changed_cb(int before_state, int current_state, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "Service State changed : Before(%d) Current(%d)", 
+               before_state, current_state);
+       return;
+}
+
+void __vc_setting_enabled_changed_cb(bool enabled)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "Service enabled changed : %s", enabled ? "on" : "off");
+
+       if (NULL != g_callback) {
+               g_callback(enabled, g_user_data);
+       }
+
+       return;
+}
+
+int vc_setting_initialize(void)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Initialize VC Setting");
+
+       if (VC_SETTING_STATE_READY == g_state) {
+               SLOG(LOG_WARN, TAG_VCS, "[WARNING] VC Setting has already been initialized.");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_NONE;
+       }
+
+       int ret = vc_config_mgr_initialize(getpid() + VC_SETTING_CONFIG_HANDLE);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to initialize config manager");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+       
+       ret = vc_config_mgr_set_lang_cb(getpid() + VC_SETTING_CONFIG_HANDLE, __config_lang_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Fail to initialize config manager");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       ret = vc_config_mgr_set_enabled_cb(getpid() + VC_SETTING_CONFIG_HANDLE, __vc_setting_enabled_changed_cb);
+       
+       g_state = VC_SETTING_STATE_READY;
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return VC_ERROR_NONE;
+}
+
+//int vc_setting_finalize()
+//{
+//     SLOG(LOG_DEBUG, TAG_VCS, "===== Finalize VC Setting");
+//
+//     vc_config_mgr_unset_lang_cb(getpid() + VC_SETTING_CONFIG_HANDLE);
+//     vc_config_mgr_finalize(getpid() + VC_SETTING_CONFIG_HANDLE);
+//
+//     g_state = VC_SETTING_STATE_NONE;
+//     
+//     SLOG(LOG_DEBUG, TAG_VCS, "=====");
+//     SLOG(LOG_DEBUG, TAG_VCS, " ");
+//
+//     return VC_ERROR_NONE;
+//}
+
+int vc_setting_deinitialize()
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Deinitialize VC Setting");
+
+       vc_config_mgr_unset_lang_cb(getpid() + VC_SETTING_CONFIG_HANDLE);
+       vc_config_mgr_finalize(getpid() + VC_SETTING_CONFIG_HANDLE);
+
+       g_state = VC_SETTING_STATE_NONE;
+       
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_setting_foreach_supported_languages(vc_setting_supported_language_cb callback, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Foreach supported languages");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Param is NULL");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = vc_config_mgr_get_language_list((vc_supported_language_cb)callback, user_data);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCS, "[SUCCESS] Foreach supported languages");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return ret;
+}
+
+int vc_setting_get_language(char** language)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Get default language");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (NULL == language) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Input parameter is NULL");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = vc_config_mgr_get_default_language(language);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCS, "[SUCCESS] Get default language");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return ret;
+}
+
+int vc_setting_set_language(const char* language)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Set default language");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (NULL == language) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Input parameter is NULL");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = vc_config_mgr_set_default_language(language);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCS, "[SUCCESS] Set default language");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+    
+       return ret;
+}
+
+int vc_setting_set_auto_language(bool value)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Set auto voice");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (value != true && value != false) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Invalid value");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = vc_config_mgr_set_auto_language(value);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCS, "[SUCCESS] Set auto language (%s)", value ? "on" : "off");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return ret;
+}
+
+int vc_setting_get_auto_language(bool* value)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Get auto language");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (NULL == value) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Param is NULL");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = vc_config_mgr_get_auto_language(value);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCS, "[SUCCESS] Get auto language (%s)", *value ? "true":"false");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return 0;
+}
+
+int vc_setting_set_enabled(bool value)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Set service enabled");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (value != true && value != false) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Invalid value");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = vc_config_mgr_set_enabled(value);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCS, "[SUCCESS] Set service enabled (%s)", value ? "on" : "off");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return ret;
+}
+
+int vc_setting_get_enabled(bool* value)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Get service enabled");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (NULL == value) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Param is NULL");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = vc_config_mgr_get_enabled(value);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Result : %d", ret);
+       } else {
+               /* Copy value */
+               SLOG(LOG_DEBUG, TAG_VCS, "[SUCCESS] Get service enabled (%s)", *value ? "on" : "off");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return ret;
+}
+
+int vc_setting_set_enabled_changed_cb(vc_setting_enabled_changed_cb callback, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Set service enabled callback");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Param is NULL");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       g_callback = callback;
+       g_user_data = user_data;
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return 0;
+}
+
+int vc_setting_unset_enabled_changed_cb()
+{
+       SLOG(LOG_DEBUG, TAG_VCS, "===== Unset service enabled callback");
+
+       if (VC_SETTING_STATE_NONE == g_state) {
+               SLOG(LOG_ERROR, TAG_VCS, "[ERROR] Not initialized");
+               SLOG(LOG_DEBUG, TAG_VCS, "=====");
+               SLOG(LOG_DEBUG, TAG_VCS, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       g_callback = NULL;
+       g_user_data = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCS, "=====");
+       SLOG(LOG_DEBUG, TAG_VCS, " ");
+
+       return 0;
+}
\ No newline at end of file
diff --git a/client/vc_widget.c b/client/vc_widget.c
new file mode 100644 (file)
index 0000000..d04a545
--- /dev/null
@@ -0,0 +1,1330 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_command.h"
+#include "vc_config_mgr.h"
+#include "vc_info_parser.h"
+#include "vc_main.h"
+#include "vc_widget_client.h"
+#include "vc_widget_dbus.h"
+#include "voice_control_command.h"
+#include "voice_control_command_expand.h"
+#include "voice_control_widget.h"
+
+
+#define VC_WIDGET_CONFIG_HANDLE        200000
+
+static bool g_w_is_daemon_started = false;
+
+static Ecore_Timer* g_w_connect_timer = NULL;
+
+static Ecore_Timer* g_w_start_timer = NULL;
+static Ecore_Timer* g_w_tooltip_timer = NULL;
+
+static vc_h g_vc_w = NULL;
+
+static Eina_Bool __vc_widget_notify_state_changed(void *data);
+static Eina_Bool __vc_widget_notify_error(void *data);
+
+const char* vc_tag()
+{
+       return TAG_VCW;
+}
+
+static const char* __vc_widget_get_error_code(vc_error_e err)
+{
+       switch(err) {
+               case VC_ERROR_NONE:             return "VC_ERROR_NONE";                 break;
+               case VC_ERROR_OUT_OF_MEMORY:    return "VC_ERROR_OUT_OF_MEMORY";        break;
+               case VC_ERROR_IO_ERROR:         return "VC_ERROR_IO_ERROR";             break;
+               case VC_ERROR_INVALID_PARAMETER:return "VC_ERROR_INVALID_PARAMETER";    break;
+               case VC_ERROR_TIMED_OUT:        return "VC_ERROR_TIMED_OUT";            break;
+               case VC_ERROR_INVALID_STATE:    return "VC_ERROR_INVALID_STATE";        break;
+               case VC_ERROR_ENGINE_NOT_FOUND: return "VC_ERROR_ENGINE_NOT_FOUND";     break;
+               case VC_ERROR_OPERATION_FAILED: return "VC_ERROR_OPERATION_FAILED";     break;
+               default:                        return "Invalid error code";            break;
+       }
+       return NULL;
+}
+
+static int __vc_widget_convert_config_error_code(vc_config_error_e code)
+{
+       if (code == VC_CONFIG_ERROR_NONE)                       return VC_ERROR_NONE;
+       if (code == VC_CONFIG_ERROR_OUT_OF_MEMORY)              return VC_ERROR_OUT_OF_MEMORY;
+       if (code == VC_CONFIG_ERROR_IO_ERROR)                   return VC_ERROR_IO_ERROR;
+       if (code == VC_CONFIG_ERROR_INVALID_PARAMETER)          return VC_ERROR_INVALID_PARAMETER;
+       if (code == VC_CONFIG_ERROR_INVALID_STATE)              return VC_ERROR_INVALID_STATE;
+       if (code == VC_CONFIG_ERROR_INVALID_LANGUAGE)           return VC_ERROR_INVALID_LANGUAGE;
+       if (code == VC_CONFIG_ERROR_ENGINE_NOT_FOUND)           return VC_ERROR_ENGINE_NOT_FOUND;
+       if (code == VC_CONFIG_ERROR_OPERATION_FAILED)           return VC_ERROR_OPERATION_FAILED;
+
+       return VC_ERROR_NONE;
+}
+
+static void __vc_widget_lang_changed_cb(const char* before_lang, const char* current_lang)
+{
+       SECURE_SLOG(LOG_DEBUG, TAG_VCW, "Lang changed : Before lang(%s) Current lang(%s)", 
+               before_lang, current_lang);
+
+       vc_current_language_changed_cb callback;
+       void* lang_user_data;
+       vc_widget_client_get_current_lang_changed_cb(g_vc_w, &callback, &lang_user_data);
+
+       if (NULL != callback) {
+               vc_widget_client_use_callback(g_vc_w);
+               callback(before_lang, current_lang, lang_user_data);
+               vc_widget_client_not_use_callback(g_vc_w);
+               SLOG(LOG_DEBUG, TAG_VCW, "Language changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCW, "[WARNING] Language changed callback is null");
+       }
+
+       return;
+}
+
+static void __vc_widget_service_state_changed_cb(int before_state, int current_state)
+{
+       SECURE_SLOG(LOG_DEBUG, TAG_VCW, "Service State changed : Before(%d) Current(%d)", 
+               before_state, current_state);
+
+       /* Save service state */
+       vc_widget_client_set_service_state(g_vc_w, (vc_service_state_e)current_state);
+
+       vc_service_state_changed_cb service_callback = NULL;
+       void* service_user_data;
+       vc_widget_client_get_service_state_changed_cb(g_vc_w, &service_callback, &service_user_data);
+
+       if (NULL != service_callback) {
+               vc_widget_client_use_callback(g_vc_w);
+               service_callback((vc_service_state_e)before_state, (vc_service_state_e)current_state, service_user_data);
+               vc_widget_client_not_use_callback(g_vc_w);
+               SLOG(LOG_DEBUG, TAG_VCW, "Service state changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCW, "[WARNING] State changed callback is null");
+       }
+
+       return;
+}
+
+int vc_widget_initialize()
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Initialize");
+
+       /* check handle */
+       if (true == vc_widget_client_is_valid(g_vc_w)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[WARNING] Already initialized");
+               return VC_ERROR_NONE;
+       }
+
+       if (0 == vc_widget_client_get_count()) {
+               if (0 != vc_widget_dbus_open_connection()) {
+                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to open connection");
+                       return VC_ERROR_OPERATION_FAILED;
+               }
+       } else {
+               SLOG(LOG_WARN, TAG_VCW, "[WARN] Already initialized");
+               return VC_ERROR_NONE;
+       }
+
+       if (0 != vc_widget_client_create(&g_vc_w)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to create client!!!!!");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       int ret = vc_config_mgr_initialize(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to init config manager : %s", 
+                       __vc_widget_get_error_code(__vc_widget_convert_config_error_code(ret)));
+               vc_widget_client_destroy(g_vc_w);
+               return __vc_widget_convert_config_error_code(ret);
+       }
+
+       ret = vc_config_mgr_set_lang_cb(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE, __vc_widget_lang_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to set config changed : %d", ret);
+               vc_config_mgr_finalize(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE);
+               vc_widget_client_destroy(g_vc_w);
+               return __vc_widget_convert_config_error_code(ret);
+       }
+
+       ret = vc_config_mgr_set_service_state_cb(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE, __vc_widget_service_state_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to set service state callback : %d", ret);
+               vc_config_mgr_unset_lang_cb(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE);
+               vc_config_mgr_finalize(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE);
+               vc_widget_client_destroy(g_vc_w);
+               return __vc_widget_convert_config_error_code(ret);
+       }
+
+       int service_state = -1;
+       if (0 != vc_config_mgr_get_service_state(&service_state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get service state");
+               vc_config_mgr_finalize(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE);
+               vc_widget_client_destroy(g_vc_w);
+               return __vc_widget_convert_config_error_code(ret);
+       }
+
+       vc_widget_client_set_service_state(g_vc_w, service_state);
+
+       SLOG(LOG_DEBUG, TAG_VCW, "[Success] pid(%d)", g_vc_w->handle);
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+
+static void __vc_widget_internal_unprepare()
+{
+       int ret = vc_widget_dbus_request_finalize(g_vc_w->handle);
+       if (0 != ret) {
+               SLOG(LOG_WARN, TAG_VCW, "[ERROR] Fail to request finalize : %s", __vc_widget_get_error_code(ret));
+       }
+
+       g_w_is_daemon_started = false;
+
+       vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_WIDGET);
+
+       return;
+}
+
+int vc_widget_deinitialize()
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Deinitialize");
+
+       if (false == vc_widget_client_is_valid(g_vc_w)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] NOT initialized");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_state_e state;
+       vc_widget_client_get_state(g_vc_w, &state);
+
+       /* check state */
+       switch (state) {
+       case VC_STATE_READY:
+               __vc_widget_internal_unprepare();
+               /* no break. need to next step*/
+       case VC_STATE_INITIALIZED:
+               if (NULL != g_w_connect_timer) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "Connect Timer is deleted");
+                       ecore_timer_del(g_w_connect_timer);
+               }
+
+               vc_config_mgr_unset_service_state_cb(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE);
+               vc_config_mgr_unset_lang_cb(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE);
+               vc_config_mgr_finalize(g_vc_w->handle + VC_WIDGET_CONFIG_HANDLE);
+
+               /* Free resources */
+               vc_widget_client_destroy(g_vc_w);
+               g_vc_w = NULL;
+               break;
+       case VC_STATE_NONE:
+               break;
+       default:
+               break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "Success: destroy");
+
+       if (0 != vc_widget_dbus_close_connection()) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to close connection");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+
+static void __vc_widget_fork_vc_daemon()
+{
+       int pid, i;
+       pid = fork();
+
+       switch(pid) {
+       case -1:
+               SLOG(LOG_ERROR, TAG_VCW, "Fail to create daemon");
+               break;
+       case 0:
+               setsid();
+               for (i = 0;i < _NSIG;i++)
+                       signal(i, SIG_DFL);
+
+               execl(VC_DAEMON_PATH, VC_DAEMON_PATH, NULL);
+               break;
+       default:
+               break;
+       }
+       return;
+}
+
+static Eina_Bool __vc_widget_connect_daemon(void *data)
+{
+       /* Send hello */
+       if (0 != vc_widget_dbus_request_hello()) {
+               if (false == g_w_is_daemon_started) {
+                       g_w_is_daemon_started = true;
+                       __vc_widget_fork_vc_daemon();
+               }
+               return EINA_TRUE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Connect daemon");
+
+       /* request initialization */
+       int ret = -1;
+       ret = vc_widget_dbus_request_initialize(g_vc_w->handle);
+
+       if (VC_ERROR_ENGINE_NOT_FOUND == ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to initialize : %s", __vc_widget_get_error_code(ret));
+
+               vc_widget_client_set_error(g_vc_w, VC_ERROR_ENGINE_NOT_FOUND);
+               ecore_timer_add(0, __vc_widget_notify_error, g_vc_w);
+
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, "  ");
+               return EINA_FALSE;
+
+       } else if (VC_ERROR_NONE != ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to initialize : %s", __vc_widget_get_error_code(ret));
+
+               vc_widget_client_set_error(g_vc_w, VC_ERROR_TIMED_OUT);
+               ecore_timer_add(0, __vc_widget_notify_error, g_vc_w);
+
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, "  ");
+               return EINA_FALSE;
+       } 
+
+       vc_widget_client_set_state(g_vc_w, VC_STATE_READY);
+       ecore_timer_add(0, __vc_widget_notify_state_changed, g_vc_w);
+
+       g_w_connect_timer = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, "  ");
+
+       return EINA_FALSE;
+}
+
+int vc_widget_prepare()
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Prepare");
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       g_w_is_daemon_started = false;
+
+       g_w_connect_timer = ecore_timer_add(0, __vc_widget_connect_daemon, NULL);
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_widget_unprepare()
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Unprepare");
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       __vc_widget_internal_unprepare();
+
+       vc_widget_client_set_state(g_vc_w, VC_STATE_INITIALIZED);
+       ecore_timer_add(0, __vc_widget_notify_state_changed, g_vc_w);
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_widget_foreach_supported_languages(vc_supported_language_cb callback, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Foreach Supported Language");
+
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Input parameter is NULL");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       ret = vc_config_mgr_get_language_list(callback, user_data);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get languages : %s", __vc_widget_get_error_code(ret));
+       }
+       
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_widget_get_current_language(char** language)
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Get Current Language");
+
+       if (NULL == language) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Input parameter is NULL");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       ret = vc_config_mgr_get_default_language(language);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get current languages : %s", __vc_widget_get_error_code(ret));
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return ret;
+}
+
+int vc_widget_get_state(vc_state_e* state)
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Get State");
+
+       if (NULL == state) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e temp;
+       if (0 != vc_widget_client_get_state(g_vc_w, &temp)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       *state = temp;
+
+       switch(*state) {
+               case VC_STATE_NONE:             SLOG(LOG_DEBUG, TAG_VCW, "Current state is 'None'");            break;
+               case VC_STATE_INITIALIZED:      SLOG(LOG_DEBUG, TAG_VCW, "Current state is 'Created'");         break;
+               case VC_STATE_READY:            SLOG(LOG_DEBUG, TAG_VCW, "Current state is 'Ready'");           break;
+               default:                        SLOG(LOG_ERROR, TAG_VCW, "Invalid state");                      break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_widget_get_service_state(vc_service_state_e* state)
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Get Service State");
+
+       if (NULL == state) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_state_e temp;
+       if (0 != vc_widget_client_get_state(g_vc_w, &temp)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       if (temp != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* get service state */
+       vc_service_state_e service_state;
+       if (0 != vc_widget_client_get_service_state(g_vc_w, &service_state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get service state");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       *state = service_state;
+
+       switch(*state) {
+       case VC_SERVICE_STATE_NONE:             SLOG(LOG_DEBUG, TAG_VCW, "Current service state is 'None'");            break;
+       case VC_SERVICE_STATE_READY:            SLOG(LOG_DEBUG, TAG_VCW, "Current service state is 'Ready'");           break;
+       case VC_SERVICE_STATE_RECORDING:        SLOG(LOG_DEBUG, TAG_VCW, "Current service state is 'Recording'");       break;
+       case VC_SERVICE_STATE_PROCESSING:       SLOG(LOG_DEBUG, TAG_VCW, "Current service state is 'Processing'");      break;
+       default:                                SLOG(LOG_ERROR, TAG_VCW, "Invalid service state");                      break;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_widget_set_foreground(bool value)
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Set foreground state");
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not valid");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "Set foreground : pid(%d) value(%s)", getpid(), value ? "true" : "false");
+       int ret = vc_config_mgr_set_foreground(getpid(), value);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to set foreground : %s", __vc_widget_get_error_code(ret));
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+#if 0
+int vc_widget_is_format_supported(vc_cmd_format_e format, bool* support)
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Is command type supported");
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not valid");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check support */
+       bool non_fixed_support = false;
+       if (0 != vc_config_mgr_get_nonfixed_support(&non_fixed_support)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get nonfixed support info");
+       }
+
+       switch (format) {
+       case VC_CMD_FORMAT_FIXED:                       *support = true;                break;
+       case VC_CMD_FORMAT_FIXED_AND_EXTRA:     *support = non_fixed_support;   break;
+       case VC_CMD_FORMAT_EXTRA_AND_FIXED:     *support = non_fixed_support;   break;
+       default:                                        *support = false;               break;
+       }
+
+       SLOG(LOG_ERROR, TAG_VCW, "[DEBUG] Format(%d) support(%s)", format, *support ? "true" : "false");
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+#endif
+/**
+* @brief Starts recognition.
+*
+* @param[in] stop_by_silence Silence detection option
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The state should be #VC_STATE_READY.
+* @post It will invoke vc_state_changed_cb(), if you register a callback with vc_state_changed_cb(). \n
+* If this function succeeds, the state will be #VC_STATE_RECORDING.
+*
+* @see vc_widget_stop()
+* @see vc_widget_cancel()
+* @see vc_state_changed_cb()
+*/
+#if 0
+int vc_widget_start(bool stop_by_silence, vc_cmd_group_h vc_group)
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Start");
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_widget_client_get_service_state(g_vc_w, &service_state);
+       if (service_state != VC_SERVICE_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: service state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = vc_widget_client_set_command_group(g_vc_w, vc_group);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to set command to client : %d", ret);
+               return ret;
+       }
+
+       GSList* list = NULL;
+       if (0 > vc_cmd_group_get_cmd_list(vc_group, &list)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to get command list : %d", ret);
+               return ret;
+       }
+
+       ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_GROUP_TYPE_WIDGET, list);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to save command group : %s", __vc_widget_get_error_code(ret));
+       } else {
+               int count = 0;
+               do {
+                       ret = vc_widget_dbus_request_start(g_vc_w->handle, stop_by_silence);
+                       if (0 != ret) {
+                               if (VC_ERROR_TIMED_OUT != ret) {
+                                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request start : %s", __vc_widget_get_error_code(ret));
+                                       break;
+                               } else {
+                                       SLOG(LOG_WARN, TAG_VCW, "[WARNING] retry request start : %s", __vc_widget_get_error_code(ret));
+                                       usleep(10000);
+                                       count++;
+                                       if (VC_RETRY_COUNT == count) {
+                                               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request");
+                                               break;
+                                       }
+                               }
+                       }
+               } while(0 != ret);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "=====");
+       SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       return VC_ERROR_NONE;
+}
+#endif
+
+/**
+* @brief Stop interrupt.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The state should be #VC_STATE_RECORDING.
+* @post It will invoke vc_state_changed_cb(), if you register a callback with vc_state_changed_cb(). \n
+* If this function succeeds, the state will be #VC_STATE_READY and vc_widget_result_cb() is called.
+*
+* @see vc_widget_start()
+* @see vc_widget_cancel()
+* @see vc_state_changed_cb()
+*/
+#if 0
+int vc_widget_stop()
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Stop");
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_widget_client_get_service_state(g_vc_w, &service_state);
+       if (service_state != VC_SERVICE_STATE_RECORDING) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: service state is not 'RECORDING'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = vc_widget_client_set_command_group(g_vc_w, NULL);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to set command to client : %d", ret);
+               return ret;
+       }
+
+       ret = vc_cmd_parser_delete_file(getpid(), VC_COMMAND_GROUP_TYPE_WIDGET);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to delete command group : %s", __vc_widget_get_error_code(ret));
+       }
+
+       int count = 0;
+       do {
+               ret = vc_widget_dbus_request_stop(g_vc_w->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request stop : %s", __vc_widget_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCW, "[WARNING] retry request stop : %s", __vc_widget_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       } while(0 != ret);
+
+       return 0;
+}
+#endif
+
+#if 0
+int vc_widget_cancel()
+{
+       SLOG(LOG_DEBUG, TAG_VCW, "===== [Widget] Cancel Recognition");
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_READY) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'READY'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* Check service state */
+       vc_service_state_e service_state = -1;
+       vc_widget_client_get_service_state(g_vc_w, &service_state);
+       if (service_state != VC_SERVICE_STATE_RECORDING && service_state != VC_SERVICE_STATE_PROCESSING) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: service state is not 'RECORDING' or 'PROCESSING'");
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       int ret = vc_widget_client_set_command_group(g_vc_w, NULL);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to set command to client : %d", ret);
+               return ret;
+       }
+
+       ret = vc_cmd_parser_delete_file(getpid(), VC_COMMAND_TYPE_WIDGET);
+       if (0 != ret) {
+               ret = vc_config_convert_error_code((vc_config_error_e)ret);
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to delete command group : %s", __vc_widget_get_error_code(ret));
+       }
+
+       int count = 0;
+       do {
+               ret = vc_widget_dbus_request_cancel(g_vc_w->handle);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request cancel : %s", __vc_widget_get_error_code(ret));
+                               break;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCW, "[WARNING] retry request cancel : %s", __vc_widget_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request");
+                                       break;
+                               }
+                       }
+               }
+       } while(0 != ret);
+
+       return 0;
+}
+#endif
+
+static Eina_Bool __vc_widget_notify_error(void *data)
+{
+       vc_error_cb callback = NULL;
+       void* user_data;
+       int reason;
+
+       vc_widget_client_get_error_cb(g_vc_w, &callback, &user_data);
+       vc_widget_client_get_error(g_vc_w, &reason);
+
+       if (NULL != callback) {
+               vc_widget_client_use_callback(g_vc_w);
+               callback(reason, user_data);
+               vc_widget_client_not_use_callback(g_vc_w);
+               SLOG(LOG_DEBUG, TAG_VCW, "[Error] callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCW, "[WARNING] Error callback is null");
+       }  
+
+       return EINA_FALSE;
+}
+
+int __vc_widget_cb_error(int pid, int reason)
+{
+       if (0 != vc_widget_client_get_handle(pid, &g_vc_w)) {
+               SLOG(LOG_ERROR, TAG_VCW, "Handle is not valid");
+               return -1;
+       }
+
+       vc_widget_client_set_error(g_vc_w, reason);
+       ecore_timer_add(0, __vc_widget_notify_error, g_vc_w);
+
+       return 0;
+}
+
+static Eina_Bool __vc_widget_start_recording(void *data)
+{
+       if (NULL != g_w_start_timer) {
+               ecore_timer_del(g_w_start_timer);
+               g_w_start_timer = NULL;
+       }
+
+       vc_widget_send_current_command_list_cb send_command_list_cb = NULL;
+       void* send_command_user_data = NULL;
+       vc_cmd_list_h vc_cmd_list = NULL;
+
+       vc_widget_client_get_send_command_list_cb(g_vc_w, &send_command_list_cb, &send_command_user_data);
+
+       if (NULL != send_command_list_cb) {
+               vc_widget_client_use_callback(g_vc_w);
+               send_command_list_cb(&vc_cmd_list, send_command_user_data);
+               vc_widget_client_not_use_callback(g_vc_w);
+               SLOG(LOG_DEBUG, TAG_VCW, "client result callback called");
+
+       } else {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] User show tooltip callback is NULL");
+       }
+
+       bool widget_command = false;
+       int ret;
+
+       if (NULL != vc_cmd_list) {
+               vc_cmd_list_s* list = NULL;
+               list = (vc_cmd_list_s*)vc_cmd_list;
+
+               ret = vc_cmd_parser_save_file(getpid(), VC_COMMAND_TYPE_WIDGET, list->list);
+               if (0 == ret) {
+                       /* widget command is valid */
+                       widget_command = true;
+                       SLOG(LOG_DEBUG, TAG_VCW, "Widget command is valid");
+               } else {
+                       ret = VC_ERROR_OPERATION_FAILED;
+                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to save command group : %s", __vc_widget_get_error_code(ret));
+               }
+       }
+
+       ret = -1;
+       int count = 0;
+       while (0 != ret) {
+               ret = vc_widget_dbus_request_start_recording(g_vc_w->handle, widget_command);
+               if (0 != ret) {
+                       if (VC_ERROR_TIMED_OUT != ret) {
+                               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request start recording to daemon : %s", __vc_widget_get_error_code(ret));
+                               return EINA_FALSE;
+                       } else {
+                               SLOG(LOG_WARN, TAG_VCW, "[WARNING] retry start recording : %s", __vc_widget_get_error_code(ret));
+                               usleep(10000);
+                               count++;
+                               if (VC_RETRY_COUNT == count) {
+                                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to request");
+                                       return EINA_FALSE;
+                               }
+                       }
+               }
+       }
+
+       return EINA_FALSE;
+}
+
+static Eina_Bool __vc_widget_notify_tooltip(void *data)
+{
+       if (NULL != g_w_tooltip_timer) {
+               ecore_timer_del(g_w_tooltip_timer);
+               g_w_tooltip_timer = NULL;
+       }
+
+       vc_widget_show_tooltip_cb callback;
+       void* user_data;
+       bool show;
+
+       vc_widget_client_get_show_tooltip_cb(g_vc_w, &callback, &user_data);
+       vc_widget_client_get_show_tooltip(g_vc_w, &show);
+
+       if (NULL != callback) {
+               vc_widget_client_use_callback(g_vc_w);
+               callback(show, user_data);
+               vc_widget_client_not_use_callback(g_vc_w);
+               SLOG(LOG_DEBUG, TAG_VCW, "client result callback called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCW, "[WARNING] Show tooltip callback is NULL");
+       }
+
+       if (true == show) {
+               g_w_start_timer = ecore_timer_add(0, __vc_widget_start_recording, NULL);
+       }
+
+       return EINA_FALSE;
+}
+
+void __vc_widget_cb_show_tooltip(int pid, bool show)
+{
+       if (0 != vc_widget_client_get_handle(pid, &g_vc_w)) {
+               SLOG(LOG_ERROR, TAG_VCW, "Handle is not valid");
+               return;
+       }
+
+       vc_widget_client_set_show_tooltip(g_vc_w, show);
+       g_w_tooltip_timer = ecore_timer_add(0, __vc_widget_notify_tooltip, NULL);
+
+       return;
+}
+
+static Eina_Bool __vc_widget_notify_result(void *data)
+{
+       char* temp_text;
+       int event;
+       vc_cmd_list_h vc_cmd_list = NULL;
+
+       vc_result_cb callback = NULL;
+       void* user_data = NULL;
+
+       vc_widget_client_get_result_cb(g_vc_w, &callback, &user_data);
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Client result callback is NULL");
+               return EINA_FALSE;
+       }
+
+       if (0 != vc_cmd_list_create(&vc_cmd_list)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to create command list");
+               return EINA_FALSE;
+       }
+
+       vc_info_parser_get_result(&temp_text, &event, NULL, getpid(), vc_cmd_list, false);
+
+       SLOG(LOG_DEBUG, TAG_VCW, "Result info : result text(%s) event(%d)", temp_text, event);
+
+       vc_cmd_print_list(vc_cmd_list);
+
+       vc_widget_client_use_callback(g_vc_w);
+       callback(event, vc_cmd_list, temp_text, user_data);
+       vc_widget_client_not_use_callback(g_vc_w);
+
+       SLOG(LOG_DEBUG, TAG_VCW, "Widget result callback called");
+
+       /* Release result */
+       if (NULL != temp_text)  free(temp_text);
+
+       vc_cmd_list_destroy(vc_cmd_list, true);
+
+       return EINA_FALSE;
+}
+
+void __vc_widget_cb_result()
+{
+       ecore_timer_add(0, __vc_widget_notify_result, NULL);
+
+       return;
+}
+
+static Eina_Bool __vc_widget_notify_state_changed(void *data)
+{
+       vc_state_changed_cb changed_callback = NULL;
+       void* user_data;
+
+       vc_widget_client_get_state_changed_cb(g_vc_w, &changed_callback, &user_data);
+
+       vc_state_e current_state;
+       vc_state_e before_state;
+
+       vc_widget_client_get_before_state(g_vc_w, &current_state, &before_state);
+
+       if (NULL != changed_callback) {
+               vc_widget_client_use_callback(g_vc_w);
+               changed_callback(before_state, current_state, user_data);
+               vc_widget_client_not_use_callback(g_vc_w);
+               SLOG(LOG_DEBUG, TAG_VCW, "State changed callback is called");
+       } else {
+               SLOG(LOG_WARN, TAG_VCW, "[WARNING] State changed callback is null");
+       }
+
+       return EINA_FALSE;
+}
+
+int vc_widget_set_result_cb(vc_result_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_result_cb(g_vc_w, callback, user_data);
+       
+       return 0;
+}
+
+int vc_widget_unset_result_cb()
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_result_cb(g_vc_w, NULL, NULL);
+
+       return 0;
+}
+
+int vc_widget_set_show_tooltip_cb(vc_widget_show_tooltip_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_show_tooltip_cb(g_vc_w, callback, user_data);
+
+       return 0;
+}
+
+int vc_widget_unset_show_tooltip_cb()
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_show_tooltip_cb(g_vc_w, NULL, NULL);
+
+       return 0;
+}
+
+int vc_widget_set_send_current_command_list_cb(vc_widget_send_current_command_list_cb callback, void* user_data)
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_send_command_list_cb(g_vc_w, callback, user_data);
+
+       return 0;
+}
+
+int vc_widget_unsset_send_current_command_list_cb()
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_send_command_list_cb(g_vc_w, NULL, NULL);
+
+       return 0;
+}
+
+int vc_widget_set_service_state_changed_cb(vc_service_state_changed_cb callback, void* user_data)
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_service_state_changed_cb(g_vc_w, callback, user_data);
+
+       return 0;
+}
+
+int vc_widget_unset_service_state_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_service_state_changed_cb(g_vc_w, NULL, NULL);
+
+       return 0;
+}
+
+int vc_widget_set_state_changed_cb(vc_state_changed_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_state_changed_cb(g_vc_w, callback, user_data);
+
+       return 0;
+}
+
+int vc_widget_unset_state_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_state_changed_cb(g_vc_w, NULL, NULL);
+
+       return 0;
+}
+
+int vc_widget_set_current_language_changed_cb(vc_current_language_changed_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_current_lang_changed_cb(g_vc_w, callback, user_data);
+
+       return 0;
+}
+
+int vc_widget_unset_current_language_changed_cb()
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_current_lang_changed_cb(g_vc_w, NULL, NULL);
+
+       return 0;
+}
+
+int vc_widget_set_error_cb(vc_error_cb callback, void* user_data)
+{
+       if (NULL == callback)
+               return VC_ERROR_INVALID_PARAMETER;
+
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_error_cb(g_vc_w, callback,  user_data);
+
+       return 0;
+}
+
+int vc_widget_unset_error_cb()
+{
+       vc_state_e state;
+       if (0 != vc_widget_client_get_state(g_vc_w, &state)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] A handle is not available");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       /* check state */
+       if (state != VC_STATE_INITIALIZED) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Invalid State: Current state is not 'Initialized'");
+               return VC_ERROR_INVALID_STATE;
+       }
+
+       vc_widget_client_set_error_cb(g_vc_w, NULL, NULL);
+
+       return 0;
+}
+
diff --git a/client/vc_widget_client.c b/client/vc_widget_client.c
new file mode 100644 (file)
index 0000000..a48d3d3
--- /dev/null
@@ -0,0 +1,628 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_main.h"
+#include "vc_widget_client.h"
+#include "voice_control_command.h"
+#include "voice_control_common.h"
+
+
+typedef struct {
+       /* base info */
+       vc_h    vc;
+       int     pid;
+       int     uid;            /*<< unique id = pid + handle */
+       int     xid;            /*<< main X window id */
+
+       vc_result_cb                    result_cb;
+       void*                           result_user_data;
+       vc_error_cb                     error_cb;
+       void*                           error_user_data;
+       vc_service_state_changed_cb     service_state_changed_cb;
+       void*                           service_state_changed_user_data;
+       vc_state_changed_cb             state_changed_cb;
+       void*                           state_changed_user_data;
+       vc_widget_show_tooltip_cb       show_tooltip_cb;
+       void*                           show_tooltip_user_data;
+       vc_current_language_changed_cb  current_lang_changed_cb;
+       void*                           current_lang_changed_user_data;
+
+       vc_widget_send_current_command_list_cb  send_command_list_cb;
+       void*                                   send_command_list_user_data;
+
+       /* tooltip */
+       bool                    show_tooltip;
+
+       /* service state */
+       vc_service_state_e      service_state;
+
+       /* state */
+       vc_state_e      before_state;
+       vc_state_e      current_state;
+
+       /* mutex */
+       int     cb_ref_count;
+
+       /* error data */
+       int     reason;
+}vc_widget_s;
+
+
+/* widget list */
+static GSList *g_widget_list = NULL;
+
+static vc_widget_s* __widget_get(vc_h vc)
+{
+       if (vc == NULL) {
+               SLOG(LOG_WARN, TAG_VCW, "[WARNING] Input parameter is NULL");
+               return NULL;
+       }
+
+       vc_widget_s *data = NULL;
+
+       int count = g_slist_length(g_widget_list);
+       int i;
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_widget_list, i);
+
+               if (NULL != data) {
+                       if (vc->handle == data->vc->handle) {
+                               return data;
+                       }
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "[DEBUG] Fail to get widget by vc");
+
+       return NULL;
+}
+
+int vc_widget_client_create(vc_h* vc)
+{
+       vc_widget_s *widget = NULL;
+
+       widget = (vc_widget_s*)calloc(1, sizeof(vc_widget_s));
+       if (NULL == widget) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to allocate memory");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       vc_h temp = (vc_h)calloc(1, sizeof(struct vc_s));
+       if (NULL == temp) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to allocate memory");
+               free(widget);
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       temp->handle = getpid(); 
+
+       /* initialize widget data */
+       widget->vc = temp;
+       widget->pid = getpid(); 
+       widget->uid = temp->handle;
+       widget->xid = -1;
+
+       widget->result_cb = NULL;
+       widget->result_user_data = NULL;
+       widget->service_state_changed_cb = NULL;
+       widget->service_state_changed_user_data = NULL;
+       widget->state_changed_cb = NULL;
+       widget->state_changed_user_data = NULL;
+       widget->show_tooltip_cb = NULL;
+       widget->show_tooltip_user_data = NULL;
+       widget->error_cb = NULL;
+       widget->error_user_data = NULL;
+
+       widget->before_state = VC_STATE_INITIALIZED; 
+       widget->current_state = VC_STATE_INITIALIZED; 
+
+       widget->cb_ref_count = 0;
+
+       g_widget_list = g_slist_append(g_widget_list, widget);
+
+       *vc = temp;
+
+       return 0;
+}
+
+int vc_widget_client_destroy(vc_h vc)
+{
+       if (vc == NULL) {
+               SLOG(LOG_ERROR, TAG_VCW, "Input parameter is NULL");
+               return 0;
+       }       
+
+       vc_widget_s *data = NULL;
+
+       int count = g_slist_length(g_widget_list);
+       int i;
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_widget_list, i);
+
+               if (NULL != data) {
+                       if (vc->handle == data->vc->handle) {
+                               g_widget_list =  g_slist_remove(g_widget_list, data);
+
+                               while (0 != data->cb_ref_count)
+                               {
+                                       /* wait for release callback function */
+                               }
+                               free(data);
+                               free(vc);
+
+                               return 0;
+                       }
+               }
+       }
+
+       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] widget Not found");
+
+       return -1;
+}
+
+bool vc_widget_client_is_valid(vc_h vc)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) {
+               SLOG(LOG_DEBUG, TAG_VCW, "[DEBUG] vc is not valid");
+               return false;
+       }
+
+       return true;
+}
+
+bool vc_widget_client_is_valid_by_uid(int uid)
+{
+       vc_widget_s *data = NULL;
+
+       int count = g_slist_length(g_widget_list);
+       int i;
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_widget_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) 
+                               return true;
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCW, "[DEBUG] Fail to get widget by vc");
+
+       return false;
+}
+
+int vc_widget_client_get_handle(int uid, vc_h* vc)
+{
+       vc_widget_s *data = NULL;
+
+       int count = g_slist_length(g_widget_list);
+       int i;
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_widget_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) {
+                               *vc = data->vc;
+                               return 0;
+                       }
+               }
+       }
+       
+       return -1;
+}
+
+/* set/get callback function */
+int vc_widget_client_set_result_cb(vc_h vc, vc_result_cb callback, void* user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->result_cb = callback;
+       widget->result_user_data = user_data;
+
+       return 0;
+}
+
+int vc_widget_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = widget->result_cb;
+       *user_data = widget->result_user_data;
+
+       return 0;       
+}
+
+int vc_widget_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->service_state_changed_cb = callback;
+       widget->service_state_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_widget_client_get_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb* callback, void** user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = widget->service_state_changed_cb;
+       *user_data = widget->service_state_changed_user_data;
+
+       return 0;
+}
+
+int vc_widget_client_set_state_changed_cb(vc_h vc, vc_state_changed_cb callback, void* user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->state_changed_cb = callback;
+       widget->state_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_widget_client_get_state_changed_cb(vc_h vc, vc_state_changed_cb* callback, void** user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = widget->state_changed_cb;
+       *user_data = widget->state_changed_user_data;
+
+       return 0;
+}
+
+int vc_widget_client_set_show_tooltip_cb(vc_h vc, vc_widget_show_tooltip_cb callback, void* user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->show_tooltip_cb = callback;
+       widget->show_tooltip_user_data = user_data;
+
+       return 0;
+}
+
+int vc_widget_client_get_show_tooltip_cb(vc_h vc, vc_widget_show_tooltip_cb* callback, void** user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = widget->show_tooltip_cb;
+       *user_data = widget->show_tooltip_user_data;
+
+       return 0;
+}
+
+int vc_widget_client_set_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb callback, void* user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->current_lang_changed_cb = callback;
+       widget->current_lang_changed_user_data = user_data;
+
+       return 0;
+}
+
+int vc_widget_client_get_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb* callback, void** user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = widget->current_lang_changed_cb;
+       *user_data = widget->current_lang_changed_user_data;
+
+       return 0;
+}
+
+int vc_widget_client_set_error_cb(vc_h vc, vc_error_cb callback, void* user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->error_cb = callback;
+       widget->error_user_data = user_data;
+
+       return 0;
+}
+
+int vc_widget_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = widget->error_cb;
+       *user_data = widget->error_user_data;
+
+       return 0;
+}
+
+int vc_widget_client_set_send_command_list_cb(vc_h vc, vc_widget_send_current_command_list_cb callback, void* user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->send_command_list_cb = callback;
+       widget->send_command_list_user_data = user_data;
+
+       return 0;
+}
+
+int vc_widget_client_get_send_command_list_cb(vc_h vc, vc_widget_send_current_command_list_cb* callback, void** user_data)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *callback = widget->send_command_list_cb;
+       *user_data = widget->send_command_list_user_data;
+
+       return 0;
+}
+
+
+/* set/get option */
+int vc_widget_client_set_service_state(vc_h vc, vc_service_state_e state)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->service_state = state;
+
+       return 0;
+}
+
+int vc_widget_client_get_service_state(vc_h vc, vc_service_state_e* state)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *state = widget->service_state;
+
+       return 0;
+}
+
+
+int vc_widget_client_set_state(vc_h vc, vc_state_e state)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->before_state = widget->current_state;
+       widget->current_state = state;
+
+       return 0;
+}
+
+int vc_widget_client_get_state(vc_h vc, vc_state_e* state)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *state = widget->current_state;
+
+       return 0;
+}
+
+int vc_widget_client_get_state_by_uid(int uid, vc_state_e* state)
+{
+       vc_widget_s *data = NULL;
+
+       int count = g_slist_length(g_widget_list);
+       int i;
+
+       for (i = 0;i < count;i++) {
+               data = g_slist_nth_data(g_widget_list, i);
+
+               if (NULL != data) {
+                       if (uid == data->vc->handle) {
+                               *state = data->current_state;
+                               return 0;
+                       }
+               }
+       }
+
+       return -1;
+}
+
+int vc_widget_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_state)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *before_state = widget->before_state;
+       *state = widget->current_state;
+
+       return 0;
+}
+
+int vc_widget_client_set_xid(vc_h vc, int xid)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->xid = xid;
+
+       return 0;
+}
+
+int vc_widget_cilent_get_xid(vc_h vc, int* xid)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *xid = widget->xid;
+
+       return 0;
+}
+
+int vc_widget_client_set_error(vc_h vc, int reason)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->reason = reason;
+
+       return 0;
+}
+
+int vc_widget_client_get_error(vc_h vc, int* reason)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *reason = widget->reason;
+
+       return 0;
+}
+
+int vc_widget_client_set_show_tooltip(vc_h vc, bool show)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->show_tooltip = show;
+       
+       return 0;
+}
+
+int vc_widget_client_get_show_tooltip(vc_h vc, bool* show)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       *show = widget->show_tooltip;
+       
+       return 0;
+}
+
+int vc_widget_client_get_count()
+{
+       return g_slist_length(g_widget_list);
+}
+
+int vc_widget_client_use_callback(vc_h vc)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->cb_ref_count++;
+       return 0;
+}
+
+int vc_widget_client_not_use_callback(vc_h vc)
+{
+       vc_widget_s* widget = __widget_get(vc);
+
+       /* check handle */
+       if (NULL == widget) 
+               return VC_ERROR_INVALID_PARAMETER;
+
+       widget->cb_ref_count--;
+       return 0;
+}
+
diff --git a/client/vc_widget_client.h b/client/vc_widget_client.h
new file mode 100644 (file)
index 0000000..828038c
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VC_WIDGET_CLIENT_H_
+#define __VC_WIDGET_CLIENT_H_
+
+#include "voice_control_common.h"
+#include "voice_control_widget.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* 
+* Common function 
+*/
+int vc_widget_client_create(vc_h* vc);
+
+int vc_widget_client_destroy(vc_h vc);
+
+bool vc_widget_client_is_valid(vc_h vc);
+
+bool vc_widget_client_is_valid_by_uid(int uid);
+
+int vc_widget_client_get_handle(int uid, vc_h* vc);
+
+/* 
+* set/get callback function 
+*/
+int vc_widget_client_set_result_cb(vc_h vc, vc_result_cb callback, void* user_data);
+
+int vc_widget_client_get_result_cb(vc_h vc, vc_result_cb* callback, void** user_data);
+
+int vc_widget_client_set_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb callback, void* user_data);
+
+int vc_widget_client_get_service_state_changed_cb(vc_h vc, vc_service_state_changed_cb* callback, void** user_data);
+
+int vc_widget_client_set_state_changed_cb(vc_h vc, vc_state_changed_cb callback, void* user_data);
+
+int vc_widget_client_get_state_changed_cb(vc_h vc, vc_state_changed_cb* callback, void** user_data);
+
+int vc_widget_client_set_show_tooltip_cb(vc_h vc, vc_widget_show_tooltip_cb callback, void* user_data);
+
+int vc_widget_client_get_show_tooltip_cb(vc_h vc, vc_widget_show_tooltip_cb* callback, void** user_data);
+
+int vc_widget_client_set_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb callback, void* user_data);
+
+int vc_widget_client_get_current_lang_changed_cb(vc_h vc, vc_current_language_changed_cb* callback, void** user_data);
+
+int vc_widget_client_set_error_cb(vc_h vc, vc_error_cb callback, void* user_data);
+
+int vc_widget_client_get_error_cb(vc_h vc, vc_error_cb* callback, void** user_data);
+
+int vc_widget_client_set_send_command_list_cb(vc_h vc, vc_widget_send_current_command_list_cb callback, void* user_data);
+
+int vc_widget_client_get_send_command_list_cb(vc_h vc, vc_widget_send_current_command_list_cb* callback, void** user_data);
+
+
+
+/* 
+* set/get option 
+*/
+int vc_widget_client_set_service_state(vc_h vc, vc_service_state_e state);
+
+int vc_widget_client_get_service_state(vc_h vc, vc_service_state_e* state);
+
+int vc_widget_client_set_state(vc_h vc, vc_state_e state);
+
+int vc_widget_client_get_state(vc_h vc, vc_state_e* state);
+
+int vc_widget_client_get_state_by_uid(int uid, vc_state_e* state);
+
+int vc_widget_client_get_before_state(vc_h vc, vc_state_e* state, vc_state_e* before_state);
+
+int vc_widget_client_set_xid(vc_h vc, int xid);
+
+int vc_widget_cilent_get_xid(vc_h vc, int* xid);
+
+int vc_widget_client_set_error(vc_h vc, int reason);
+
+int vc_widget_client_get_error(vc_h vc, int* reason);
+
+int vc_widget_client_set_show_tooltip(vc_h vc, bool show);
+
+int vc_widget_client_get_show_tooltip(vc_h vc, bool* show);
+
+
+/* utils */
+int vc_widget_client_get_count();
+
+int vc_widget_client_use_callback(vc_h vc);
+
+int vc_widget_client_not_use_callback(vc_h vc);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_WIDGET_CLIENT_H_ */
diff --git a/client/vc_widget_dbus.c b/client/vc_widget_dbus.c
new file mode 100644 (file)
index 0000000..0b1a11d
--- /dev/null
@@ -0,0 +1,754 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_main.h"
+#include "vc_widget_client.h"
+#include "vc_widget_dbus.h"
+
+
+static int g_w_waiting_time = 3000;
+
+static Ecore_Fd_Handler* g_w_fd_handler = NULL;
+
+static DBusConnection* g_w_conn = NULL;
+
+
+extern int __vc_widget_cb_error(int pid, int reason);
+
+extern void __vc_widget_cb_show_tooltip(int pid, bool show);
+
+extern void __vc_widget_cb_result();
+
+
+static Eina_Bool widget_listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
+{
+       DBusConnection* conn = (DBusConnection*)data;
+       DBusMessage* msg = NULL;
+       DBusMessage *reply = NULL;
+
+       if (NULL == conn)
+               return ECORE_CALLBACK_RENEW;
+
+       dbus_connection_read_write_dispatch(conn, 50);
+
+       msg = dbus_connection_pop_message(conn);
+
+       /* loop again if we haven't read a message */
+       if (NULL == msg) { 
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       char if_name[64];
+       snprintf(if_name, 64, "%s%d", VC_WIDGET_SERVICE_INTERFACE, getpid());
+
+       if (dbus_message_is_method_call(msg, if_name, VCD_WIDGET_METHOD_HELLO)) {
+               SLOG(LOG_DEBUG, TAG_VCW, "===== Get widget hello");
+               int pid = 0;
+               int response = -1;
+
+               dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+               
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+                       dbus_error_free(&err);
+               }
+
+               if (pid > 0) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget get hello : pid(%d) ", pid);
+                       response = 1;
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget get hello : invalid pid ");
+               }
+
+               reply = dbus_message_new_method_return(msg);
+               
+               if (NULL != reply) {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &response, DBUS_TYPE_INVALID);
+
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget get hello : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget get hello : result(%d)", response);
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget get hello : fail to create reply message");
+               }
+               
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+       } /* VCD_WIDGET_METHOD_HELLO */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_WIDGET_METHOD_SHOW_TOOLTIP)) {
+               SLOG(LOG_DEBUG, TAG_VCW, "===== Show / Hide tooltip");
+               int pid = 0;
+               int show = 0;
+
+               dbus_message_get_args(msg, &err, 
+                       DBUS_TYPE_INT32, &pid, 
+                       DBUS_TYPE_INT32, &show,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+                       dbus_error_free(&err);
+               }
+
+               if (pid > 0) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget show tooltip : pid(%d), show(%d)", pid, show);
+
+                       __vc_widget_cb_show_tooltip(pid, (bool)show);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget show tooltip : invalid pid");
+               }
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget show tooltip : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget show tooltip");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget show tooltip : fail to create reply message");
+               }
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+       } /* VCD_WIDGET_METHOD_SHOW_TOOLTIP */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_WIDGET_METHOD_RESULT)) {
+               SLOG(LOG_DEBUG, TAG_VCW, "===== Get widget result");
+
+               __vc_widget_cb_result();
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget get result : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget get result");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget get result : fail to create reply message");
+               
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+
+       } /* VCD_WIDGET_METHOD_RESULT */
+
+       else if (dbus_message_is_method_call(msg, if_name, VCD_WIDGET_METHOD_ERROR)) {
+               SLOG(LOG_DEBUG, TAG_VCW, "===== Get widget error");
+               int pid;
+               int reason;
+               char* err_msg;
+
+               dbus_message_get_args(msg, &err,
+                       DBUS_TYPE_INT32, &pid,
+                       DBUS_TYPE_INT32, &reason,
+                       DBUS_TYPE_STRING, &err_msg,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget get error message : Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget get error message : pid(%d), reason(%d), msg(%s)", pid, reason, err_msg);
+                       __vc_widget_cb_error(pid, reason);
+               }
+
+               /*
+               reply = dbus_message_new_method_return(msg);
+
+               if (NULL != reply) {
+                       if (!dbus_connection_send(conn, reply, NULL))
+                               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget error message : fail to send reply");
+                       else 
+                               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget error message");
+
+                       dbus_connection_flush(conn);
+                       dbus_message_unref(reply); 
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget error message : fail to create reply message");
+               }
+               */
+
+               SLOG(LOG_DEBUG, TAG_VCW, "=====");
+               SLOG(LOG_DEBUG, TAG_VCW, " ");
+       } /* VCD_WIDGET_METHOD_ERROR */
+
+       /* free the message */
+       dbus_message_unref(msg);
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+int vc_widget_dbus_open_connection()
+{
+       if (NULL != g_w_conn) {
+               SLOG(LOG_WARN, TAG_VCW, "Already existed connection ");
+               return 0;
+       }
+
+       DBusError err;
+       int ret;
+
+       /* initialise the error value */
+       dbus_error_init(&err);
+
+       /* connect to the DBUS system bus, and check for errors */
+       g_w_conn = dbus_bus_get_private(DBUS_BUS_SYSTEM, &err);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCW, "Dbus Connection Error (%s)", err.message); 
+               dbus_error_free(&err); 
+       }
+
+       if (NULL == g_w_conn) {
+               SLOG(LOG_ERROR, TAG_VCW, "Fail to get dbus connection ");
+               return VC_ERROR_OPERATION_FAILED; 
+       }
+
+       int pid = getpid();
+
+       char service_name[64];
+       memset(service_name, '\0', 64);
+       snprintf(service_name, 64, "%s%d", VC_WIDGET_SERVICE_NAME, pid);
+
+       SLOG(LOG_DEBUG, TAG_VCW, "service name is %s", service_name);
+
+       /* register our name on the bus, and check for errors */
+       ret = dbus_bus_request_name(g_w_conn, service_name, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCW, "Name Error (%s)", err.message); 
+               dbus_error_free(&err); 
+       }
+
+       if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+               SLOG(LOG_ERROR, TAG_VCW, "fail dbus_bus_request_name()");
+               return -2;
+       }
+
+       if( NULL != g_w_fd_handler ) {
+               SLOG(LOG_WARN, TAG_VCW, "The handler already exists.");
+               return 0;
+       }
+
+       char rule[128];
+       snprintf(rule, 128, "type='signal',interface='%s%d'", VC_WIDGET_SERVICE_INTERFACE, pid);
+
+       /* add a rule for which messages we want to see */
+       dbus_bus_add_match(g_w_conn, rule, &err); 
+       dbus_connection_flush(g_w_conn);
+
+       if (dbus_error_is_set(&err)) 
+       { 
+               SLOG(LOG_ERROR, TAG_VCW, "Match Error (%s)", err.message);
+               dbus_error_free(&err);
+               return VC_ERROR_OPERATION_FAILED; 
+       }
+
+       int fd = 0;
+       if (1 != dbus_connection_get_unix_fd(g_w_conn, &fd)) {
+               SLOG(LOG_ERROR, TAG_VCW, "fail to get fd from dbus ");
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, "Get fd from dbus : %d", fd);
+       }
+
+       g_w_fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)widget_listener_event_callback, g_w_conn, NULL, NULL);
+
+       if (NULL == g_w_fd_handler) {
+               SLOG(LOG_ERROR, TAG_VCW, "fail to get fd handler from ecore ");
+               return VC_ERROR_OPERATION_FAILED;
+       }
+
+       return 0;
+}
+
+int vc_widget_dbus_close_connection()
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid = getpid();
+
+       char service_name[64];
+       memset(service_name, '\0', 64);
+       snprintf(service_name, 64, "%s%d", VC_WIDGET_SERVICE_NAME, pid);
+
+       dbus_bus_release_name (g_w_conn, service_name, &err);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       dbus_connection_close(g_w_conn);
+
+       g_w_fd_handler = NULL;
+       g_w_conn = NULL;
+
+       return 0;
+}
+
+int vc_widget_dbus_reconnect()
+{
+       bool connected = dbus_connection_get_is_connected(g_w_conn);
+       SECURE_SLOG(LOG_DEBUG, TAG_VCW, "[DBUS] %s", connected ? "Connected" : "Not connected");
+
+       if (false == connected) {
+               vc_widget_dbus_close_connection();
+
+               if (0 != vc_widget_dbus_open_connection()) {
+                       SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Fail to reconnect");
+                       return -1;
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCW, "[DBUS] Reconnect");
+       }
+       return 0;
+}
+
+int vc_widget_dbus_request_hello()
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_METHOD_HELLO);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCW, ">>>> Request vc hello : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } 
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg = NULL;
+       int result = 0;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_w_conn, msg, 500, &err);
+
+       if (dbus_error_is_set(&err)) {
+               dbus_error_free(&err);
+       }
+
+       dbus_message_unref(msg);
+
+       if (NULL != result_msg) {
+               dbus_message_unref(result_msg);
+               result = 0;
+       } else {
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+
+int vc_widget_dbus_request_initialize(int pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_WIDGET_METHOD_INITIALIZE);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget initialize : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget initialize : pid(%d)", pid);
+       }
+
+       dbus_message_append_args( msg, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_w_conn, msg, g_w_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err, 
+                       DBUS_TYPE_INT32, &result, 
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget initialize : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget initialize : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCW, "<<<< Result message is NULL ");
+               vc_widget_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_widget_dbus_request_finalize(int pid)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_WIDGET_METHOD_FINALIZE);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget finalize : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget finalize : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_w_conn, msg, g_w_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err, 
+                               DBUS_TYPE_INT32, &result,
+                               DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget finalize : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget finalize : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCW, "<<<< Result message is NULL ");
+               vc_widget_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_widget_dbus_request_start_recording(int pid, bool command)
+{
+       DBusMessage* msg;
+
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME, 
+               VC_SERVER_SERVICE_OBJECT_PATH, 
+               VC_SERVER_SERVICE_INTERFACE, 
+               VC_WIDGET_METHOD_START_RECORDING);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget start recording : Fail to make message"); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget start recording : pid(%d)", pid);
+       }
+
+       int temp = (int)command;
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INT32, &temp, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_w_conn, msg, g_w_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget start recording : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget start recording : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_ERROR, TAG_VCW, "<<<< Result message is NULL");
+               vc_widget_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_widget_dbus_request_start(int pid, int silence)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_WIDGET_METHOD_START);                
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget start : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget start : pid(%d), silence(%d)", pid, silence);
+       }
+
+       DBusMessageIter args;
+       dbus_message_iter_init_append(msg, &args);
+
+       /* Append result*/
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &(pid));
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &(silence));
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_w_conn, msg, g_w_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget start : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget start : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, "<<<< Result Message is NULL");
+               vc_widget_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_widget_dbus_request_stop(int pid)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  
+               VC_SERVER_SERVICE_INTERFACE,    
+               VC_WIDGET_METHOD_STOP);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget stop : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget stop : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_w_conn, msg, g_w_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget stop : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget stop : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, "<<<< Result Message is NULL");
+               vc_widget_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
+
+int vc_widget_dbus_request_cancel(int pid)
+{
+       DBusMessage* msg;
+
+       /* create a signal & check for errors */
+       msg = dbus_message_new_method_call(
+               VC_SERVER_SERVICE_NAME,
+               VC_SERVER_SERVICE_OBJECT_PATH,  /* object name of the signal */
+               VC_SERVER_SERVICE_INTERFACE,    /* interface name of the signal */
+               VC_WIDGET_METHOD_CANCEL);       /* name of the signal */
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCW, ">>>> vc widget cancel : Fail to make message "); 
+               return VC_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, ">>>> vc widget cancel : pid(%d)", pid);
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = VC_ERROR_OPERATION_FAILED;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_w_conn, msg, g_w_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCW, "[ERROR] Dbus Error (%s)", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err,
+                       DBUS_TYPE_INT32, &result,
+                       DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< Get arguments error (%s)", err.message);
+                       dbus_error_free(&err); 
+                       result = VC_ERROR_OPERATION_FAILED;
+               }
+               dbus_message_unref(result_msg);
+
+               if (0 == result) {
+                       SLOG(LOG_DEBUG, TAG_VCW, "<<<< vc widget cancel : result = %d", result);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCW, "<<<< vc widget cancel : result = %d", result);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCW, "<<<< Result Message is NULL");
+               vc_widget_dbus_reconnect();
+               result = VC_ERROR_TIMED_OUT;
+       }
+
+       return result;
+}
\ No newline at end of file
diff --git a/client/vc_widget_dbus.h b/client/vc_widget_dbus.h
new file mode 100644 (file)
index 0000000..65d0c56
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __VC_WIDGET_DBUS_H_
+#define __VC_WIDGET_DBUS_H_
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int vc_widget_dbus_open_connection();
+
+int vc_widget_dbus_close_connection();
+
+
+int vc_widget_dbus_request_hello();
+
+int vc_widget_dbus_request_initialize(int pid);
+
+int vc_widget_dbus_request_finalize(int pid);
+
+int vc_widget_dbus_request_start_recording(int pid, bool command);
+
+
+int vc_widget_dbus_request_start(int pid, int silence);
+
+int vc_widget_dbus_request_stop(int pid);
+
+int vc_widget_dbus_request_cancel(int pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_WIDGET_DBUS_H_ */
diff --git a/common/vc_command.c b/common/vc_command.c
new file mode 100644 (file)
index 0000000..fd501da
--- /dev/null
@@ -0,0 +1,775 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include <libintl.h>
+#include <stdlib.h>
+
+#include "vc_command.h"
+#include "vc_main.h"
+#include "voice_control_command.h"
+#include "voice_control_command_expand.h"
+#include "voice_control_common.h"
+#include "voice_control_key_defines.h"
+
+
+int vc_cmd_list_create(vc_cmd_list_h* vc_cmd_list)
+{
+       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 = (vc_cmd_list_s*)calloc(1, sizeof(vc_cmd_list_s));
+
+       if (NULL == list) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not enough memory");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       list->index = -1;
+       list->list = NULL;
+
+       *vc_cmd_list = (vc_cmd_list_h)list;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p)", *vc_cmd_list);
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_destroy(vc_cmd_list_h vc_cmd_list, bool release_command)
+{
+       if (NULL == vc_cmd_list) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
+               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;
+       }
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_get_count(vc_cmd_list_h vc_cmd_list, int* count)
+{
+       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;
+       }
+
+       vc_cmd_list_s* list = NULL;
+       list = (vc_cmd_list_s*)vc_cmd_list;
+
+       *count = g_slist_length(list->list);
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p), count(%d)", list, *count);
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_add(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command)
+{
+       if (NULL == vc_cmd_list || NULL == vc_command) {
+               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_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       list->list = g_slist_append(list->list, cmd);
+
+       if (1 == g_slist_length(list->list)) {
+               list->index = 0;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list(%p), command(%p)", list, cmd);
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_remove(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command)
+{
+       if (NULL == vc_cmd_list || NULL == vc_command) {
+               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_s* cmd = NULL;
+       cmd = (vc_cmd_s*)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);
+       }
+
+       int count = g_slist_length(list->list);
+
+       if (0 == count) {
+               list->index = -1;
+       } else if (list->index == count) {
+               list->index = count - 1;
+       }
+
+       return VC_ERROR_NONE;
+}
+
+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 (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;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list (%p), release command (%s)"
+               , list, release_command ? "true" : "false");
+
+       int count = g_slist_length(list->list);
+
+       int i ;
+       vc_cmd_s *temp_cmd;
+
+       for (i = 0;i < count ;i++) {
+               temp_cmd = g_slist_nth_data(list->list, 0);
+
+               if (NULL != temp_cmd) {
+                       list->list = g_slist_remove(list->list, temp_cmd);
+
+                       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;
+                       }
+               } 
+       }
+
+       list->index = -1;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCCMD, " ");
+
+       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 (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;
+
+       int count = g_slist_length(list->list);
+       int i ;
+
+       GSList *iter = NULL;
+       vc_cmd_s *temp_cmd;
+
+       iter = g_slist_nth(list->list, 0);
+
+       for (i = 0;i < count;i++) {
+               temp_cmd = iter->data;
+
+               if (NULL != temp_cmd) {
+                       if (false == callback((vc_cmd_h)temp_cmd, user_data)) {
+                               break;
+                       }
+
+               } 
+               iter = g_slist_next(iter);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "===== Foreach commands Done");
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_first(vc_cmd_list_h vc_cmd_list)
+{
+       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;
+
+       if (0 == g_slist_length(list->list)) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] List is empty");
+               return VC_ERROR_EMPTY;
+       }
+
+       list->index = 0;
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_last(vc_cmd_list_h vc_cmd_list)
+{
+       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;
+
+       int count = g_slist_length(list->list);
+
+       if (0 == count) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] List is empty");
+               return VC_ERROR_EMPTY;
+       } else {
+               list->index = count - 1;
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
+       }
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_next(vc_cmd_list_h vc_cmd_list)
+{
+       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;
+
+       int count = g_slist_length(list->list);
+
+       if (list->index < count - 1) {
+               list->index = list->index + 1;
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
+               return VC_ERROR_ITERATION_END;
+       }
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_prev(vc_cmd_list_h vc_cmd_list)
+{
+       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;
+
+       if (list->index > 0) {
+               list->index = list->index - 1;
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[DEBUG] List index : %d", list->index);
+               return VC_ERROR_ITERATION_END;
+       }
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_list_get_current(vc_cmd_list_h vc_cmd_list, vc_cmd_h* vc_command)
+{
+       if (NULL == vc_cmd_list || NULL == vc_command) {
+               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;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list (%p), index (%d)", list, list->index);
+
+       if (0 == g_slist_length(list->list)) {
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[List] list is empty");
+               *vc_command = NULL;
+               return VC_ERROR_EMPTY;
+       }
+
+       vc_cmd_s *temp_cmd = NULL;
+       temp_cmd = g_slist_nth_data(list->list, list->index);
+
+       *vc_command = (vc_cmd_h)temp_cmd;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[List] Get current command (%p)", *vc_command);
+
+       return VC_ERROR_NONE;
+}
+
+
+int vc_cmd_create(vc_cmd_h* vc_command)
+{
+       if (NULL == vc_command) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* command = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s));
+
+       if (NULL == command) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Not enough memory");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       command->pid = 0;
+       command->id = 0;
+       command->index = 0;
+       command->type = VC_COMMAND_TYPE_NONE;
+       command->format = VC_CMD_FORMAT_FIXED;
+       command->command = NULL;
+       command->parameter = NULL;
+       command->domain = 0;
+       command->key = VC_KEY_NONE;
+       command->modifier = VC_MODIFIER_NONE;
+
+       *vc_command = (vc_cmd_h)command;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Create command][%p]", *vc_command);
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_destroy(vc_cmd_h vc_command)
+{
+       if (NULL == vc_command) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Input parameter is NULL");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* command = NULL;
+       command = (vc_cmd_s*)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;
+       }
+
+       return VC_ERROR_NONE;
+}
+
+int vc_cmd_set_id(vc_cmd_h vc_command, int id)
+{
+       if (NULL == vc_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 (NULL != cmd) {
+               cmd->id = id;
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[Set id][%p] id(%d)", vc_command, cmd->id);
+       }
+
+       return 0;       
+}
+
+int vc_cmd_get_id(vc_cmd_h vc_command, int* id)
+{
+       if (NULL == vc_command || NULL == id) {
+               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 (NULL != cmd) {
+               *id = cmd->id;
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[Get id][%p] id(%d)", vc_command, *id);
+       }
+
+       return 0;
+}
+
+int vc_cmd_set_command(vc_cmd_h vc_command, const char* command)
+{
+       if (NULL == vc_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 (NULL != cmd->command) {
+               free(cmd->command);
+       }
+
+       cmd->command = NULL;
+
+       if (NULL != command) {
+               cmd->command = strdup(command);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set command][%p] Command(%s)", vc_command, cmd->command);
+
+       return 0;
+}
+
+int vc_cmd_get_command(vc_cmd_h vc_command, char** command)
+{
+       if (NULL == vc_command || NULL == command) {
+               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 (NULL != cmd->command) {
+               *command = strdup(gettext(cmd->command));
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get command][%p] Command(%s)", vc_command, *command);
+
+       return 0;
+}
+
+int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command)
+{
+       if (NULL == vc_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 (NULL != cmd->parameter) {
+               free(cmd->parameter);
+       }
+
+       cmd->parameter = NULL;
+
+       if (NULL != command) {
+               cmd->parameter = strdup(command);
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[Set parameter][%p] parameter(%s)", vc_command, cmd->parameter);
+       }
+
+       return 0;
+}
+
+int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command)
+{
+       if (NULL == vc_command || NULL == command) {
+               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 (NULL != cmd->parameter) {
+               *command = strdup(gettext(cmd->parameter));
+               SLOG(LOG_DEBUG, TAG_VCCMD, "[Get nonfixed command][%p] nonfixed command(%s)", vc_command, *command);
+       }
+
+       return 0;
+}
+
+//int vc_cmd_set_type(vc_cmd_h vc_command, vc_cmd_type_e type)
+int vc_cmd_set_type(vc_cmd_h vc_command, int type)
+{
+       if (NULL == vc_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;
+
+       cmd->type = type;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set type][%p] type(%d)", vc_command, cmd->type);
+
+       return 0;
+}
+
+int vc_cmd_get_type(vc_cmd_h vc_command, int* type)
+{
+       if (NULL == vc_command || NULL == type) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       *type = cmd->type;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get type][%p] type(%d)", vc_command, *type);
+
+       return 0;
+}
+
+int vc_cmd_set_format(vc_cmd_h vc_command, vc_cmd_format_e format)
+{
+       if (NULL == vc_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;
+
+       cmd->format = format;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set format][%p] format(%d)", vc_command, format);
+
+       return 0;
+}
+
+int vc_cmd_get_format(vc_cmd_h vc_command, vc_cmd_format_e* format)
+{
+       if (NULL == vc_command || NULL == format) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       *format = cmd->format;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get format][%p] format(%d)", vc_command, *format);
+
+       return 0;
+}
+
+int vc_cmd_set_pid(vc_cmd_h vc_command, int pid)
+{
+       if (NULL == vc_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;
+
+       cmd->pid = pid;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set pid][%p] pid(%d)", vc_command, cmd->pid);
+
+       return 0;
+}
+
+int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid)
+{
+       if (NULL == vc_command || NULL == pid) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       *pid = cmd->pid;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get pid][%p] pid(%d)", vc_command, *pid);
+
+       return 0;
+}
+
+int vc_cmd_set_domain(vc_cmd_h vc_command, int domain)
+{
+       if (NULL == vc_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;
+
+       cmd->domain = domain;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Set domain] domain : %d", domain);
+
+       return 0;
+}
+
+int vc_cmd_get_domain(vc_cmd_h vc_command, int* domain)
+{
+       if (NULL == vc_command || NULL == domain) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       *domain = cmd->domain;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "[Get domain] domain : %d", *domain);
+
+       return 0;
+}
+
+/**
+* @brief Sets key value of command.
+*
+* @param[in] vc_command Command handle
+* @param[in] key key value
+* @param[in] modifier modifier value
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @see vc_cmd_get_result_key()
+*/
+int vc_cmd_set_result_key(vc_cmd_h vc_command, int key, int modifier)
+{
+       SLOG(LOG_DEBUG, TAG_VCCMD, "===== Set result key");
+
+       if (NULL == vc_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;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "key : %d, modifier : %d", key, modifier);
+
+       cmd->key = key;
+       cmd->modifier = modifier;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCCMD, " ");
+
+       return 0;
+}
+
+/**
+* @brief Gets key value of command.
+*
+* @param[in] vc_command Command handle
+* @param[out] key key value
+* @param[out] modifier modifier value
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @see vc_cmd_add_result_key()
+*/
+int vc_cmd_get_result_key(vc_cmd_h vc_command, int* key, int* modifier)
+//int vc_command_get_result_key(vc_cmd_h vc_command, int* key, int* modifier)
+{
+       SLOG(LOG_DEBUG, TAG_VCCMD, "===== Get result key");
+
+       if (NULL == vc_command || NULL == key || NULL == modifier) {
+               SLOG(LOG_ERROR, TAG_VCCMD, "[ERROR] Invalid parameter ");
+               return VC_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_cmd_s* cmd = NULL;
+       cmd = (vc_cmd_s*)vc_command;
+
+       *key = cmd->key;
+       *modifier = cmd->modifier;
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCCMD, " ");
+
+       return 0;
+}
+
+int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list)
+{
+       if (NULL == vc_cmd_list) {
+               return -1;
+       }
+
+       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, "[List][%p]", list);
+
+       int count = g_slist_length(list->list);
+
+       int i;
+       vc_cmd_s *temp_cmd = NULL;
+
+       for (i = 0;i < count ;i++) {
+               temp_cmd = g_slist_nth_data(list->list, i);
+
+               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);
+               } 
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCCMD, "==================");
+       SLOG(LOG_DEBUG, TAG_VCCMD, " ");
+
+       return 0;
+}
diff --git a/common/vc_command.h b/common/vc_command.h
new file mode 100644 (file)
index 0000000..b490f34
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_INTERNAL_COMMAND_h_
+#define __VOICE_CONTROL_INTERNAL_COMMAND_h_
+
+#include <glib.h>
+
+#include "voice_control_command.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct _command_s{
+       int     pid;
+       int     id;
+       int     index;
+       int     type;
+       int     format;
+       int     domain;
+       char*   command;
+       char*   parameter;
+
+       /* not used */
+       int     key;
+       int     modifier;
+}vc_cmd_s;
+
+typedef struct {
+       int index;
+       GSList* list;
+}vc_cmd_list_s;
+
+/**
+* @brief Enumerations of command type.
+* @since_tizen 2.4
+*/
+typedef enum {
+       VC_COMMAND_TYPE_NONE = 0,       /**< No command position */
+       VC_COMMAND_TYPE_FOREGROUND = 1, /**< Foreground command by client*/
+       VC_COMMAND_TYPE_BACKGROUND = 2, /**< Background command by client */
+       VC_COMMAND_TYPE_WIDGET = 3,     /**< Widget command by widget client */
+       VC_COMMAND_TYPE_SYSTEM = 4,     /**< System command by manager client */
+       VC_COMMAND_TYPE_EXCLUSIVE = 5   /**< exclusive command by manager client */
+}vc_cmd_type_e;
+
+
+int vc_cmd_set_id(vc_cmd_h vc_command, int id);
+
+int vc_cmd_get_id(vc_cmd_h vc_command, int* id);
+
+int vc_cmd_print_list(vc_cmd_list_h vc_cmd_list);
+
+/**
+* @brief Remove all commands from command list.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+* @param[in] free_command The command free option @c true = release each commands in list,
+*                      @c false = remove command from list
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_CMD_ERROR_NONE Successful
+* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_CMD_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature
+*
+* @see vc_cmd_list_add()
+*/
+int vc_cmd_list_remove_all(vc_cmd_list_h vc_cmd_list, bool free_command);
+
+/**
+* @brief Sets extra unfixed command.
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[in] command The unfixed command
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_CMD_ERROR_NONE Successful
+* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_CMD_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature
+*
+* @see vc_cmd_get_non_fixed_command()
+*/
+int vc_cmd_set_unfixed_command(vc_cmd_h vc_command, const char* command);
+
+/**
+* @brief Sets pid.
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[in] pid process id
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_CMD_ERROR_NONE Successful
+* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @see vc_cmd_set_pid()
+*/
+int vc_cmd_set_pid(vc_cmd_h vc_command, int pid);
+
+/**
+* @brief Sets command domain
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[in] domain domain
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_CMD_ERROR_NONE Successful
+* @retval #VC_CMD_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_CMD_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_CMD_ERROR_NOT_SUPPORTED Not supported feature
+*
+* @see vc_cmd_get_domain()
+*/
+int vc_cmd_get_pid(vc_cmd_h vc_command, int* pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VOICE_CONTROL_INTERNAL_COMMAND_h_ */
diff --git a/common/vc_config_mgr.c b/common/vc_config_mgr.c
new file mode 100644 (file)
index 0000000..153d7ef
--- /dev/null
@@ -0,0 +1,1654 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include <dirent.h>
+#include <dlfcn.h>
+#include <dlog.h>
+#include <Ecore.h>
+#include <fcntl.h>
+#include <glib.h>
+#include <unistd.h>
+#include <sys/inotify.h>
+#include <vconf.h>
+#include <vconf-internal-keys.h>
+
+#include "vc_config_mgr.h"
+#include "vc_defs.h"
+#include "vc_config_parser.h"
+#include "vc_main.h"
+#include "voice_control_command.h"
+
+#define EVENT_SIZE  (sizeof(struct inotify_event))
+#define BUF_LEN     (EVENT_SIZE + 16)
+
+typedef struct {
+       int     uid;
+       vc_config_lang_changed_cb       lang_cb;
+       vc_config_foreground_changed_cb foreground_cb;
+       vc_config_state_changed_cb      state_cb;
+       vc_config_enabled_cb            enabled_cb;
+}vc_config_client_s;
+
+
+const char* vc_config_tag()
+{
+       return TAG_VCCONFIG;
+}
+
+static GSList* g_engine_list = NULL;
+
+static GSList* g_config_client_list = NULL;
+
+static vc_config_s* g_config_info;
+
+static int g_service_state;
+
+static int g_foreground_pid;
+
+static int g_lang_ref_count;
+static Ecore_Fd_Handler* g_fd_handler_lang = NULL;
+static int g_fd_lang;
+static int g_wd_lang;
+
+static int g_state_ref_count;
+static Ecore_Fd_Handler* g_fd_handler_state = NULL;
+static int g_fd_state;
+static int g_wd_state;
+
+static int g_fore_ref_count;
+static Ecore_Fd_Handler* g_fd_handler_fore = NULL;
+static int g_fd_fore;
+static int g_wd_fore;
+
+
+int __vc_config_mgr_print_engine_info();
+
+int __vc_config_mgr_print_client_info();
+
+int vc_config_convert_error_code(vc_config_error_e code)
+{
+       if (code == VC_CONFIG_ERROR_NONE)                       return VC_ERROR_NONE;
+       if (code == VC_CONFIG_ERROR_OPERATION_FAILED)           return VC_ERROR_OPERATION_FAILED;
+       if (code == VC_CONFIG_ERROR_INVALID_PARAMETER)          return VC_ERROR_INVALID_PARAMETER;
+       if (code == VC_CONFIG_ERROR_ENGINE_NOT_FOUND)           return VC_ERROR_ENGINE_NOT_FOUND;
+       if (code == VC_CONFIG_ERROR_INVALID_STATE)              return VC_ERROR_INVALID_STATE;
+       if (code == VC_CONFIG_ERROR_INVALID_LANGUAGE)           return VC_ERROR_INVALID_LANGUAGE;
+       if (code == VC_CONFIG_ERROR_IO_ERROR)                   return VC_ERROR_IO_ERROR;
+       if (code == VC_CONFIG_ERROR_OUT_OF_MEMORY)              return VC_ERROR_OUT_OF_MEMORY;
+
+       return VC_CONFIG_ERROR_NONE;
+}
+
+int __vc_config_mgr_check_engine_is_valid(const char* engine_id)
+{
+       if (NULL == engine_id) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       GSList *iter = NULL;
+       vc_engine_info_s *engine_info = NULL;
+
+       if (0 >= g_slist_length(g_engine_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!");
+               return -1;
+       }
+
+       iter = g_slist_nth(g_engine_list, 0);
+
+       while (NULL != iter) {
+               engine_info = iter->data;
+
+               if (NULL == engine_info) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine info is NULL");
+                       return -1;
+               }
+
+               if (NULL == engine_info->uuid) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine id is NULL");
+                       return -1;
+               }
+
+               if (!strcmp(engine_id, engine_info->uuid)) {
+                       SLOG(LOG_DEBUG, vc_config_tag(), "Default engine is valid : %s", engine_id);
+                       return 0;
+               }
+
+               iter = g_slist_next(iter);
+       }
+
+       iter = g_slist_nth(g_engine_list, 0);
+       engine_info = iter->data;
+
+       if (NULL == engine_info) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine info is NULL");
+               return -1;
+       }
+
+       if (NULL == engine_info->uuid) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine id is NULL");
+               return -1;
+       }
+
+       if (NULL == g_config_info) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Config info is NULL");
+               return -1;
+       }
+
+       if (NULL != g_config_info->engine_id)
+               free(g_config_info->engine_id);
+
+       g_config_info->engine_id = strdup(engine_info->uuid);
+       
+       SLOG(LOG_DEBUG, vc_config_tag(), "Default engine is changed : %s", g_config_info->engine_id);
+       if (0 != vc_parser_set_engine(g_config_info->engine_id)) {
+               SLOG(LOG_ERROR, vc_config_tag(), " Fail to save config");
+               return -1;
+       }
+
+       return 0;
+}
+
+bool __vc_config_mgr_check_lang_is_valid(const char* engine_id, const char* language)
+{
+       if (NULL == engine_id || NULL == language) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return false;
+       }
+
+       GSList *iter = NULL;
+       vc_engine_info_s *engine_info = NULL;
+
+       if (0 >= g_slist_length(g_engine_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!");
+               return false;
+       }
+
+       /* Get a first item */
+       iter = g_slist_nth(g_engine_list, 0);
+
+       while (NULL != iter) {
+               engine_info = iter->data;
+
+               if (NULL == engine_info) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine info is NULL");
+                       return false;
+               }
+
+               if (0 != strcmp(engine_id, engine_info->uuid)) {
+                       iter = g_slist_next(iter);
+                       continue;
+               }
+
+               GSList *iter_lang = NULL;
+               char* engine_lang;
+               if (g_slist_length(engine_info->languages) > 0) {
+                       /* Get a first item */
+                       iter_lang = g_slist_nth(engine_info->languages, 0);
+
+                       int i = 1;      
+                       while (NULL != iter_lang) {
+                               /*Get handle data from list*/
+                               engine_lang = iter_lang->data;
+
+                               SLOG(LOG_DEBUG, vc_config_tag(), "  [%dth] %s", i, engine_lang);
+
+                               if (0 == strcmp(language, engine_lang)) {
+                                       return true;
+                               }
+
+                               /*Get next item*/
+                               iter_lang = g_slist_next(iter_lang);
+                               i++;
+                       }
+               }
+               break;
+       }
+
+       return false;
+}
+
+int __vc_config_mgr_select_lang(const char* engine_id, char** language)
+{
+       if (NULL == engine_id || NULL == language) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return false;
+       }
+
+       GSList *iter = NULL;
+       vc_engine_info_s *engine_info = NULL;
+
+       if (0 >= g_slist_length(g_engine_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] There is no engine!!");
+               return false;
+       }
+
+       /* Get a first item */
+       iter = g_slist_nth(g_engine_list, 0);
+
+       while (NULL != iter) {
+               engine_info = iter->data;
+
+               if (NULL == engine_info) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "engine info is NULL");
+                       return false;
+               }
+
+               if (0 != strcmp(engine_id, engine_info->uuid)) {
+                       iter = g_slist_next(iter);
+                       continue;
+               }
+               
+               GSList *iter_lang = NULL;
+               char* engine_lang = NULL;
+               if (g_slist_length(engine_info->languages) > 0) {
+                       /* Get a first item */
+                       iter_lang = g_slist_nth(engine_info->languages, 0);
+                       
+                       while (NULL != iter_lang) {
+                               engine_lang = iter_lang->data;
+                               if (NULL != engine_lang) {
+                                       /* Check base language */
+                                       if (0 == strcmp(VC_BASE_LANGUAGE, engine_lang)) {
+                                               *language = strdup(engine_lang);
+                                               SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language);
+                                               return 0;
+                                       }
+                               }
+
+                               iter_lang = g_slist_next(iter_lang);
+                       }
+
+                       /* Not support base language */
+                       if (NULL != engine_lang) {
+                               *language = strdup(engine_lang);
+                               SLOG(LOG_DEBUG, vc_config_tag(), "Selected language : %s", *language);
+                               return 0;
+                       }
+               }
+               break;
+       }
+
+       return -1;
+}
+
+Eina_Bool vc_config_mgr_inotify_event_cb(void* data, Ecore_Fd_Handler *fd_handler)
+{
+       SLOG(LOG_DEBUG, vc_config_tag(), "===== Config changed callback event");
+
+       int length;
+       struct inotify_event event;
+       memset(&event, '\0', sizeof(struct inotify_event));
+
+       length = read(g_fd_lang, &event, sizeof(struct inotify_event));
+
+       if (0 > length) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event");
+               SLOG(LOG_DEBUG, vc_config_tag(), "=====");
+               SLOG(LOG_DEBUG, vc_config_tag(), " ");
+               return ECORE_CALLBACK_PASS_ON;
+       }
+
+       if (IN_CLOSE_WRITE == event.mask) {
+               int auto_lang = -1;
+               char* lang = NULL;
+               int enabled = -1;
+
+               GSList *iter = NULL;
+               vc_config_client_s* temp_client = NULL;
+
+               if (0 != vc_parser_find_config_changed(&auto_lang, &lang, &enabled))
+                       return ECORE_CALLBACK_PASS_ON;
+
+               if (-1 != auto_lang) {
+                       g_config_info->auto_lang = auto_lang;
+               }
+
+               /* Only language changed */
+               if (NULL != lang) {
+                       char* before_lang = NULL;
+
+                       before_lang = strdup(g_config_info->language);
+
+                       if (NULL != g_config_info->language)    free(g_config_info->language);
+                       g_config_info->language = strdup(lang);
+
+                       /* Call all callbacks of client*/
+                       iter = g_slist_nth(g_config_client_list, 0);
+
+                       while (NULL != iter) {
+                               temp_client = iter->data;
+
+                               if (NULL != temp_client) {
+                                       if (NULL != temp_client->lang_cb) {
+                                               temp_client->lang_cb(before_lang, lang);
+                                       }
+                               }
+
+                               iter = g_slist_next(iter);
+                       }
+
+                       if (NULL != before_lang)        free(before_lang);
+               }
+
+               if (NULL != lang)       free(lang);
+
+               if (-1 != enabled) {
+                       g_config_info->enabled = enabled;
+
+                       /* Call all callbacks of client*/
+                       iter = g_slist_nth(g_config_client_list, 0);
+
+                       while (NULL != iter) {
+                               temp_client = iter->data;
+
+                               if (NULL != temp_client) {
+                                       if (NULL != temp_client->enabled_cb) {
+                                               temp_client->enabled_cb(enabled);
+                                       }
+                               }
+
+                               iter = g_slist_next(iter);
+                       }
+               }
+       } else {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event");
+       }
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "=====");
+       SLOG(LOG_DEBUG, vc_config_tag(), " ");
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+int __vc_config_set_auto_language()
+{
+       char candidate_lang[6] = {'\0', };
+       char* value = NULL;
+
+       value = vconf_get_str(VCONFKEY_LANGSET);
+       if (NULL == value) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[Config ERROR] Fail to get display language");
+               return -1;
+       }
+
+       strncpy(candidate_lang, value, 5);
+       free(value);
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Display language : %s", candidate_lang);
+
+       /* Check current language */
+       if (0 == strncmp(g_config_info->language, candidate_lang, 5)) {
+               SLOG(LOG_DEBUG, vc_config_tag(), "[Config] VC language(%s) is same with display language", g_config_info->language);
+               return 0;
+       }
+
+       if (true == __vc_config_mgr_check_lang_is_valid(g_config_info->engine_id, candidate_lang)) {
+               /* stt default language change */
+               if (NULL == g_config_info->language) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "Current config language is NULL");
+                       return -1;
+               }
+
+               char* before_lang = NULL;
+               if (0 != vc_parser_set_language(candidate_lang)) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "Fail to save default language");
+                       return -1;
+               }
+
+               before_lang = strdup(g_config_info->language);
+
+               free(g_config_info->language);
+               g_config_info->language = strdup(candidate_lang);
+
+               SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Default language change : before(%s) current(%s)", 
+                       before_lang, g_config_info->language);
+
+               /* Call all callbacks of client*/
+               GSList *iter = NULL;
+               vc_config_client_s* temp_client = NULL;
+
+               iter = g_slist_nth(g_config_client_list, 0);
+
+               while (NULL != iter) {
+                       temp_client = iter->data;
+
+                       if (NULL != temp_client) {
+                               if (NULL != temp_client->lang_cb) {
+                                       temp_client->lang_cb(before_lang, g_config_info->language);
+                               }
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+
+               if (NULL != before_lang)        free(before_lang);
+       } else {
+               /* Candidate language is not valid */
+               char* tmp_language = NULL;
+               if (0 != __vc_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to select language");
+                       return -1;
+               }
+
+               if (NULL == tmp_language) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Selected language is NULL");
+                       return -1;
+               }
+
+               char* before_lang = NULL;
+               if (0 != vc_parser_set_language(tmp_language)) {
+                       free(tmp_language);
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config");
+                       return -1;
+               }
+
+               before_lang = strdup(g_config_info->language);
+
+               if (NULL != g_config_info->language) {
+                       free(g_config_info->language);
+                       g_config_info->language = strdup(tmp_language);
+               }
+               free(tmp_language);
+
+               SLOG(LOG_DEBUG, vc_config_tag(), "[Config] Default language change : before(%s) current(%s)", 
+                       before_lang, g_config_info->language);
+
+               /* Call all callbacks of client*/
+               GSList *iter = NULL;
+               vc_config_client_s* temp_client = NULL;
+
+               iter = g_slist_nth(g_config_client_list, 0);
+
+               while (NULL != iter) {
+                       temp_client = iter->data;
+
+                       if (NULL != temp_client) {
+                               if (NULL != temp_client->lang_cb) {
+                                       temp_client->lang_cb(before_lang, g_config_info->language);
+                               }
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+
+               if (NULL != before_lang)        free(before_lang);
+       }
+
+       return 0;
+}
+
+void __vc_config_language_changed_cb(keynode_t *key, void *data)
+{
+       if (true == g_config_info->auto_lang) {
+               /* Get voice input vconf key */
+               __vc_config_set_auto_language();
+       }
+
+       return;
+}
+
+int vc_config_mgr_initialize(int uid)
+{
+       GSList *iter = NULL;
+       int* get_uid;
+       vc_config_client_s* temp_client = NULL;
+
+       if (0 < g_slist_length(g_config_client_list)) {
+               /* Check uid */
+               iter = g_slist_nth(g_config_client_list, 0);
+
+               while (NULL != iter) {
+                       get_uid = iter->data;
+
+                       if (uid == *get_uid) {
+                               SLOG(LOG_WARN, vc_config_tag(), "[CONFIG] uid(%d) has already registered", uid);
+                               return 0;
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+
+               temp_client = (vc_config_client_s*)calloc(1, sizeof(vc_config_client_s));
+               if (NULL == temp_client) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory");
+                       return VC_ERROR_OUT_OF_MEMORY;
+               }
+
+               temp_client->uid = uid;
+               
+               /* Add uid */
+               g_config_client_list = g_slist_append(g_config_client_list, temp_client);
+
+               SLOG(LOG_WARN, vc_config_tag(), "[CONFIG] Add uid(%d) but config has already initialized", uid);
+
+               __vc_config_mgr_print_client_info();
+               return 0;
+       }
+
+       /* Get file name from default engine directory */
+       DIR *dp = NULL;
+       int ret = -1;
+       struct dirent entry;
+       struct dirent *dirp = NULL;
+
+       g_engine_list = NULL;
+
+       dp  = opendir(VC_DEFAULT_ENGINE_INFO);
+       if (NULL != dp) {
+               do {
+                       ret = readdir_r(dp, &entry, &dirp);
+                       if (0 != ret) {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[File ERROR] Fail to read directory");
+                               break;
+                       }
+
+                       if (NULL != dirp) {
+                               if (!strcmp(".", dirp->d_name) || !strcmp("..", dirp->d_name))
+                                       continue;
+
+                               vc_engine_info_s* info = NULL;
+                               char* filepath = NULL;
+                               int filesize = 0;
+
+                               filesize = strlen(VC_DEFAULT_ENGINE_INFO) + strlen(dirp->d_name) + 5;
+                               filepath = (char*)calloc(filesize, sizeof(char));
+
+                               if (NULL != filepath) {
+                                       snprintf(filepath, filesize, "%s/%s", VC_DEFAULT_ENGINE_INFO, dirp->d_name);
+                               } else {
+                                       SLOG(LOG_ERROR, vc_config_tag(), "[Engine Agent ERROR] Memory not enough!!");
+                                       continue;
+                               }
+
+                               if (0 == vc_parser_get_engine_info(filepath, &info)) {
+                                       g_engine_list = g_slist_append(g_engine_list, info);
+                               }
+
+                               if (NULL != filepath) {
+                                       free(filepath);
+                                       filepath = NULL;
+                               }
+                       }
+               } while (NULL != dirp);
+
+               closedir(dp);
+       } else {
+               SLOG(LOG_WARN, vc_config_tag(), "[Engine Agent WARNING] Fail to open default directory");
+       }
+
+       __vc_config_mgr_print_engine_info();
+
+       if (0 != vc_parser_load_config(&g_config_info)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse configure information");
+               return -1;
+       }
+
+       if (0 != __vc_config_mgr_check_engine_is_valid(g_config_info->engine_id)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get default engine");
+               return VC_CONFIG_ERROR_ENGINE_NOT_FOUND;
+       }
+
+       if (true == g_config_info->auto_lang) {
+               /* Check language with display language */
+               __vc_config_set_auto_language();
+       } else {
+               if (false == __vc_config_mgr_check_lang_is_valid(g_config_info->engine_id, g_config_info->language)) {
+                       /* Default language is not valid */
+                       char* tmp_language;
+                       if (0 != __vc_config_mgr_select_lang(g_config_info->engine_id, &tmp_language)) {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to select language");
+                               return -1;
+                       }
+
+                       if (NULL != tmp_language) {
+                               if (NULL != g_config_info->language) {
+                                       free(g_config_info->language);
+                                       g_config_info->language = strdup(tmp_language);
+                               }
+
+                               if (0 != vc_parser_set_language(tmp_language)) {
+                                       free(tmp_language);
+                                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to save config");
+                                       return -1;
+                               }
+
+                               free(tmp_language);
+                       }
+               }
+       }
+
+       /* print daemon config */
+       SLOG(LOG_DEBUG, vc_config_tag(), "== Daemon config ==");
+       SLOG(LOG_DEBUG, vc_config_tag(), " engine : %s", g_config_info->engine_id);
+       SLOG(LOG_DEBUG, vc_config_tag(), " auto language : %s", g_config_info->auto_lang ? "on" : "off");
+       SLOG(LOG_DEBUG, vc_config_tag(), " language : %s", g_config_info->language);
+       SLOG(LOG_DEBUG, vc_config_tag(), "===================");
+
+       /* Get service state */
+       if (0 != vc_parser_get_service_state(&g_service_state)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get state");
+               return VC_CONFIG_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "Current service state : %d", g_service_state);
+
+       if (0 != vc_parser_get_foreground(&g_foreground_pid)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get foreground pid");
+               return VC_CONFIG_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "Current foreground pid : %d", g_foreground_pid);
+
+       g_lang_ref_count = 0;
+       g_state_ref_count = 0;
+       g_fore_ref_count = 0;
+
+       /* Register to detect display language change */
+       vconf_notify_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb, NULL);
+
+       temp_client = (vc_config_client_s*)calloc(1, sizeof(vc_config_client_s));
+       if (NULL == temp_client) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       temp_client->uid = uid;
+       
+       SLOG(LOG_DEBUG, vc_config_tag(), "uid(%d) temp_uid(%d)", uid, temp_client->uid);
+
+       /* Add uid */
+       g_config_client_list = g_slist_append(g_config_client_list, temp_client);
+
+       __vc_config_mgr_print_client_info();
+
+       return 0;
+}
+
+int vc_config_mgr_finalize(int uid)
+{
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       if (0 < g_slist_length(g_config_client_list)) {
+               /* Check uid */
+               iter = g_slist_nth(g_config_client_list, 0);
+
+               while (NULL != iter) {
+                       temp_client = iter->data;
+
+                       if (NULL != temp_client) {
+                               if (uid == temp_client->uid) {
+                                       g_config_client_list = g_slist_remove(g_config_client_list, temp_client);
+                                       free(temp_client);
+                                       break;
+                               }
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       if (0 < g_slist_length(g_config_client_list)) {
+               SLOG(LOG_DEBUG, vc_config_tag(), "Client count (%d)", g_slist_length(g_config_client_list));
+               return 0;
+       }
+
+       vc_engine_info_s *engine_info = NULL;
+
+       if (0 < g_slist_length(g_engine_list)) {
+
+               /* Get a first item */
+               iter = g_slist_nth(g_engine_list, 0);
+
+               while (NULL != iter) {
+                       engine_info = iter->data;
+
+                       if (NULL != engine_info) {
+                               g_engine_list = g_slist_remove(g_engine_list, engine_info);
+
+                               vc_parser_free_engine_info(engine_info);
+                       }
+
+                       iter = g_slist_nth(g_engine_list, 0);
+               }
+       }
+
+       vconf_ignore_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb);
+
+       vc_parser_unload_config(g_config_info);
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "[Success] Finalize config");
+
+       return 0;
+}
+
+
+int __vc_config_mgr_register_lang_event()
+{
+       if (0 == g_lang_ref_count) {
+               /* get file notification handler */
+               int fd;
+               int wd;
+
+               fd = inotify_init();
+               if (fd < 0) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail get inotify fd");
+                       return -1;
+               }
+               g_fd_lang = fd;
+
+               wd = inotify_add_watch(fd, VC_CONFIG, IN_CLOSE_WRITE);
+               g_wd_lang = wd;
+
+               g_fd_handler_lang = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)vc_config_mgr_inotify_event_cb, NULL, NULL, NULL);
+               if (NULL == g_fd_handler_lang) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get handler_noti");
+                       return -1;
+               }
+
+               /* Set non-blocking mode of file */
+               int value;
+               value = fcntl(fd, F_GETFL, 0);
+               value |= O_NONBLOCK;
+
+               if (0 > fcntl(fd, F_SETFL, value)) {
+                       SLOG(LOG_WARN, vc_config_tag(), "[WARNING] Fail to set non-block mode");
+               }
+       }
+       g_lang_ref_count++;
+
+       return 0;
+}
+
+int __vc_config_mgr_unregister_config_event()
+{
+       if (0 == g_lang_ref_count) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Lang ref count is 0");
+               return VC_CONFIG_ERROR_INVALID_STATE;
+       }
+
+       g_lang_ref_count--;
+       if (0 == g_lang_ref_count) {
+               /* delete inotify variable */
+               ecore_main_fd_handler_del(g_fd_handler_lang);
+               inotify_rm_watch(g_fd_lang, g_wd_lang);
+               close(g_fd_lang);
+
+               vconf_ignore_key_changed(VCONFKEY_LANGSET, __vc_config_language_changed_cb);
+       }
+
+       return 0;
+}
+
+int vc_config_mgr_set_lang_cb(int uid, vc_config_lang_changed_cb lang_cb)
+{
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       /* Call all callbacks of client*/
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (uid == temp_client->uid) {
+                               temp_client->lang_cb = lang_cb;
+                               if (0 != __vc_config_mgr_register_lang_event()) {
+                                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to register config event");
+                                       return VC_CONFIG_ERROR_OPERATION_FAILED;
+                               }
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return 0;
+}
+
+int vc_config_mgr_unset_lang_cb(int uid)
+{      
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       /* Call all callbacks of client*/
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (uid == temp_client->uid) {
+                               temp_client->lang_cb = NULL;
+                               __vc_config_mgr_unregister_config_event();
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return 0;
+}
+
+Eina_Bool vc_config_mgr_inotify_state_cb(void* data, Ecore_Fd_Handler *fd_handler)
+{
+       SLOG(LOG_DEBUG, vc_config_tag(), "===== State changed callback event");
+
+       int length;
+       struct inotify_event event;
+       memset(&event, '\0', sizeof(struct inotify_event));
+
+       length = read(g_fd_state, &event, sizeof(struct inotify_event));
+       if (0 > length) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event");
+               SLOG(LOG_DEBUG, vc_config_tag(), "=====");
+               SLOG(LOG_DEBUG, vc_config_tag(), " ");
+               return ECORE_CALLBACK_PASS_ON;
+       }
+
+       if (IN_CLOSE_WRITE == event.mask) {
+               int state = -1;
+               if (0 != vc_parser_get_service_state(&state)) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "Fail to get state");
+                       return ECORE_CALLBACK_PASS_ON;
+               }
+
+               SLOG(LOG_DEBUG, vc_config_tag(), "Previous state(%d) Current state(%d)", g_service_state, state);
+
+               /* If state is not changed */
+               if (g_service_state != state) {
+                       int previous_state = g_service_state;
+                       g_service_state = state;
+
+                       GSList *iter = NULL;
+                       vc_config_client_s* temp_client = NULL;
+
+                       /* Call all callbacks of client*/
+                       iter = g_slist_nth(g_config_client_list, 0);
+
+                       while (NULL != iter) {
+                               temp_client = iter->data;
+
+                               if (NULL != temp_client) {
+                                       if (NULL != temp_client->state_cb) {
+                                               temp_client->state_cb(previous_state, g_service_state);
+                                       }
+                               }
+
+                               iter = g_slist_next(iter);
+                       }
+               }
+       } else {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event");
+       }
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "=====");
+       SLOG(LOG_DEBUG, vc_config_tag(), " ");
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+int __vc_config_mgr_register_state_event()
+{
+       if (0 == g_state_ref_count) {
+               /* get file notification handler */
+               int fd;
+               int wd;
+
+               fd = inotify_init();
+               if (fd < 0) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail get inotify fd");
+                       return -1;
+               }
+               g_fd_state = fd;
+
+               wd = inotify_add_watch(fd, VC_RUNTIME_INFO_SERVICE_STATE, IN_CLOSE_WRITE);
+               g_wd_state = wd;
+
+               g_fd_handler_state = ecore_main_fd_handler_add(fd, ECORE_FD_READ, (Ecore_Fd_Cb)vc_config_mgr_inotify_state_cb, NULL, NULL, NULL);               
+               if (NULL == g_fd_handler_state) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get handler for state");
+                       return -1;
+               }
+       }
+       g_state_ref_count++;
+
+       return 0;
+}
+
+int __vc_config_mgr_unregister_state_event()
+{
+       if (0 == g_state_ref_count) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] State ref count is 0");
+               return VC_CONFIG_ERROR_INVALID_STATE;
+       }
+
+       g_state_ref_count--;
+       if (0 == g_state_ref_count) {
+               /* delete inotify variable */
+               ecore_main_fd_handler_del(g_fd_handler_state);
+               inotify_rm_watch(g_fd_state, g_wd_state);
+               close(g_fd_state);
+       }
+       return 0;
+}
+
+int vc_config_mgr_set_service_state_cb(int uid, vc_config_state_changed_cb state_cb)
+{
+       if (NULL == state_cb) {
+               SLOG(LOG_ERROR, vc_config_tag(), "State changed cb is NULL : uid(%d) ", uid);
+               return VC_CONFIG_ERROR_INVALID_PARAMETER;
+       }
+
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       /* Call all callbacks of client*/
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (uid == temp_client->uid) {
+                               temp_client->state_cb = state_cb;
+                               __vc_config_mgr_register_state_event();
+                               return VC_CONFIG_ERROR_NONE;
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return VC_CONFIG_ERROR_INVALID_PARAMETER;
+}
+
+int vc_config_mgr_unset_service_state_cb(int uid)
+{
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       /* Call all callbacks of client*/
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (uid == temp_client->uid) {
+                               temp_client->state_cb = NULL;
+                               __vc_config_mgr_unregister_state_event();
+                               return 0;
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return VC_CONFIG_ERROR_INVALID_PARAMETER;
+}
+
+Eina_Bool vc_config_mgr_inotify_foreground_cb(void* data, Ecore_Fd_Handler *fd_handler)
+{
+       SLOG(LOG_DEBUG, vc_config_tag(), "===== Foreground changed callback event");
+
+       int length;
+       struct inotify_event event;
+       memset(&event, '\0', sizeof(struct inotify_event));
+
+       length = read(g_fd_fore, &event, sizeof(struct inotify_event));
+       if (0 > length) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty Inotify event");
+               SLOG(LOG_DEBUG, vc_config_tag(), "=====");
+               SLOG(LOG_DEBUG, vc_config_tag(), " ");
+               return ECORE_CALLBACK_PASS_ON;
+       }
+
+       if (IN_CLOSE_WRITE == event.mask) {
+               int foreground_pid = -1;
+               if (0 != vc_parser_get_foreground(&foreground_pid)) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "Fail to get state");
+                       return ECORE_CALLBACK_PASS_ON;
+               }
+
+               SLOG(LOG_DEBUG, vc_config_tag(), "foreground pid (%d)", foreground_pid);
+
+               /* If foreground pid is changed */
+               if (g_foreground_pid != foreground_pid) {
+                       int previous_pid = g_foreground_pid;
+                       g_foreground_pid = foreground_pid;
+
+                       GSList *iter = NULL;
+                       vc_config_client_s* temp_client = NULL;
+
+                       /* Call all callbacks of client*/
+                       iter = g_slist_nth(g_config_client_list, 0);
+
+                       while (NULL != iter) {
+                               temp_client = iter->data;
+
+                               if (NULL != temp_client) {
+                                       if (NULL != temp_client->foreground_cb) {
+                                               temp_client->foreground_cb(previous_pid, g_foreground_pid);
+                                       }
+                               }
+
+                               iter = g_slist_next(iter);
+                       }
+               }
+       } else {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Undefined event");
+       }
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "=====");
+       SLOG(LOG_DEBUG, vc_config_tag(), " ");
+
+       return ECORE_CALLBACK_PASS_ON;
+}
+
+int __vc_config_mgr_register_foreground_event()
+{
+       if (0 == g_fore_ref_count) {
+               /* get file notification handler */
+               int fd;
+               int wd;
+
+               fd = inotify_init();
+               if (fd < 0) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail get inotify fd");
+                       return -1;
+               }
+               g_fd_fore = fd;
+
+               wd = inotify_add_watch(g_fd_fore, VC_RUNTIME_INFO_FOREGROUND, IN_CLOSE_WRITE);
+               g_wd_fore = wd;
+
+               g_fd_handler_fore = ecore_main_fd_handler_add(g_fd_fore, ECORE_FD_READ, 
+                       (Ecore_Fd_Cb)vc_config_mgr_inotify_foreground_cb, NULL, NULL, NULL);            
+               if (NULL == g_fd_handler_fore) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to get handler for foreground");
+                       return -1;
+               }
+       }
+       g_fore_ref_count++;
+       
+       return 0;
+}
+
+int __vc_config_mgr_unregister_foreground_event()
+{
+       if (0 == g_fore_ref_count) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Foreground ref count is 0");
+               return VC_CONFIG_ERROR_INVALID_STATE;
+       }
+
+       g_fore_ref_count--;
+
+       if (0 == g_fore_ref_count) {
+               /* delete inotify variable */
+               ecore_main_fd_handler_del(g_fd_handler_fore);
+               inotify_rm_watch(g_fd_fore, g_wd_fore);
+               close(g_fd_fore);
+       }
+
+       return 0;
+}
+
+int vc_config_mgr_set_foreground_cb(int uid, vc_config_foreground_changed_cb foreground_cb)
+{
+       if (NULL == foreground_cb) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Foreground changed cb is NULL : uid(%d) ", uid);
+               return VC_CONFIG_ERROR_INVALID_PARAMETER;
+       }
+
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       /* Call all callbacks of client*/
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (uid == temp_client->uid) {
+                               temp_client->foreground_cb = foreground_cb;
+                               __vc_config_mgr_register_foreground_event();
+                               return VC_CONFIG_ERROR_NONE;
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return VC_CONFIG_ERROR_INVALID_PARAMETER;
+}
+
+int vc_config_mgr_unset_foreground_cb(int uid)
+{
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       /* Call all callbacks of client*/
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (uid == temp_client->uid) {
+                               temp_client->foreground_cb = NULL;
+                               __vc_config_mgr_unregister_foreground_event();
+                               return 0;
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return VC_CONFIG_ERROR_INVALID_PARAMETER;
+}
+
+int vc_config_mgr_set_enabled_cb(int uid, vc_config_enabled_cb enabled_cb)
+{
+       if (NULL == enabled_cb) {
+               SLOG(LOG_ERROR, vc_config_tag(), "enabled cb is NULL : uid(%d) ", uid);
+               return VC_CONFIG_ERROR_INVALID_PARAMETER;
+       }
+
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       /* Call all callbacks of client*/
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (uid == temp_client->uid) {
+                               temp_client->enabled_cb = enabled_cb;
+                               return VC_CONFIG_ERROR_NONE;
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return VC_CONFIG_ERROR_INVALID_PARAMETER;
+}
+
+int vc_config_mgr_unset_enabled_cb(int uid)
+{
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       /* Call all callbacks of client*/
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+                       if (uid == temp_client->uid) {
+                               temp_client->enabled_cb = NULL;
+                               return 0;
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return VC_CONFIG_ERROR_INVALID_PARAMETER;
+}
+
+int vc_config_mgr_get_auto_language(bool* value)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (NULL == value) {
+               return -1;
+       }
+
+       *value = g_config_info->auto_lang;
+
+       return 0;
+}
+
+int vc_config_mgr_set_auto_language(bool value)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (g_config_info->auto_lang != value) {
+               /* Check language is valid */
+               if (0 != vc_parser_set_auto_lang(value)) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "Fail to save engine id");
+                       return -1;
+               }
+               g_config_info->auto_lang = value;
+
+               if (true == g_config_info->auto_lang) {
+                       __vc_config_set_auto_language();
+               }
+       }
+
+       return 0;
+}
+
+int vc_config_mgr_get_language_list(vc_supported_language_cb callback, void* user_data)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+       
+       if (0 >= g_slist_length(g_engine_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "There is no engine");
+               return -1;
+       }
+
+       GSList *iter = NULL;
+       vc_engine_info_s *engine_info = NULL;
+
+       /* Get a first item */
+       iter = g_slist_nth(g_engine_list, 0);
+
+       while (NULL != iter) {
+               engine_info = iter->data;
+
+               if (NULL == engine_info) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] engine info is NULL");
+                       return -1;
+               }
+
+               if (0 != strcmp(g_config_info->engine_id, engine_info->uuid)) {
+                       iter = g_slist_next(iter);
+                       continue;
+               }
+
+               GSList *iter_lang = NULL;
+               char* lang;
+               
+               /* Get a first item */
+               iter_lang = g_slist_nth(engine_info->languages, 0);
+
+               while (NULL != iter_lang) {
+                       /*Get handle data from list*/
+                       lang = iter_lang->data;
+
+                       SLOG(LOG_DEBUG, vc_config_tag(), " %s", lang);
+                       if (NULL != lang) {
+                               if (false == callback(lang, user_data))
+                                       break;
+                       }
+                       
+                       /*Get next item*/
+                       iter_lang = g_slist_next(iter_lang);
+               }
+               break;
+       }
+
+       return 0;
+}
+
+int vc_config_mgr_get_default_language(char** language)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (NULL == language) {
+               return -1;
+       }
+
+       if (NULL != g_config_info->language) {
+               *language = strdup(g_config_info->language);
+       } else {
+               SLOG(LOG_ERROR, vc_config_tag(), " language is NULL");
+               return -1;
+       }
+
+       return 0;
+}
+
+int vc_config_mgr_set_default_language(const char* language)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (NULL == language) {
+               return -1;
+       }
+
+       /* Check language is valid */
+       if (NULL != g_config_info->language) {
+               if (0 != vc_parser_set_language(language)) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "Fail to save engine id");
+                       return -1;
+               }
+               free(g_config_info->language);
+               g_config_info->language = strdup(language);
+       } else {
+               SLOG(LOG_ERROR, vc_config_tag(), " language is NULL");
+               return -1;
+       }
+
+       return 0;
+}
+
+int vc_config_mgr_get_enabled(bool* value)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (NULL == value) {
+               return -1;
+       }
+
+       *value = g_config_info->enabled;
+
+       return 0;
+}
+
+int vc_config_mgr_set_enabled(bool value)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (0 != vc_parser_set_enabled(value)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Fail to set enabled");
+               return -1;
+       }
+
+       g_config_info->enabled = value;
+
+       return 0;
+}
+
+int vc_config_mgr_get_nonfixed_support(bool* value)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (NULL == value) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Input parameter is NULL");
+               return -1;
+       }
+
+       if (0 >= g_slist_length(g_engine_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "There is no engine");
+               return -1;
+       }
+
+       GSList *iter = NULL;
+       vc_engine_info_s *engine_info = NULL;
+
+       /* Get a first item */
+       iter = g_slist_nth(g_engine_list, 0);
+
+       while (NULL != iter) {
+               engine_info = iter->data;
+
+               if (NULL == engine_info) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] engine info is NULL");
+                       return -1;
+               }
+
+               if (0 != strcmp(g_config_info->engine_id, engine_info->uuid)) {
+                       iter = g_slist_next(iter);
+                       continue;
+               }
+
+               *value = engine_info->non_fixed_support;
+
+               break;
+       }
+
+       return 0;
+}
+
+bool vc_config_check_default_engine_is_valid(const char* engine)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (NULL == engine) {
+               return false;
+       }
+
+       if (0 >= g_slist_length(g_engine_list)) 
+               return false;
+
+       GSList *iter = NULL;
+       vc_engine_info_s *engine_info = NULL;
+
+       /* Get a first item */
+       iter = g_slist_nth(g_engine_list, 0);
+
+       while (NULL != iter) {
+               engine_info = iter->data;
+
+               if (NULL != engine_info) {
+                       if (0 == strcmp(engine, engine_info->uuid)) {
+                               return true;
+                       }
+               }
+               iter = g_slist_next(iter);
+       }
+
+       return false;
+}
+
+bool vc_config_check_default_language_is_valid(const char* language)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       if (NULL == language) {
+               return false;
+       }
+
+       if (NULL == g_config_info->engine_id) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Default engine id is NULL");
+               return false;
+       }
+
+       if (0 >= g_slist_length(g_engine_list)) 
+               return false;
+
+       GSList *iter = NULL;
+       vc_engine_info_s *engine_info = NULL;
+
+       /* Get a first item */
+       iter = g_slist_nth(g_engine_list, 0);
+
+       while (NULL != iter) {
+               engine_info = iter->data;
+
+               if (NULL == engine_info) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Engine info is NULL");
+                       iter = g_slist_next(iter);
+                       continue;
+               }
+               
+               if (0 == strcmp(g_config_info->engine_id, engine_info->uuid)) {
+                       iter = g_slist_next(iter);
+                       continue;
+               }
+
+               GSList *iter_lang = NULL;
+               char* lang;
+
+               /* Get a first item */
+               iter_lang = g_slist_nth(engine_info->languages, 0);
+
+               while (NULL != iter_lang) {
+                       lang = iter_lang->data;
+                       
+                       if (0 == strcmp(language, lang))
+                               return true;
+
+                       /*Get next item*/
+                       iter_lang = g_slist_next(iter_lang);
+               }
+               break;
+       }
+
+       return false;
+}
+
+int vc_config_mgr_set_service_state(int state)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       return vc_parser_set_service_state(state);
+}
+
+int vc_config_mgr_get_service_state(int* state)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       return vc_parser_get_service_state(state);
+}
+
+int vc_config_mgr_set_foreground(int pid, bool value)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       return vc_parser_set_foreground(pid, value);
+}
+
+int vc_config_mgr_get_foreground(int* pid)
+{
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "Not initialized");
+               return -1;
+       }
+
+       return vc_parser_get_foreground(pid);
+}
+
+
+
+int __vc_config_mgr_print_engine_info()
+{
+       GSList *iter = NULL;
+       vc_engine_info_s *engine_info = NULL;
+
+       if (0 >= g_slist_length(g_engine_list)) {
+               SLOG(LOG_DEBUG, vc_config_tag(), "-------------- engine list -----------------");
+               SLOG(LOG_DEBUG, vc_config_tag(), "  No Engine in engine directory");
+               SLOG(LOG_DEBUG, vc_config_tag(), "--------------------------------------------");
+               return 0;
+       }
+
+       /* Get a first item */
+       iter = g_slist_nth(g_engine_list, 0);
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "--------------- engine list -----------------");
+
+       int i = 1;      
+       while (NULL != iter) {
+               engine_info = iter->data;
+
+               SLOG(LOG_DEBUG, vc_config_tag(), "[%dth]", i);
+               SLOG(LOG_DEBUG, vc_config_tag(), " name : %s", engine_info->name);
+               SLOG(LOG_DEBUG, vc_config_tag(), " id   : %s", engine_info->uuid);
+               
+
+               SLOG(LOG_DEBUG, vc_config_tag(), " languages");
+               GSList *iter_lang = NULL;
+               char* lang;
+               if (g_slist_length(engine_info->languages) > 0) {
+                       /* Get a first item */
+                       iter_lang = g_slist_nth(engine_info->languages, 0);
+
+                       int j = 1;      
+                       while (NULL != iter_lang) {
+                               /*Get handle data from list*/
+                               lang = iter_lang->data;
+
+                               SLOG(LOG_DEBUG, vc_config_tag(), "  [%dth] %s", j, lang);
+
+                               /*Get next item*/
+                               iter_lang = g_slist_next(iter_lang);
+                               j++;
+                       }
+               } else {
+                       SLOG(LOG_ERROR, vc_config_tag(), "  language is NONE");
+               }
+               SLOG(LOG_DEBUG, vc_config_tag(), " ");
+               iter = g_slist_next(iter);
+               i++;
+       }
+       SLOG(LOG_DEBUG, vc_config_tag(), "--------------------------------------------");
+
+       return 0;
+}
+
+int __vc_config_mgr_print_client_info()
+{
+       GSList *iter = NULL;
+       vc_config_client_s* temp_client = NULL;
+
+       if (0 >= g_slist_length(g_config_client_list)) {
+               SLOG(LOG_DEBUG, vc_config_tag(), "-------------- Client list -----------------");
+               SLOG(LOG_DEBUG, vc_config_tag(), "  No Client");
+               SLOG(LOG_DEBUG, vc_config_tag(), "--------------------------------------------");
+               return 0;
+       }
+
+       /* Get a first item */
+       iter = g_slist_nth(g_config_client_list, 0);
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "--------------- Client list -----------------");
+
+       int i = 1;      
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               SLOG(LOG_DEBUG, vc_config_tag(), "[%dth] uid(%d)", i, temp_client->uid);
+               
+               iter = g_slist_next(iter);
+               i++;
+       }
+       SLOG(LOG_DEBUG, vc_config_tag(), "--------------------------------------------");
+
+       return 0;
+}
\ No newline at end of file
diff --git a/common/vc_config_mgr.h b/common/vc_config_mgr.h
new file mode 100644 (file)
index 0000000..171e0e2
--- /dev/null
@@ -0,0 +1,108 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __VC_CONFIG_MANAGER_H_
+#define __VC_CONFIG_MANAGER_H_
+
+#include <stdbool.h>
+#include <voice_control_common.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+       VC_CONFIG_ERROR_NONE                    = TIZEN_ERROR_NONE,                     /**< Success, No error */
+       VC_CONFIG_ERROR_OUT_OF_MEMORY           = TIZEN_ERROR_OUT_OF_MEMORY,            /**< Out of Memory */
+       VC_CONFIG_ERROR_IO_ERROR                = TIZEN_ERROR_IO_ERROR,                 /**< I/O error */
+       VC_CONFIG_ERROR_INVALID_PARAMETER       = TIZEN_ERROR_INVALID_PARAMETER,        /**< Invalid parameter */
+       VC_CONFIG_ERROR_INVALID_STATE           = TIZEN_ERROR_VOICE_CONTROL | 0x011,    /**< Invalid state */
+       VC_CONFIG_ERROR_INVALID_LANGUAGE        = TIZEN_ERROR_VOICE_CONTROL | 0x012,    /**< Invalid voice */
+       VC_CONFIG_ERROR_ENGINE_NOT_FOUND        = TIZEN_ERROR_VOICE_CONTROL | 0x013,    /**< No available VC-engine  */
+       VC_CONFIG_ERROR_OPERATION_FAILED        = TIZEN_ERROR_VOICE_CONTROL | 0x014     /**< Operation failed  */
+}vc_config_error_e;
+
+
+typedef void (*vc_config_lang_changed_cb)(const char* before_lang, const char* current_lang);
+
+typedef void (*vc_config_foreground_changed_cb)(int previous, int current);
+
+typedef void (*vc_config_state_changed_cb)(int previous, int current);
+
+typedef void (*vc_config_enabled_cb)(bool enable);
+
+
+int vc_config_mgr_initialize(int uid);
+
+int vc_config_mgr_finalize(int uid);
+
+
+/* Set / Unset callback */
+int vc_config_mgr_set_lang_cb(int uid, vc_config_lang_changed_cb lang_cb);
+
+int vc_config_mgr_unset_lang_cb(int uid);
+
+int vc_config_mgr_set_service_state_cb(int uid, vc_config_state_changed_cb state_cb);
+
+int vc_config_mgr_unset_service_state_cb(int uid);
+
+int vc_config_mgr_set_foreground_cb(int uid, vc_config_foreground_changed_cb foreground_cb);
+
+int vc_config_mgr_unset_foreground_cb(int uid);
+
+int vc_config_mgr_set_enabled_cb(int uid, vc_config_enabled_cb enabled_cb);
+
+int vc_config_mgr_unset_enabled_cb(int uid);
+
+
+int vc_config_mgr_get_auto_language(bool* value);
+
+int vc_config_mgr_set_auto_language(bool value);
+
+int vc_config_mgr_get_language_list(vc_supported_language_cb callback, void* user_data);
+
+int vc_config_mgr_get_default_language(char** language);
+
+int vc_config_mgr_set_default_language(const char* language);
+
+int vc_config_mgr_get_enabled(bool* value);
+
+int vc_config_mgr_set_enabled(bool value);
+
+
+int vc_config_mgr_get_nonfixed_support(bool* value);
+
+bool vc_config_check_default_language_is_valid(const char* language);
+
+int vc_config_convert_error_code(vc_config_error_e code);
+
+
+int vc_config_mgr_set_service_state(int state);
+
+int vc_config_mgr_get_service_state(int* state);
+
+
+int vc_config_mgr_set_foreground(int pid, bool value);
+
+int vc_config_mgr_get_foreground(int* pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_CONFIG_MANAGER_H_ */
diff --git a/common/vc_config_parser.c b/common/vc_config_parser.c
new file mode 100644 (file)
index 0000000..7dd47e3
--- /dev/null
@@ -0,0 +1,1085 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include <dlog.h>
+#include <libxml/parser.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <vconf.h>
+
+#include "vc_defs.h"
+#include "vc_main.h"
+#include "vc_config_parser.h"
+
+
+#define VC_TAG_ENGINE_BASE_TAG         "voice-control-engine"
+#define VC_TAG_ENGINE_NAME             "name"
+#define VC_TAG_ENGINE_ID               "id"
+#define VC_TAG_ENGINE_LANGUAGE_SET     "languages"
+#define VC_TAG_ENGINE_LANGUAGE         "lang"
+#define VC_TAG_ENGINE_NON_FIXED_SUPPORT        "non-fixed-support"
+
+#define VC_TAG_CONFIG_BASE_TAG         "voice-control-config"
+#define VC_TAG_CONFIG_ENGINE_ID                "engine"
+#define VC_TAG_CONFIG_AUTO_LANGUAGE    "auto"
+#define VC_TAG_CONFIG_LANGUAGE         "language"
+#define VC_TAG_CONFIG_ENABLED          "enabled"
+
+#define VC_TAG_INFO_BASE_TAG           "vc_info_option"
+#define VC_TAG_INFO_SERVICE_STATE      "service_state"
+#define VC_TAG_INFO_FOREGROUND         "foreground_pid"
+
+
+extern char* vc_config_tag();
+
+static xmlDocPtr g_config_doc = NULL;
+
+static int __vc_config_parser_set_file_mode(const char* filename)
+{
+       if (NULL == filename) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Invalid parameter");
+               return -1;
+       }
+
+       if (0 > chmod(filename, 0666)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to change file mode");
+               return -1;
+       }
+
+       if (0 > chown(filename, 5000, 5000)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to change file owner");
+               return -1;
+       }
+
+       return 0;
+}
+
+int vc_parser_get_engine_info(const char* path, vc_engine_info_s** engine_info)
+{
+       if (NULL == path || NULL == engine_info) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+
+       doc = xmlParseFile(path);
+       if (doc == NULL) {
+               SLOG(LOG_WARN, vc_config_tag(), "[WARNING] Fail to parse file error : %s", path);
+               return -1;
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_ENGINE_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT 'voice-control-engine'");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* alloc engine info */
+       vc_engine_info_s* temp;
+       temp = (vc_engine_info_s*)calloc(1, sizeof(vc_engine_info_s));
+       if (NULL == temp) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory");
+               xmlFreeDoc(doc);
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       temp->name = NULL;
+       temp->uuid = NULL;
+       temp->languages = NULL;
+       temp->non_fixed_support = false;
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_ENGINE_NAME)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               // SLOG(LOG_DEBUG, vc_config_tag(), "Engine name : %s", (char *)key);
+                               if (NULL != temp->name) free(temp->name);
+                               temp->name = strdup((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] <%s> has no content", VC_TAG_ENGINE_ID);
+                       }
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_ENGINE_ID)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               // SLOG(LOG_DEBUG, vc_config_tag(), "Engine uuid : %s", (char *)key);
+                               if (NULL != temp->uuid) free(temp->uuid);
+                               temp->uuid = strdup((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] <%s> has no content", VC_TAG_ENGINE_ID);
+                       }
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_ENGINE_LANGUAGE_SET)) {
+                       xmlNodePtr lang_node = NULL;
+                       char* temp_lang = NULL;
+
+                       lang_node = cur->xmlChildrenNode;
+
+                       while (lang_node != NULL) {
+                               if (0 == xmlStrcmp(lang_node->name, (const xmlChar *)VC_TAG_ENGINE_LANGUAGE)){
+                                       key = xmlNodeGetContent(lang_node);
+                                       if (NULL != key) {
+                                               // SLOG(LOG_DEBUG, vc_config_tag(), "language : %s", (char *)key);
+                                               temp_lang = strdup((char*)key);
+                                               temp->languages = g_slist_append(temp->languages, temp_lang);
+                                               xmlFree(key);
+                                       } else {
+                                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] <%s> has no content", VC_TAG_ENGINE_LANGUAGE);
+                                       }
+                               }
+
+                               lang_node = lang_node->next;
+                       }
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_ENGINE_NON_FIXED_SUPPORT)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               // SLOG(LOG_DEBUG, vc_config_tag(), "Engine uuid : %s", (char *)key);
+
+                               if (0 == xmlStrcmp(key, (const xmlChar *)"true")) {
+                                       temp->non_fixed_support = true;
+                               } else if (0 == xmlStrcmp(key, (const xmlChar *)"false")) {
+                                       temp->non_fixed_support = false;
+                               } else {
+                                       SLOG(LOG_ERROR, vc_config_tag(), "Auto voice is wrong");
+                                       temp->non_fixed_support = false;
+                               }
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] <%s> has no content", VC_TAG_ENGINE_NON_FIXED_SUPPORT);
+                       }
+               } else {
+
+               }
+
+               cur = cur->next;
+       }
+
+       xmlFreeDoc(doc);
+
+       if (NULL == temp->uuid || NULL == temp->languages) {
+               /* Invalid engine */
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Invalid engine : %s", path);
+               vc_parser_free_engine_info(temp);
+               return -1;
+       }
+
+       *engine_info = temp;
+
+       return 0;
+}
+
+int vc_parser_free_engine_info(vc_engine_info_s* engine_info)
+{
+       if (NULL == engine_info) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       if (NULL != engine_info->name)          free(engine_info->name);
+       if (NULL != engine_info->uuid)          free(engine_info->uuid);
+
+       int count = g_slist_length(engine_info->languages);
+
+       int i ;
+       char *temp_lang;
+
+       for (i = 0;i < count ;i++) {
+               temp_lang = g_slist_nth_data(engine_info->languages, 0);
+
+               if (NULL != temp_lang) {
+                       engine_info->languages = g_slist_remove(engine_info->languages, temp_lang);
+
+                       if (NULL != temp_lang)
+                               free(temp_lang);
+               } 
+       }
+
+       if (NULL != engine_info)        free(engine_info);
+
+       return 0;       
+}
+
+int vc_parser_print_engine_info(vc_engine_info_s* engine_info)
+{
+       if (NULL == engine_info)
+               return -1;
+
+       SLOG(LOG_DEBUG, vc_config_tag(), "== engine info ==");
+       SLOG(LOG_DEBUG, vc_config_tag(), " id   : %s", engine_info->uuid);
+       
+       SLOG(LOG_DEBUG, vc_config_tag(), " languages");
+       GSList *iter = NULL;
+       char* lang;
+       if (g_slist_length(engine_info->languages) > 0) {
+               /* Get a first item */
+               iter = g_slist_nth(engine_info->languages, 0);
+
+               int i = 1;      
+               while (NULL != iter) {
+                       /*Get handle data from list*/
+                       lang = iter->data;
+
+                       SLOG(LOG_DEBUG, vc_config_tag(), "  [%dth] %s", i, lang);
+
+                       /*Get next item*/
+                       iter = g_slist_next(iter);
+                       i++;
+               }
+       } else {
+               SLOG(LOG_ERROR, vc_config_tag(), "  language is NONE");
+       }
+       SLOG(LOG_DEBUG, vc_config_tag(), "=====================");
+
+       return 0;
+}
+
+int vc_parser_load_config(vc_config_s** config_info)
+{
+       if (NULL == config_info) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+       bool is_default_open = false;
+
+       if (0 != access(VC_CONFIG, F_OK)) {
+               doc = xmlParseFile(VC_CONFIG_DEFAULT);
+               if (doc == NULL) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse file error : %s", VC_CONFIG_DEFAULT);
+                       return -1;
+               }
+               SLOG(LOG_DEBUG, vc_config_tag(), "Use default config : %s", VC_CONFIG_DEFAULT);
+               is_default_open = true;
+       } else {
+               int retry_count = 0;
+
+               while (NULL == doc) {
+                       doc = xmlParseFile(VC_CONFIG);
+                       if (NULL != doc) {
+                               break;
+                       }
+                       retry_count++;
+                       usleep(10000);
+
+                       if (VC_RETRY_COUNT == retry_count) {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse file error : %s", VC_CONFIG);
+                               return -1;
+                       }
+               }
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *) VC_TAG_CONFIG_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT %s", VC_TAG_CONFIG_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* alloc engine info */
+       vc_config_s* temp;
+       temp = (vc_config_s*)calloc(1, sizeof(vc_config_s));
+       if (NULL == temp) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to allocate memory");
+               xmlFreeDoc(doc);
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       temp->engine_id = NULL;
+       temp->language = NULL;
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CONFIG_ENGINE_ID)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_config_tag(), "Engine id : %s", (char *)key);
+                               if (NULL != temp->engine_id)    free(temp->engine_id);
+                               temp->engine_id = strdup((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] enable is NULL");
+                       }
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CONFIG_AUTO_LANGUAGE)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_config_tag(), "Auto language : %s", (char *)key);
+
+                               if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
+                                       temp->auto_lang = true;
+                               } else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
+                                       temp->auto_lang = false;
+                               } else {
+                                       SLOG(LOG_ERROR, vc_config_tag(), "Auto voice is wrong");
+                                       temp->auto_lang = false;
+                               }
+
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] voice type is NULL");
+                       }
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CONFIG_LANGUAGE)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_config_tag(), "language : %s", (char *)key);
+                               if (NULL != temp->language)     free(temp->language);
+                               temp->language = strdup((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] language is NULL");
+                       }
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar*)VC_TAG_CONFIG_ENABLED)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_config_tag(), "Enabled service : %s", (char *)key);
+
+                               if (0 == xmlStrcmp(key, (const xmlChar *)"on")) {
+                                       temp->enabled = true;
+                               }
+                               else if (0 == xmlStrcmp(key, (const xmlChar *)"off")) {
+                                       temp->enabled = false;
+                               }
+                               else {
+                                       SLOG(LOG_ERROR, vc_config_tag(), "Enabled service is wrong");
+                                       temp->enabled = false;
+                               }
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Enabled service is NULL");
+                       }
+               } else {
+
+               }
+
+               cur = cur->next;
+       }
+
+       *config_info = temp;
+       g_config_doc = doc;
+
+       if (is_default_open) {
+               xmlSaveFile(VC_CONFIG, g_config_doc);
+               if (0 != __vc_config_parser_set_file_mode(VC_CONFIG))
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set file mode - %s", VC_CONFIG);
+       }
+
+       return 0;
+}
+
+int vc_parser_unload_config(vc_config_s* config_info)
+{
+       if (NULL != g_config_doc)       xmlFreeDoc(g_config_doc);
+
+       if (NULL != config_info) {
+               if (NULL != config_info->engine_id)     free(config_info->engine_id);
+               if (NULL != config_info->language)      free(config_info->language);
+               free(config_info);
+       }
+
+       return 0;
+}
+
+int vc_parser_set_engine(const char* engine_id)
+{
+       if (NULL == engine_id) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       xmlNodePtr cur = NULL;
+       cur = xmlDocGetRootElement(g_config_doc);
+       if (NULL == cur) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *) VC_TAG_CONFIG_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT %s", VC_TAG_CONFIG_BASE_TAG);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (NULL == cur) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       while (NULL != cur) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CONFIG_ENGINE_ID)) {
+                       xmlNodeSetContent(cur, (const xmlChar *)engine_id);
+               }
+
+               cur = cur->next;
+       }
+
+       int ret = xmlSaveFile(VC_CONFIG, g_config_doc);
+       if (0 > ret) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Save result : %d", ret);
+       }
+
+       return 0;
+}
+
+int vc_parser_set_auto_lang(bool value)
+{
+       if (NULL == g_config_doc)
+               return -1;
+
+       xmlNodePtr cur = NULL;
+       cur = xmlDocGetRootElement(g_config_doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *) VC_TAG_CONFIG_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT %s", VC_TAG_CONFIG_BASE_TAG);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CONFIG_AUTO_LANGUAGE)) {
+                       if (true == value) {
+                               xmlNodeSetContent(cur, (const xmlChar *)"on");
+                       } else if (false == value) {
+                               xmlNodeSetContent(cur, (const xmlChar *)"off");
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong value of auto voice");
+                               return -1;
+                       }
+                       break;
+               }
+               cur = cur->next;
+       }
+
+       int ret = xmlSaveFile(VC_CONFIG, g_config_doc);
+       SLOG(LOG_DEBUG, vc_config_tag(), "Save result : %d", ret);
+
+       return 0;
+}
+
+int vc_parser_set_language(const char* language)
+{
+       if (NULL == g_config_doc || NULL == language)
+               return -1;
+
+       xmlNodePtr cur = NULL;
+       cur = xmlDocGetRootElement(g_config_doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *) VC_TAG_CONFIG_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT %s", VC_TAG_CONFIG_BASE_TAG);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CONFIG_LANGUAGE)) {
+                       xmlNodeSetContent(cur, (const xmlChar *)language);
+               } 
+
+               cur = cur->next;
+       }
+
+       int ret = xmlSaveFile(VC_CONFIG, g_config_doc);
+       SLOG(LOG_DEBUG, vc_config_tag(), "Save result : %d", ret);
+
+       return 0;
+}
+
+int vc_parser_set_enabled(bool value)
+{
+       if (NULL == g_config_doc)
+               return -1;
+
+       xmlNodePtr cur = NULL;
+       cur = xmlDocGetRootElement(g_config_doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CONFIG_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT %s", VC_TAG_CONFIG_BASE_TAG);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CONFIG_ENABLED)) {
+                       xmlNodeSetContent(cur, (const xmlChar *)(value ? "on" : "off"));
+               }
+
+               cur = cur->next;
+       }
+
+       int ret = xmlSaveFile(VC_CONFIG, g_config_doc);
+       SLOG(LOG_DEBUG, vc_config_tag(), "Save result : %d", ret);
+
+       return 0;
+}
+
+int vc_parser_find_config_changed(int* auto_lang, char** language, int* enabled)
+{
+       if (NULL == auto_lang || NULL == language) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur_new = NULL;
+       xmlNodePtr cur_old = NULL;
+
+       xmlChar *key_new;
+       xmlChar *key_old;
+
+       int retry_count = 0;
+
+       while (NULL == doc) {
+               doc = xmlParseFile(VC_CONFIG);
+               if (NULL != doc) {
+                       break;
+               }
+               retry_count++;
+               usleep(10000);
+
+               if (VC_RETRY_COUNT == retry_count) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse file error : %s", VC_CONFIG);
+                       return -1;
+               }
+       }
+
+       cur_new = xmlDocGetRootElement(doc);
+       cur_old = xmlDocGetRootElement(g_config_doc);
+       if (cur_new == NULL || cur_old == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur_new->name, (const xmlChar*)VC_TAG_CONFIG_BASE_TAG) || xmlStrcmp(cur_old->name, (const xmlChar*)VC_TAG_CONFIG_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT %s", VC_TAG_CONFIG_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur_new = cur_new->xmlChildrenNode;
+       cur_old = cur_old->xmlChildrenNode;
+       if (cur_new == NULL || cur_old == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       *language = NULL;
+       while (cur_new != NULL && cur_old != NULL) {
+
+               // SLOG(LOG_DEBUG, vc_config_tag(), "cur_new->name(%s), cur_old->name(%s)", (char*)cur_new->name, (char*)cur_old->name);
+
+               if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)VC_TAG_CONFIG_AUTO_LANGUAGE)) {
+                       if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)VC_TAG_CONFIG_AUTO_LANGUAGE)) {
+                               key_old = xmlNodeGetContent(cur_old);
+                               if (NULL != key_old) {
+                                       key_new = xmlNodeGetContent(cur_new);
+                                       if (NULL != key_new) {
+                                               if (0 != xmlStrcmp(key_old, key_new)) {
+                                                       SLOG(LOG_DEBUG, vc_config_tag(), "Old auto lang(%s), New auto lang(%s)", (char*)key_old, (char*)key_new);
+                                                       if (0 == xmlStrcmp(key_new, (const xmlChar*)"on")) {
+                                                               *auto_lang = 1;
+                                                       } else {
+                                                               *auto_lang = 0;
+                                                       }
+                                               }
+                                               xmlFree(key_new);
+                                       }
+                                       xmlFree(key_old);
+                               }
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Old config and new config are different");
+                       }
+               } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)VC_TAG_CONFIG_LANGUAGE)) {
+                       if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)VC_TAG_CONFIG_LANGUAGE)) {
+                               key_old = xmlNodeGetContent(cur_old);
+                               if (NULL != key_old) {
+                                       key_new = xmlNodeGetContent(cur_new);
+                                       if (NULL != key_new) {
+                                               if (0 != xmlStrcmp(key_old, key_new)) {
+                                                       SLOG(LOG_DEBUG, vc_config_tag(), "Old language(%s), New language(%s)", (char*)key_old, (char*)key_new);
+                                                       if (NULL != *language)  free(*language);
+                                                       *language = strdup((char*)key_new);
+                                               }
+                                               xmlFree(key_new);
+                                       }
+                                       xmlFree(key_old);
+                               }
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] old config and new config are different");
+                       }
+               } else if (0 == xmlStrcmp(cur_new->name, (const xmlChar*)VC_TAG_CONFIG_ENABLED)) {
+                       if (0 == xmlStrcmp(cur_old->name, (const xmlChar*)VC_TAG_CONFIG_ENABLED)) {
+                               key_old = xmlNodeGetContent(cur_old);
+                               if (NULL != key_old) {
+                                       key_new = xmlNodeGetContent(cur_new);
+                                       if (NULL != key_new) {
+                                               if (0 != xmlStrcmp(key_old, key_new)) {
+                                                       SLOG(LOG_DEBUG, vc_config_tag(), "Old enabled(%s), New enabled(%s)", (char*)key_old, (char*)key_new);
+                                                       if (0 == xmlStrcmp(key_new, (const xmlChar*)"on")) {
+                                                               *enabled = 1;
+                                                       } else {
+                                                               *enabled = 0;
+                                                       }
+                                               }
+                                               xmlFree(key_new);
+                                       }
+                                       xmlFree(key_old);
+                               }
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] old config and new config are different");
+                       }
+               } else {
+
+               }
+
+               cur_new = cur_new->next;
+               cur_old = cur_old->next;
+       }
+       
+       xmlFreeDoc(g_config_doc);
+       g_config_doc = doc;
+
+       return 0;
+}
+
+int vc_parser_init_service_state()
+{
+       if (0 != access(VC_RUNTIME_INFO_SERVICE_STATE, R_OK | W_OK)) {
+               /* make file */
+               xmlDocPtr doc;
+               xmlNodePtr root_node;
+               xmlNodePtr info_node;
+
+               doc = xmlNewDoc((const xmlChar*)"1.0");
+               doc->encoding = (const xmlChar*)"utf-8";
+               doc->charset = 1;
+
+               root_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_INFO_BASE_TAG);
+               xmlDocSetRootElement(doc,root_node);
+
+               /* Make new command node */
+               info_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_INFO_SERVICE_STATE);
+               xmlNodeSetContent(info_node, (const xmlChar *)"0");
+               xmlAddChild(root_node, info_node);
+
+               int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_SERVICE_STATE, doc, 1);
+               SLOG(LOG_DEBUG, vc_config_tag(), "Save service state info file : %d", ret);
+
+               if (0 != __vc_config_parser_set_file_mode(VC_RUNTIME_INFO_SERVICE_STATE))
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set file mode - %s", VC_RUNTIME_INFO_SERVICE_STATE);
+       }
+
+       return 0;
+}
+
+int vc_parser_set_service_state(int state)
+{
+       /* Set service state */
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+
+       int retry_count = 0;
+
+       while (NULL == doc) {
+               doc = xmlParseFile(VC_RUNTIME_INFO_SERVICE_STATE);
+               if (NULL != doc) {
+                       break;
+               }
+               retry_count++;
+               usleep(10000);
+
+               if (VC_RETRY_COUNT == retry_count) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse file error : %s", VC_RUNTIME_INFO_SERVICE_STATE);
+                       return -1;
+               }
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *) VC_TAG_INFO_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT %s", VC_TAG_INFO_BASE_TAG);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_INFO_SERVICE_STATE)) {                    
+                       char temp[16];
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", state);
+
+                       xmlNodeSetContent(cur, (const xmlChar *)temp);
+                       break;
+               } 
+
+               cur = cur->next;
+       }
+
+       int ret = xmlSaveFile(VC_RUNTIME_INFO_SERVICE_STATE, doc);
+       if (0 >= ret) {
+               SLOG(LOG_DEBUG, vc_config_tag(), "[ERROR] Fail to save service state info file : %d", ret);
+               return -1;
+       }
+       SLOG(LOG_DEBUG, vc_config_tag(), "[Success] Save service state info file : state(%d)", state);
+
+       return 0;
+}
+
+int vc_parser_get_service_state(int* state)
+{
+       if (NULL == state) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       if (0 != access(VC_RUNTIME_INFO_SERVICE_STATE, F_OK)) {
+               /* make file */
+               xmlDocPtr doc;
+               xmlNodePtr root_node;
+               xmlNodePtr info_node;
+
+               doc = xmlNewDoc((const xmlChar*)"1.0");
+               doc->encoding = (const xmlChar*)"utf-8";
+               doc->charset = 1;
+
+               root_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_INFO_BASE_TAG);
+               xmlDocSetRootElement(doc, root_node);
+
+               /* Make new command node */
+               info_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_INFO_SERVICE_STATE);
+               xmlNodeSetContent(info_node, (const xmlChar *)"0");
+               xmlAddChild(root_node, info_node);
+
+               int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_SERVICE_STATE, doc, 1);
+               SLOG(LOG_DEBUG, vc_config_tag(), "Save runtime info file : %d", ret);
+
+               if (0 != __vc_config_parser_set_file_mode(VC_RUNTIME_INFO_SERVICE_STATE))
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set file mode - %s", VC_RUNTIME_INFO_SERVICE_STATE);
+
+               *state = 0;
+               return 0;
+       }
+
+       /* Check file */
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+       int retry_count = 0;
+
+       while (NULL == doc) {
+               doc = xmlParseFile(VC_RUNTIME_INFO_SERVICE_STATE);
+               if (NULL != doc) {
+                       break;
+               }
+               retry_count++;
+               usleep(10000);
+
+               if (VC_RETRY_COUNT == retry_count) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse file error : %s", VC_RUNTIME_INFO_SERVICE_STATE);
+                       return -1;
+               }
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_INFO_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_INFO_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_INFO_SERVICE_STATE)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_config_tag(), "Service state : %s", (char *)key);
+                               *state = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] enable is NULL");
+                       }
+               }
+               cur = cur->next;
+       }
+
+       xmlFreeDoc(doc);
+
+       return 0;
+}
+
+int vc_parser_set_foreground(int pid, bool value)
+{
+       int cur_pid = 0;
+       /* Get foreground pid */
+       if (0 != vc_parser_get_foreground(&cur_pid)) {
+               SLOG(LOG_DEBUG, vc_config_tag(), "Fail to get pid from info file");
+               return -1;
+       }
+
+       if (true == value) {
+               /* Focus in */
+               if (cur_pid == pid) {
+                       return 0;
+               }
+               SLOG(LOG_DEBUG, vc_config_tag(), "Current foreground pid (%d)", cur_pid);
+       } else {
+               /* Focus out */
+               if (VC_NO_FOREGROUND_PID != cur_pid) {
+                       if (cur_pid != pid) {
+                               SLOG(LOG_DEBUG, vc_config_tag(), "Input pid(%d) is NOT different from the saved pid(%d)", pid, cur_pid);
+                               return 0;
+                       }
+               }
+       }
+
+       /* Set foreground pid */
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+
+       int retry_count = 0;
+
+       while (NULL == doc) {
+               doc = xmlParseFile(VC_RUNTIME_INFO_FOREGROUND);
+               if (NULL != doc) {
+                       break;
+               }
+               retry_count++;
+               usleep(10000);
+
+               if (VC_RETRY_COUNT == retry_count) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse file error : %s", VC_RUNTIME_INFO_FOREGROUND);
+                       return -1;
+               }
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *) VC_TAG_INFO_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT %s", VC_TAG_INFO_BASE_TAG);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+               return -1;
+       }
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_INFO_FOREGROUND)) {                       
+                       char temp[16];
+                       memset(temp, 0, 16);
+                       if (true == value) {
+                               snprintf(temp, 16, "%d", pid);
+                       } else {
+                               snprintf(temp, 16, "%d", VC_NO_FOREGROUND_PID);
+                       }
+
+                       xmlNodeSetContent(cur, (const xmlChar *)temp);
+                       break;
+               } 
+
+               cur = cur->next;
+       }
+
+       int ret = xmlSaveFile(VC_RUNTIME_INFO_FOREGROUND, doc);
+       if (0 >= ret) {
+               SLOG(LOG_DEBUG, vc_config_tag(), "[ERROR] Fail to save foreground info : %d", ret);
+               return -1;
+       }
+       SLOG(LOG_DEBUG, vc_config_tag(), "[Success] Save foreground info pid(%d)", pid);
+
+       return 0;
+}
+
+int vc_parser_get_foreground(int* pid)
+{
+       if (NULL == pid) {
+               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       int ret;
+
+       if (0 != access(VC_RUNTIME_INFO_FOREGROUND, F_OK)) {
+               /* make file */
+               xmlDocPtr doc;
+               xmlNodePtr root_node;
+               xmlNodePtr info_node;
+
+               doc = xmlNewDoc((const xmlChar*)"1.0");
+               doc->encoding = (const xmlChar*)"utf-8";
+               doc->charset = 1;
+
+               root_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_INFO_BASE_TAG);
+               xmlDocSetRootElement(doc,root_node);
+
+               /* Make new command node */
+               info_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_INFO_FOREGROUND);
+               xmlNodeSetContent(info_node, (const xmlChar *)"0");
+               xmlAddChild(root_node, info_node);
+
+               ret = xmlSaveFormatFile(VC_RUNTIME_INFO_FOREGROUND, doc, 1);
+               SLOG(LOG_DEBUG, vc_config_tag(), "Save runtime info file : %d", ret);
+
+               *pid = 0;
+
+               if (0 != __vc_config_parser_set_file_mode(VC_RUNTIME_INFO_FOREGROUND))
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to set file mode - %s", VC_RUNTIME_INFO_FOREGROUND);
+       } else {
+               /* Check file */
+               xmlDocPtr doc = NULL;
+               xmlNodePtr cur = NULL;
+               xmlChar *key;
+
+               int retry_count = 0;
+
+               while (NULL == doc) {
+                       doc = xmlParseFile(VC_RUNTIME_INFO_FOREGROUND);
+                       if (NULL != doc) {
+                               break;
+                       }
+                       retry_count++;
+                       usleep(10000);
+
+                       if (VC_RETRY_COUNT == retry_count) {
+                               SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Fail to parse file error : %s", VC_RUNTIME_INFO_FOREGROUND);
+                               return -1;
+                       }
+               }
+
+               cur = xmlDocGetRootElement(doc);
+               if (cur == NULL) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+                       xmlFreeDoc(doc);
+                       return -1;
+               }
+
+               if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_INFO_BASE_TAG)) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_INFO_BASE_TAG);
+                       xmlFreeDoc(doc);
+                       return -1;
+               }
+
+               cur = cur->xmlChildrenNode;
+               if (cur == NULL) {
+                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] Empty document");
+                       xmlFreeDoc(doc);
+                       return -1;
+               }
+
+               while (cur != NULL) {
+                       if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_INFO_FOREGROUND)) {
+                               key = xmlNodeGetContent(cur);
+                               if (NULL != key) {
+                                       SLOG(LOG_DEBUG, vc_config_tag(), "Foreground pid : %s", (char *)key);
+                                       *pid = atoi((char*)key);
+                                       xmlFree(key);
+                               } else {
+                                       SLOG(LOG_ERROR, vc_config_tag(), "[ERROR] enable is NULL");
+                               }
+                       }
+                       cur = cur->next;
+               }
+
+               xmlFreeDoc(doc);
+       }
+
+       return 0;
+}
\ No newline at end of file
diff --git a/common/vc_config_parser.h b/common/vc_config_parser.h
new file mode 100644 (file)
index 0000000..8760d06
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __VC_CONFIG_PARSER_H_
+#define __VC_CONFIG_PARSER_H_
+
+#include <glib.h>
+#include <stdbool.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+       char*   name;
+       char*   uuid;
+       GSList* languages;
+       bool    non_fixed_support;
+}vc_engine_info_s;
+
+typedef struct {
+       char*   engine_id;
+       bool    auto_lang;
+       char*   language;
+       bool    enabled;
+}vc_config_s;
+
+
+/* Get engine information */
+int vc_parser_get_engine_info(const char* path, vc_engine_info_s** engine_info);
+
+int vc_parser_free_engine_info(vc_engine_info_s* engine_info);
+
+
+int vc_parser_load_config(vc_config_s** config_info);
+
+int vc_parser_unload_config(vc_config_s* config_info);
+
+int vc_parser_set_engine(const char* engine_id);
+
+int vc_parser_set_auto_lang(bool value);
+
+int vc_parser_set_language(const char* language);
+
+int vc_parser_set_enabled(bool value);
+
+int vc_parser_find_config_changed(int* auto_lang, char** language, int* enabled);
+
+
+/* Set / Get service state */
+int vc_parser_init_service_state();
+
+int vc_parser_set_service_state(int state);
+
+int vc_parser_get_service_state(int* state);
+
+
+/* Set / Get foreground info */
+int vc_parser_set_foreground(int pid, bool value);
+
+int vc_parser_get_foreground(int* pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_CONFIG_PARSER_H_ */
diff --git a/common/vc_defs.h b/common/vc_defs.h
new file mode 100644 (file)
index 0000000..cc3cd54
--- /dev/null
@@ -0,0 +1,171 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VC_DEFS_H__
+#define __VC_DEFS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/******************************************************************************************
+* Definition for Dbus
+*******************************************************************************************/
+
+#define VC_CLIENT_SERVICE_NAME         "org.tizen.voice.vcclient"
+#define VC_CLIENT_SERVICE_OBJECT_PATH  "/org/tizen/voice/vcclient"
+#define VC_CLIENT_SERVICE_INTERFACE    "org.tizen.voice.vcclient"
+
+#define VC_WIDGET_SERVICE_NAME        "org.tizen.voice.vcwidget"
+#define VC_WIDGET_SERVICE_OBJECT_PATH "/org/tizen/voice/vcwidget"
+#define VC_WIDGET_SERVICE_INTERFACE   "org.tizen.voice.vcwidget"
+
+#define VC_MANAGER_SERVICE_NAME        "org.tizen.voice.vcmanager"
+#define VC_MANAGER_SERVICE_OBJECT_PATH "/org/tizen/voice/vcmanager"
+#define VC_MANAGER_SERVICE_INTERFACE   "org.tizen.voice.vcmanager"
+
+#define VC_SERVER_SERVICE_NAME         "service.connect.vcserver"
+#define VC_SERVER_SERVICE_OBJECT_PATH  "/org/tizen/voice/vcserver"
+#define VC_SERVER_SERVICE_INTERFACE    "org.tizen.voice.vcserver"
+
+
+/******************************************************************************************
+* Message Definition for all 
+*******************************************************************************************/
+
+#define VC_METHOD_HELLO                        "vc_method_hello"
+
+/******************************************************************************************
+* Message Definition for Client
+*******************************************************************************************/
+
+#define VC_METHOD_INITIALIZE           "vc_method_initialize"
+#define VC_METHOD_FINALIZE             "vc_method_finalilze"
+
+#define VC_METHOD_SET_EXCLUSIVE_CMD    "vc_method_set_exclusive_cmd"
+#define VC_METHOD_SET_COMMAND          "vc_method_set_command"
+#define VC_METHOD_UNSET_COMMAND                "vc_method_unset_command"
+
+#define VCD_METHOD_RESULT              "vcd_method_result"
+#define VCD_METHOD_ERROR               "vcd_method_error"
+#define VCD_METHOD_HELLO               "vcd_method_hello"
+
+/* Authority */
+#if 0
+#define VC_METHOD_OBTAIN_AUTHORITY     "vc_method_obtain_authority"
+#define VC_METHOD_RETURN_AUTHORITY     "vc_method_return_authority"
+
+#define VC_METHOD_REQUEST_START                "vc_method_request_start"
+#define VC_METHOD_REQUEST_STOP         "vc_method_request_stop"
+#define VC_METHOD_REQUEST_CANCEL       "vc_method_request_cancel"
+#endif
+
+#define VC_METHOD_AUTH_ENABLE          "vc_method_auth_enable"
+#define VC_METHOD_AUTH_DISABLE         "vc_method_auth_disable"
+
+#define VC_METHOD_AUTH_START           "vc_method_auth_start"
+#define VC_METHOD_AUTH_STOP            "vc_method_auth_stop"
+#define VC_METHOD_AUTH_CANCEL          "vc_method_auth_cancel"
+
+/******************************************************************************************
+* Message Definition for widget
+*******************************************************************************************/
+
+#define VC_WIDGET_METHOD_INITIALIZE            "vc_widget_method_initialize"
+#define VC_WIDGET_METHOD_FINALIZE              "vc_widget_method_finalilze"
+
+#define VC_WIDGET_METHOD_START_RECORDING       "vc_widget_method_start_recording"
+
+#define VC_WIDGET_METHOD_START                 "vc_widget_method_start"
+#define VC_WIDGET_METHOD_STOP                  "vc_widget_method_stop"
+#define VC_WIDGET_METHOD_CANCEL                        "vc_widget_method_cancel"
+
+#define VCD_WIDGET_METHOD_RESULT               "vcd_widget_method_result"
+#define VCD_WIDGET_METHOD_ERROR                        "vcd_widget_method_error"
+#define VCD_WIDGET_METHOD_HELLO                        "vcd_widget_method_hello"
+#define VCD_WIDGET_METHOD_SHOW_TOOLTIP         "vcd_widget_method_show_tooltip"
+
+
+/******************************************************************************************
+* Message Definition for manager
+*******************************************************************************************/
+
+#define VC_MANAGER_METHOD_INITIALIZE           "vc_manager_method_initialize"
+#define VC_MANAGER_METHOD_FINALIZE             "vc_manager_method_finalilze"
+
+#define VC_MANAGER_METHOD_SET_COMMAND          "vc_manager_method_set_command"
+#define VC_MANAGER_METHOD_UNSET_COMMAND                "vc_manager_method_unset_command"
+#define VC_MANAGER_METHOD_SET_DEMANDABLE       "vc_manager_method_set_demandable_client"
+#define VC_MANAGER_METHOD_SET_AUDIO_TYPE       "vc_manager_method_set_audio_type"
+#define VC_MANAGER_METHOD_GET_AUDIO_TYPE       "vc_manager_method_get_audio_type"
+#define VC_MANAGER_METHOD_SET_CLIENT_INFO      "vc_manager_method_set_client_info"
+
+#define VC_MANAGER_METHOD_START                        "vc_manager_method_request_start"
+#define VC_MANAGER_METHOD_STOP                 "vc_manager_method_request_stop"
+#define VC_MANAGER_METHOD_CANCEL               "vc_manager_method_request_cancel"
+#define VC_MANAGER_METHOD_RESULT_SELECTION     "vc_manager_method_result_selection"
+
+#define VCD_MANAGER_METHOD_HELLO               "vcd_manager_method_hello"
+#define VCD_MANAGER_METHOD_SPEECH_DETECTED     "vcd_manager_method_speech_detected"
+#define VCD_MANAGER_METHOD_ALL_RESULT          "vcd_manager_method_all_result"
+#define VCD_MANAGER_METHOD_RESULT              "vcd_manager_method_result"
+
+#define VCD_MANAGER_METHOD_ERROR               "vcd_manager_method_error"
+
+
+/******************************************************************************************
+* Defines for configuration
+*******************************************************************************************/
+
+#define VC_DAEMON_PATH                 "/usr/bin/vc-daemon"
+
+#define VC_CONFIG_DEFAULT              "/usr/lib/voice/vc/1.0/vc-config.xml"
+
+#define VC_CONFIG                      "/opt/home/app/.voice/vc-config.xml"
+
+#define VC_DEFAULT_ENGINE_INFO         "/usr/lib/voice/vc/1.0/engine-info"
+
+#define VC_NO_FOREGROUND_PID           0
+
+#define VC_BASE_LANGUAGE               "en_US"
+
+#define VC_RETRY_COUNT         5
+
+
+#define VC_RUNTIME_INFO_ROOT           "/opt/home/app/.voice/vc"
+
+#define VC_RUNTIME_INFO_AUDIO_VOLUME   VC_RUNTIME_INFO_ROOT"/vc_vol"
+
+#define VC_RUNTIME_INFO_FOREGROUND     VC_RUNTIME_INFO_ROOT"/vc-info-foreground.xml"
+
+#define VC_RUNTIME_INFO_SERVICE_STATE  VC_RUNTIME_INFO_ROOT"/vc-info-state.xml"
+
+#define VC_RUNTIME_INFO_DEMANDABLE_LIST        VC_RUNTIME_INFO_ROOT"/vc-demandable-client.xml"
+
+#define VC_RUNTIME_INFO_RESULT         VC_RUNTIME_INFO_ROOT"/vc-result.xml"
+
+#define VC_RUNTIME_INFO_EX_RESULT      VC_RUNTIME_INFO_ROOT"/vc-ex-result.xml"
+
+#define VC_RUNTIME_INFO_CLIENT         VC_RUNTIME_INFO_ROOT"/vc-client-info.xml"
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_DEFS_H__ */
diff --git a/common/vc_info_parser.c b/common/vc_info_parser.c
new file mode 100644 (file)
index 0000000..e8093ae
--- /dev/null
@@ -0,0 +1,1611 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include <dlog.h>
+#include <libxml/parser.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "vc_defs.h"
+#include "vc_info_parser.h"
+#include "vc_main.h"
+#include "voice_control_command.h"
+#include "voice_control_command_expand.h"
+#include "voice_control_common.h"
+
+
+#define VC_TAG_CMD_BASE_TAG            "vc_commands"
+
+#define VC_TAG_CMD_COMMAND             "command"
+#define VC_TAG_CMD_ID                  "cmd_id"
+#define VC_TAG_CMD_PID                 "cmd_pid"
+#define VC_TAG_CMD_TYPE                        "cmd_type"
+#define VC_TAG_CMD_FORMAT              "cmd_format"
+#define VC_TAG_CMD_COMMAND_TEXT                "cmd_cmd_text"
+#define VC_TAG_CMD_PARAMETER_TEXT      "cmd_param_text"
+#define VC_TAG_CMD_DOMAIN              "cmd_domain"
+#define VC_TAG_CMD_KEY                 "cmd_key"
+#define VC_TAG_CMD_MODIFIER            "cmd_modifier"
+
+#define VC_TAG_RESULT_BASE_TAG         "vc_results"
+#define VC_TAG_RESULT_TEXT             "result_text"
+#define VC_TAG_RESULT_EVENT            "result_event"
+#define VC_TAG_RESULT_MESSAGE          "result_message"
+
+#define VC_TAG_INFO_BASE_TAG           "vc_info_option"
+#define VC_TAG_INFO_FOREGROUND         "foreground_pid"
+
+#define VC_TAG_DEMANDABLE_CLIENT_BASE_TAG      "vc_demandable_client"
+#define VC_TAG_DEMANDABLE_CLIENT_APPID         "appid"
+
+#define VC_TAG_CLIENT_BASE_TAG         "vc_client_info"
+#define VC_TAG_CLIENT_CLIENT           "client"
+#define VC_TAG_CLIENT_PID              "pid"
+#define VC_TAG_CLIENT_FGCMD            "fgcmd"
+#define VC_TAG_CLIENT_BGCMD            "bgcmd"
+#define VC_TAG_CLIENT_EXCMD            "excmd"
+
+
+const char* vc_info_tag()
+{
+       return TAG_VCINFO;
+}
+
+int __vc_cmd_parser_print_commands(GSList* cmd_list);
+
+
+static int __vc_info_parser_set_file_mode(const char* filename)
+{
+       if (NULL == filename) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Invalid parameter");
+               return -1;
+       }
+
+       if (0 > chmod(filename, 0666)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to change file mode");
+               return -1;
+       }
+
+       if (0 > chown(filename, 5000, 5000)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to change file owner");
+               return -1;
+       }
+
+       return 0;
+}
+
+int __vc_cmd_parser_make_filepath(int pid, vc_cmd_type_e type, char** path)
+{
+       if (NULL == path) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       *path = (char*)calloc(256, sizeof(char));
+       if (NULL == *path) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to allocate memory");
+               return VC_ERROR_OUT_OF_MEMORY;
+       }
+
+       snprintf(*path, 256, "%s/vc_%d_%d.xml", VC_RUNTIME_INFO_ROOT, (int)type, pid);
+
+       return 0;
+}
+
+int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list)
+{
+       if (0 >= g_slist_length(cmd_list)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Command list is invalid");
+               return -1;
+       }
+
+       /* Check file */
+       char* filepath = NULL;
+       __vc_cmd_parser_make_filepath(pid, type, &filepath);
+
+       if (NULL == filepath) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to create file path");
+               return -1;
+       }
+
+       remove(filepath);
+
+       xmlDocPtr doc;
+       xmlNodePtr root_node;
+       xmlNodePtr cmd_node;
+       xmlNodePtr tmp_node;
+
+       doc = xmlNewDoc((const xmlChar*)"1.0");
+       doc->encoding = (const xmlChar*)"utf-8";
+       doc->charset = 1;
+
+       root_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_BASE_TAG);
+       xmlDocSetRootElement(doc,root_node);
+
+       GSList *iter = NULL;
+       vc_cmd_s *temp_cmd;
+
+       int i;
+       int count = g_slist_length(cmd_list);
+       iter = g_slist_nth(cmd_list, 0);
+
+       SLOG(LOG_DEBUG, vc_info_tag(), "list count : %d", count);
+       char temp[16];
+       int selected_count = 0;
+
+       for (i = 0;i < count;i++) {
+               temp_cmd = iter->data;
+
+               if (NULL == temp_cmd) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "comamnd is NULL");
+                       break;
+               }
+
+               if (type == temp_cmd->type) {
+                       SLOG(LOG_DEBUG, vc_info_tag(), "[%dth] type(%d) format(%d) domain(%d) cmd(%s) param(%s)", 
+                               i, temp_cmd->type, temp_cmd->format, temp_cmd->domain, temp_cmd->command, temp_cmd->parameter);
+
+                       /* Make new command node */
+                       cmd_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_COMMAND);
+
+                       /* ID */
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", i);
+
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_ID);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(cmd_node, tmp_node);
+
+                       /* PID */
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", getpid());
+                       
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_PID);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(cmd_node, tmp_node);
+                       
+                       /* TYPE */
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", temp_cmd->type);
+
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_TYPE);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(cmd_node, tmp_node);
+
+                       /* FORMAT */
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", temp_cmd->format);
+
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_FORMAT);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(cmd_node, tmp_node);
+
+                       /* DOMAIN */
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", temp_cmd->domain);
+
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_DOMAIN);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(cmd_node, tmp_node);
+
+                       /* COMMAND */
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_COMMAND_TEXT);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp_cmd->command);
+                       xmlAddChild(cmd_node, tmp_node);
+
+                       /* PARAMETER */
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_PARAMETER_TEXT);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp_cmd->parameter);
+                       xmlAddChild(cmd_node, tmp_node);
+
+                       xmlAddChild(root_node, cmd_node);
+
+                       selected_count++;
+               } else {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Command type(%d) is NOT valid : request type(%d)", temp_cmd->type, type);
+               }
+               iter = g_slist_next(iter);
+       }
+
+       if (0 < selected_count) {
+               int ret = xmlSaveFormatFile(filepath, doc, 1);
+               if (0 >= ret) {
+                       SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to save command file : %d", ret);
+                       free(filepath);
+                       return -1;
+               }
+
+               if (0 != __vc_info_parser_set_file_mode(filepath)) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to set file mode - %s", filepath);
+               } else {
+                       SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save command file");
+               }
+               free(filepath);
+       } else {
+               free(filepath);
+               
+               SLOG(LOG_DEBUG, vc_info_tag(), "No command");
+               return -1;
+       }
+
+
+       return 0;
+}
+
+int vc_cmd_parser_delete_file(int pid, vc_cmd_type_e type)
+{
+       /* Check file */
+       char* filepath = NULL;
+       __vc_cmd_parser_make_filepath(pid, type, &filepath);
+
+       if (NULL != filepath) {
+               remove(filepath);
+               free(filepath);
+       }
+       return 0;
+}
+
+int vc_cmd_parser_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list)
+{
+       /* Check file */
+       char* filepath = NULL;
+       __vc_cmd_parser_make_filepath(pid, type, &filepath);
+
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+
+       doc = xmlParseFile(filepath);
+       if (doc == NULL) {
+               SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath);
+               return -1;
+       }
+       if (NULL != filepath)   free(filepath);
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CMD_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_CMD_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       GSList* temp_cmd_list = NULL;
+
+       while (cur != NULL) {
+               cur = cur->next;
+
+               if (NULL == cur) {
+                       break;
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) {
+                       continue;
+               }
+
+               xmlNodePtr command_node = NULL;
+               command_node = cur->xmlChildrenNode;
+               command_node = command_node->next;
+
+               vc_cmd_s* temp_cmd;
+               temp_cmd = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s));
+               
+               if (NULL == temp_cmd) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!");
+                       return -1;
+               }
+
+               /* ID */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_ID)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "ID : %s", (char *)key);
+                               temp_cmd->index = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_ID);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+               
+               /* PID */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PID)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "PID : %s", (char *)key);
+                               temp_cmd->pid = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PID);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Type */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_TYPE)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Type : %s", (char *)key);
+                               temp_cmd->type = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_TYPE);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Format */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_FORMAT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Format : %s", (char *)key);
+                               temp_cmd->format = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_FORMAT);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Domain */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_DOMAIN)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Domain : %s", (char *)key);
+                               temp_cmd->domain = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_DOMAIN);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+               
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Command */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Command : %s", (char *)key);
+                               if (0 < xmlStrlen(key)) {
+                                       temp_cmd->command = strdup((char*)key);
+                               } else {
+                                       temp_cmd->command = NULL;
+                               }
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Parameter */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PARAMETER_TEXT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Parameter : %s", (char *)key);
+                               if (0 < xmlStrlen(key)) {
+                                       temp_cmd->parameter = strdup((char*)key);
+                               } else {
+                                       temp_cmd->parameter = NULL;
+                               }
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PARAMETER_TEXT);
+                               if (NULL != temp_cmd->command)  free(temp_cmd->command);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               if (type == temp_cmd->type) {
+                       temp_cmd_list = g_slist_append(temp_cmd_list, temp_cmd);
+               } else {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Command type(%d) is NOT valid : request type(%d)", temp_cmd->type, type);
+                       vc_cmd_destroy((vc_cmd_h)temp_cmd);
+               }
+       }
+
+       xmlFreeDoc(doc);
+
+       *cmd_list = temp_cmd_list;
+       
+       __vc_cmd_parser_print_commands(temp_cmd_list);
+
+       return 0;
+}
+
+int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_cmd_list)
+{
+       /* Check file */
+       char* filepath = NULL;
+       __vc_cmd_parser_make_filepath(pid, type, &filepath);
+
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+
+       doc = xmlParseFile(filepath);
+       if (doc == NULL) {
+               SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath);
+               return -1;
+       }
+       if (NULL != filepath)   free(filepath);
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CMD_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_CMD_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       vc_cmd_h temp_command = NULL;
+
+       while (cur != NULL) {
+               cur = cur->next;
+
+               if (NULL == cur) {
+                       break;
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) {
+                       continue;
+               }
+
+               xmlNodePtr command_node = NULL;
+               command_node = cur->xmlChildrenNode;
+               command_node = command_node->next;
+
+               if (0 != vc_cmd_create(&temp_command)) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to create command!!");
+                       return -1;
+               }
+
+               /* ID */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_ID)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_info_tag(), "ID : %s", (char *)key);
+                               vc_cmd_set_id(temp_command, atoi((char*)key));
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_ID);
+                               vc_cmd_destroy(temp_command);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* PID */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PID)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_info_tag(), "PID : %s", (char *)key);
+                               vc_cmd_set_pid(temp_command, atoi((char*)key));
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PID);
+                               vc_cmd_destroy(temp_command);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* TYPE */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_TYPE)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_info_tag(), "Type : %s", (char *)key);
+                               vc_cmd_set_type(temp_command, atoi((char*)key));
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_TYPE);
+                               vc_cmd_destroy(temp_command);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* FORMAT */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_FORMAT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_info_tag(), "Format : %s", (char *)key);
+                               vc_cmd_set_format(temp_command, atoi((char*)key));
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_FORMAT);
+                               vc_cmd_destroy(temp_command);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* DOMAIN */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_DOMAIN)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_info_tag(), "Domain : %s", (char *)key);
+                               vc_cmd_set_domain(temp_command, atoi((char*)key));
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_DOMAIN);
+                               vc_cmd_destroy(temp_command);
+                               break;
+                       }
+               }
+               
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Command */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_info_tag(), "Command : %s, size : %d", (char *)key, strlen(key));
+                               vc_cmd_set_command(temp_command, (char*)key);
+                       
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT);
+                               vc_cmd_destroy(temp_command);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Parameter */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PARAMETER_TEXT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               //SLOG(LOG_DEBUG, vc_info_tag(), "Parameter : %s , size : %d", (char *)key, strlen(key));
+                               //vc_cmd_set_parameter(temp_command, (char*)key);
+                               vc_cmd_set_unfixed_command(temp_command, (char*)key);
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PARAMETER_TEXT);
+                               vc_cmd_destroy(temp_command);
+                               break;
+                       }
+               }
+
+               if (0 != vc_cmd_list_add(vc_cmd_list, temp_command)) {
+                       SLOG(LOG_DEBUG, vc_info_tag(), "Fail to add command to list");
+                       vc_cmd_destroy(temp_command);
+                       vc_cmd_list_destroy(vc_cmd_list, true);
+                       return -1;
+               }
+       }
+
+       xmlFreeDoc(doc);
+
+       vc_cmd_print_list(vc_cmd_list);
+
+       return 0;
+}
+
+int vc_info_parser_get_demandable_clients(GSList** client_list)
+{
+       /* Check file */
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+
+       doc = xmlParseFile(VC_RUNTIME_INFO_DEMANDABLE_LIST);
+       if (doc == NULL) {
+               SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", VC_RUNTIME_INFO_FOREGROUND);
+               return -1;
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_DEMANDABLE_CLIENT_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       GSList* temp_client_list = NULL;
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_APPID)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "App id : %s", (char *)key);
+
+                               vc_demandable_client_s* temp_client;
+                               temp_client = (vc_demandable_client_s*)calloc(1, sizeof(vc_demandable_client_s));
+                               
+                               if (NULL == temp_client) {
+                                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!");
+                                       return -1;
+                               }
+
+                               if (0 < xmlStrlen(key)) {
+                                       temp_client->appid = strdup((char*)key);
+                               } else {
+                                       /* NULL for appid is available */
+                                       temp_client->appid = NULL;
+                               }
+                               xmlFree(key);
+
+                               temp_client_list = g_slist_append(temp_client_list, temp_client);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] enable is NULL");
+                       }
+               }
+               cur = cur->next;
+       }
+
+       xmlFreeDoc(doc);
+
+       *client_list = temp_client_list;                
+
+       remove(VC_RUNTIME_INFO_DEMANDABLE_LIST);
+
+       return 0;
+}
+
+int vc_info_parser_set_demandable_client(const char* filepath)
+{
+       if (NULL == filepath) {
+               remove(VC_RUNTIME_INFO_DEMANDABLE_LIST);
+               return 0;
+       }
+
+       /* Check file */
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+
+       doc = xmlParseFile(filepath);
+       if (doc == NULL) {
+               SECURE_SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath);
+               return -1;
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_DEMANDABLE_CLIENT_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       while (cur != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_DEMANDABLE_CLIENT_APPID)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "App id : %s", (char *)key);
+                               xmlFree(key);
+                       } else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] enable is NULL");
+                               xmlFreeDoc(doc);
+                               return -1;
+                       }
+               }
+               cur = cur->next;
+       }
+
+       int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_DEMANDABLE_LIST, doc, 1);
+       SLOG(LOG_DEBUG, vc_info_tag(), "Save demandable file info : %d", ret);
+
+       return 0;
+}
+
+int vc_info_parser_set_result(const char* result_text, int event, const char* msg, vc_cmd_list_h vc_cmd_list, bool exclusive)
+{
+       char filepath[256] = {'\0',};
+
+       if (false == exclusive) {
+               snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_RESULT);
+       } else {
+               snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_EX_RESULT);
+       }
+       
+       SLOG(LOG_DEBUG, vc_info_tag(), "Result file path : %s", filepath);
+
+       /* Check file */
+       remove(filepath);
+
+       xmlDocPtr doc;
+       xmlNodePtr root_node;
+       xmlNodePtr cmd_node;
+       xmlNodePtr tmp_node;
+       char temp[16];
+       int ret = 0;
+
+       doc = xmlNewDoc((const xmlChar*)"1.0");
+       doc->encoding = (const xmlChar*)"utf-8";
+       doc->charset = 1;
+
+       root_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_RESULT_BASE_TAG);
+       xmlDocSetRootElement(doc,root_node);
+
+       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_RESULT_TEXT);
+       xmlNodeSetContent(tmp_node, (const xmlChar *)result_text);
+       xmlAddChild(root_node, tmp_node);
+
+       memset(temp, 0, 16);
+       snprintf(temp, 16, "%d", event);
+
+       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_RESULT_EVENT);
+       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+       xmlAddChild(root_node, tmp_node);
+
+       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_RESULT_MESSAGE);
+       xmlNodeSetContent(tmp_node, (const xmlChar *)msg);
+       xmlAddChild(root_node, tmp_node);       
+
+       /* Make client list node */
+       vc_cmd_h vc_command = NULL;
+
+       vc_cmd_list_first(vc_cmd_list);
+
+       while (VC_ERROR_ITERATION_END != ret) {
+               if (0 != vc_cmd_list_get_current(vc_cmd_list, &vc_command)) {
+                       LOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to get command");
+                       break;
+               }
+
+               if (NULL == vc_command) {
+                       break;
+               }
+
+               vc_cmd_s* temp_cmd = NULL;
+               temp_cmd = (vc_cmd_s*)vc_command;
+
+               /* Make new command node */
+               cmd_node = xmlNewNode(NULL, (const xmlChar*)VC_TAG_CMD_COMMAND);
+               
+               SLOG(LOG_DEBUG, vc_info_tag(), "[Result info] ID(%d) PID(%d) type(%d) format(%d) domain(%d) cmd(%s) param(%s)", 
+                       temp_cmd->id, temp_cmd->pid, temp_cmd->type, temp_cmd->format, temp_cmd->domain, temp_cmd->command, temp_cmd->parameter);
+
+
+               /* ID */
+               memset(temp, 0, 16);
+               snprintf(temp, 16, "%d", temp_cmd->id);
+
+               tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_ID);
+               xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+               xmlAddChild(cmd_node, tmp_node);
+
+               /* PID */
+               memset(temp, 0, 16);
+               snprintf(temp, 16, "%d", temp_cmd->pid);
+
+               tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_PID);
+               xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+               xmlAddChild(cmd_node, tmp_node);
+
+               /* TYPE */
+               memset(temp, 0, 16);
+               snprintf(temp, 16, "%d", temp_cmd->type);
+
+               tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_TYPE);
+               xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+               xmlAddChild(cmd_node, tmp_node);
+
+               /* FORMAT */
+               memset(temp, 0, 16);
+               snprintf(temp, 16, "%d", temp_cmd->format);
+
+               tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_FORMAT);
+               xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+               xmlAddChild(cmd_node, tmp_node);
+
+               /* DOMAIN */
+               memset(temp, 0, 16);
+               snprintf(temp, 16, "%d", temp_cmd->domain);
+
+               tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_DOMAIN);
+               xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+               xmlAddChild(cmd_node, tmp_node);
+
+               /* COMMAND */
+               tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_COMMAND_TEXT);
+               xmlNodeSetContent(tmp_node, (const xmlChar *)temp_cmd->command);
+               xmlAddChild(cmd_node, tmp_node);
+
+               /* PARAMETER */
+               tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CMD_PARAMETER_TEXT);
+               xmlNodeSetContent(tmp_node, (const xmlChar *)temp_cmd->parameter);
+               xmlAddChild(cmd_node, tmp_node);
+
+               xmlAddChild(root_node, cmd_node);
+
+               ret = vc_cmd_list_next(vc_cmd_list);
+       }
+
+       ret = xmlSaveFormatFile(filepath, doc, 1);
+       if (0 >= ret) {
+               SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to save result command file : %d", ret);
+               return -1;
+       }
+
+       SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save result command file");
+
+       return 0;
+}
+
+int vc_info_parser_get_result(char** result_text, int* event, char** result_message, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive)
+{
+       if (NULL == result_text || NULL == event || NULL == vc_cmd_list) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Input parameter is NULL");
+               return -1;
+       }
+
+       char filepath[256] = {'\0',};
+
+       if (false == exclusive) {
+               snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_RESULT);
+       } else {
+               snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_EX_RESULT);
+       }
+       
+       SLOG(LOG_DEBUG, vc_info_tag(), "Result file path : %s", filepath);
+
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+
+       doc = xmlParseFile(filepath);
+       if (doc == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath);
+               return -1;
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_RESULT_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->next;
+       if (NULL == cur) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+       
+       /* Result text */
+       if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_TEXT)) {
+               key = xmlNodeGetContent(cur);
+               if (NULL != key) {
+                       SLOG(LOG_DEBUG, vc_info_tag(), "Result text : %s", (char *)key);
+                       *result_text = strdup((char*)key);
+                       xmlFree(key);
+               } else {
+                       SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_RESULT_TEXT);
+                       return -1;
+               }
+       }
+
+       cur = cur->next;
+       cur = cur->next;
+       if (NULL == cur) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       /* Result event */
+       if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_EVENT)) {
+               key = xmlNodeGetContent(cur);
+               if (NULL != key) {
+                       SLOG(LOG_DEBUG, vc_info_tag(), "Result event : %s", (char *)key);
+                       *event = atoi((char*)key);
+                       xmlFree(key);
+               } else {
+                       SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_RESULT_EVENT);
+                       return -1;
+               }
+       }
+
+       cur = cur->next;
+       cur = cur->next;
+       if (NULL == cur) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+       
+       /* Result Message */
+       if (result_message != NULL) {
+               if (0 == xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_MESSAGE)) {
+                       key = xmlNodeGetContent(cur);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Result message : %s", (char *)key);
+                               *result_message = strdup((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_RESULT_MESSAGE);
+                               return -1;
+                       }
+               }
+       }
+
+       vc_cmd_h vc_command = NULL;
+
+       while (cur != NULL) {
+
+               cur = cur->next;
+               if (NULL == cur) {
+                       break;
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) {
+                       continue;
+               }
+               
+               SLOG(LOG_ERROR, vc_info_tag(), "111 : %s", cur->name);
+
+               /* Check Command tag */
+               if (0 != xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CMD_COMMAND)) {
+                       break;
+               }
+
+               if (0 != vc_cmd_create(&vc_command)) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to create command!!");
+                       return -1;
+               }
+
+               vc_cmd_s* temp_cmd = NULL;
+               temp_cmd = (vc_cmd_s*)vc_command;
+               
+               if (NULL == temp_cmd) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!");
+                       return -1;
+               }
+
+               xmlNodePtr command_node = NULL;
+               command_node = cur->xmlChildrenNode;
+               command_node = command_node->next;
+
+
+               SLOG(LOG_ERROR, vc_info_tag(), "222 : %s", command_node->name);
+
+               /* ID */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_ID)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "ID : %s", (char *)key);
+                               temp_cmd->id = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_ID);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* PID */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PID)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "PID : %s", (char *)key);
+                               temp_cmd->pid = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PID);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Type */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_TYPE)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Type : %s", (char *)key);
+                               temp_cmd->type = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_TYPE);
+                               free(temp_cmd);
+                               return -1;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Format */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_FORMAT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Format : %s", (char *)key);
+                               temp_cmd->format = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_FORMAT);
+                               free(temp_cmd);
+                               return -1;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Domain */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_DOMAIN)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Command domain : %s", (char *)key);
+                               temp_cmd->domain = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_DOMAIN);
+                               free(temp_cmd);
+                               return -1;
+                       }
+               }
+               
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Command */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Command text : %s, size : %d", (char *)key, xmlStrlen(key));
+                               if (0 < xmlStrlen(key)) {
+                                       temp_cmd->command = strdup((char*)key);
+                               } else {
+                                       temp_cmd->command = NULL;
+                               }
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT);
+                               free(temp_cmd);
+                               return -1;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Parameter */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PARAMETER_TEXT)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Parameter text : %s , size : %d", (char *)key, xmlStrlen(key));
+                               if (0 < xmlStrlen(key)) {
+                                       temp_cmd->parameter = strdup((char*)key);
+                               } else {
+                                       temp_cmd->parameter = NULL;
+                               }
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PARAMETER_TEXT);
+                               if (NULL != temp_cmd->command)  free(temp_cmd->command);
+                               free(temp_cmd);
+                               return -1;
+                       }
+               }
+
+               if (0 < pid && pid != temp_cmd->pid) {
+                       SLOG(LOG_DEBUG, vc_info_tag(), "Current command is NOT valid");
+                       vc_cmd_destroy(vc_command);
+               } else {
+                       if (0 != vc_cmd_list_add(vc_cmd_list, vc_command)) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Fail to add command to list");
+                               vc_cmd_destroy(vc_command);
+                               return -1;
+                       }
+               }
+       }
+
+       xmlFreeDoc(doc);
+
+       return 0;
+}
+
+int vc_info_parser_unset_result(bool exclusive)
+{
+       if (false == exclusive) {
+               remove(VC_RUNTIME_INFO_RESULT);
+       } else {
+               remove(VC_RUNTIME_INFO_EX_RESULT);
+       }
+
+       return 0;
+}
+
+int vc_info_parser_get_result_pid_list(GSList** pid_list)
+{
+       char filepath[256] = {'\0', };
+       snprintf(filepath, 256, "%s", VC_RUNTIME_INFO_RESULT);
+
+       SLOG(LOG_DEBUG, vc_info_tag(), "Result file path : %s", filepath);
+
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+
+       doc = xmlParseFile(filepath);
+       if (doc == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[WARNING] Fail to parse file error : %s", filepath);
+               return -1;
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_RESULT_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_RESULT_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       cur = cur->next;
+
+       cur = cur->next;
+       cur = cur->next;
+
+       cur = cur->next;
+       cur = cur->next;
+
+       GSList* iter = NULL;
+       vc_cmd_s* temp_cmd = NULL;
+       vc_cmd_s* check_cmd = NULL;
+
+       while (cur != NULL) {
+
+               cur = cur->next;
+               if (NULL == cur) {
+                       break;
+               }
+               else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) {
+                       continue;
+               }
+
+               /* Check Command tag */
+               if (0 != xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CMD_COMMAND)) {
+                       break;
+               }
+
+               temp_cmd = (vc_cmd_s*)calloc(1, sizeof(vc_cmd_s));
+               if (NULL == temp_cmd) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Fail to alloc command");
+                       break;
+               }
+
+               xmlNodePtr command_node = NULL;
+               command_node = cur->xmlChildrenNode;
+               command_node = command_node->next;
+
+               /* ID */
+               if (0 != xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_ID)) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_ID);
+                       free(temp_cmd);
+                       break;
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* PID */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_PID)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "PID : %s", (char *)key);
+                               temp_cmd->pid = atoi((char*)key);
+                               xmlFree(key);
+                       }
+                       else {
+                               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_PID);
+                               free(temp_cmd);
+                               break;
+                       }
+               }
+
+               command_node = command_node->next;
+               command_node = command_node->next;
+
+               /* Type */
+               if (0 == xmlStrcmp(command_node->name, (const xmlChar *)VC_TAG_CMD_TYPE)) {
+                       key = xmlNodeGetContent(command_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "Type : %s", (char *)key);
+                               temp_cmd->type = atoi((char*)key);
+                               xmlFree(key);
+                       }
+                       else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_TYPE);
+                               free(temp_cmd);
+                               return -1;
+                       }
+               }
+
+               /* check pid in gslist */
+               iter = g_slist_nth(*pid_list, 0);
+               while (NULL != iter) {
+                       check_cmd = iter->data;
+
+                       if (NULL == check_cmd) {
+                               free(temp_cmd);
+                               temp_cmd = NULL;
+                               break;
+                       }
+
+                       if (check_cmd->pid == temp_cmd->pid && check_cmd->type == temp_cmd->type) {
+                               free(temp_cmd);
+                               temp_cmd = NULL;
+                               break;
+                       }
+                       iter = g_slist_next(iter);
+               }
+
+               if (NULL != temp_cmd) {
+                       /* add pid to gslist */
+                       *pid_list = g_slist_append(*pid_list, temp_cmd);
+               }
+       }
+
+       xmlFreeDoc(doc);
+
+       return 0;
+}
+
+int vc_info_parser_set_client_info(GSList* client_info_list)
+{
+       if (0 >= g_slist_length(client_info_list)) {
+               SLOG(LOG_WARN, vc_info_tag(), "[WARNING] client list is empty");
+               return 0;
+       }
+
+       /* Remove file */
+       remove(VC_RUNTIME_INFO_CLIENT);
+
+       xmlDocPtr doc;
+       xmlNodePtr root_node;
+       xmlNodePtr client_node;
+       xmlNodePtr tmp_node;
+
+       doc = xmlNewDoc((const xmlChar*)"1.0");
+       doc->encoding = (const xmlChar*)"utf-8";
+       doc->charset = 1;
+
+       root_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CLIENT_BASE_TAG);
+       xmlDocSetRootElement(doc, root_node);
+
+       GSList *iter = NULL;
+       vc_client_info_s *client = NULL;
+
+       int i;
+       int count = g_slist_length(client_info_list);
+       iter = g_slist_nth(client_info_list, 0);
+
+       SLOG(LOG_DEBUG, vc_info_tag(), "client count : %d", count);
+       char temp[16] = {0, };
+
+       for (i = 0;i < count;i++) {
+               client = iter->data;
+
+               if (NULL != client) {
+                       SLOG(LOG_DEBUG, vc_info_tag(), "[%dth] pid(%d) fgcmd(%d) bgcmd(%d) excmd(%d)", 
+                               i, client->pid, client->fg_cmd, client->bg_cmd, client->exclusive_cmd);
+
+                       /* Make new client node */
+                       client_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CLIENT_CLIENT);
+
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", client->pid);
+
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CLIENT_PID);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(client_node, tmp_node);
+
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", client->fg_cmd);
+
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CLIENT_FGCMD);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(client_node, tmp_node);
+
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", client->bg_cmd);
+
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CLIENT_BGCMD);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(client_node, tmp_node);
+
+                       memset(temp, 0, 16);
+                       snprintf(temp, 16, "%d", client->exclusive_cmd);
+
+                       tmp_node = xmlNewNode(NULL,(const xmlChar*)VC_TAG_CLIENT_EXCMD);
+                       xmlNodeSetContent(tmp_node, (const xmlChar *)temp);
+                       xmlAddChild(client_node, tmp_node);
+
+                       xmlAddChild(root_node, client_node);
+               } 
+               iter = g_slist_next(iter);
+       }
+
+       int ret = xmlSaveFormatFile(VC_RUNTIME_INFO_CLIENT, doc, 1);
+       //xmlFreeDoc(doc);
+       if (0 >= ret) {
+               SLOG(LOG_DEBUG, vc_info_tag(), "[ERROR] Fail to save client file : %d", ret);
+               return -1;
+       }
+
+       SLOG(LOG_DEBUG, vc_info_tag(), "[Success] Save client file");
+
+       return 0;
+}
+
+int vc_info_parser_get_client_info(GSList** client_info_list)
+{
+       xmlDocPtr doc = NULL;
+       xmlNodePtr cur = NULL;
+       xmlChar *key;
+
+       doc = xmlParseFile(VC_RUNTIME_INFO_CLIENT);
+       if (doc == NULL) {
+               SLOG(LOG_WARN, vc_info_tag(), "[WARNING] Fail to parse file error : %s", VC_RUNTIME_INFO_CLIENT);
+               return -1;
+       }
+
+       cur = xmlDocGetRootElement(doc);
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       if (xmlStrcmp(cur->name, (const xmlChar *)VC_TAG_CLIENT_BASE_TAG)) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] The wrong type, root node is NOT '%s'", VC_TAG_CLIENT_BASE_TAG);
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       cur = cur->xmlChildrenNode;
+       if (cur == NULL) {
+               SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Empty document");
+               xmlFreeDoc(doc);
+               return -1;
+       }
+
+       GSList* temp_client_list = NULL;
+
+       while (cur != NULL) {
+               cur = cur->next;
+
+               if (NULL == cur) {
+                       break;
+               } else if (0 == xmlStrcmp(cur->name, (const xmlChar *)"text")) {
+                       continue;
+               }
+
+               xmlNodePtr client_node = NULL;
+               client_node = cur->xmlChildrenNode;
+               client_node = client_node->next;
+
+               vc_client_info_s *client = NULL;
+               client = (vc_client_info_s*)calloc(1, sizeof(vc_client_info_s));
+               
+               if (NULL == client) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] Memory alloc error!!");
+                       return -1;
+               }
+
+               /* PID */
+               if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_PID)) {
+                       key = xmlNodeGetContent(client_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "pid : %s", (char *)key);
+                               client->pid = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_PID);
+                               free(client);
+                               break;
+                       }
+               }
+
+               client_node = client_node->next;
+               client_node = client_node->next;
+
+               /* Foreground command */
+               if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_FGCMD)) {
+                       key = xmlNodeGetContent(client_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "fgcmd : %s", (char *)key);
+                               client->fg_cmd = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_FGCMD);
+                               free(client);
+                               break;
+                       }
+               }
+
+               client_node = client_node->next;
+               client_node = client_node->next;
+
+               /* Background command */
+               if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CLIENT_BGCMD)) {
+                       key = xmlNodeGetContent(client_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "bgcmd : %s", (char *)key);
+                               client->bg_cmd = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CLIENT_BGCMD);
+                               free(client);
+                               break;
+                       }
+               }
+               
+               client_node = client_node->next;
+               client_node = client_node->next;
+
+               /* Text */
+               if (0 == xmlStrcmp(client_node->name, (const xmlChar *)VC_TAG_CMD_COMMAND_TEXT)) {
+                       key = xmlNodeGetContent(client_node);
+                       if (NULL != key) {
+                               SLOG(LOG_DEBUG, vc_info_tag(), "excmd : %s", (char *)key);
+                               client->exclusive_cmd = atoi((char*)key);
+                               xmlFree(key);
+                       } else {
+                               SECURE_SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] <%s> has no content", VC_TAG_CMD_COMMAND_TEXT);
+                               free(client);
+                               break;
+                       }
+               }
+
+               temp_client_list = g_slist_append(temp_client_list, client);
+       }
+
+       xmlFreeDoc(doc);
+
+       *client_info_list = temp_client_list;
+
+       return 0;
+}
+
+int __vc_cmd_parser_print_commands(GSList* cmd_list)
+{
+       int count = g_slist_length(cmd_list);
+       int i ;
+       GSList *iter = NULL;
+       vc_cmd_s *temp_cmd;
+
+       iter = g_slist_nth(cmd_list, 0);
+
+       for (i = 0;i < count;i++) {
+               temp_cmd = iter->data;
+
+               if (NULL == temp_cmd) {
+                       SLOG(LOG_ERROR, vc_info_tag(), "[ERROR] NULL data from command list");
+                       iter = g_slist_next(iter);
+                       continue;
+               }
+
+               SLOG(LOG_DEBUG, vc_info_tag(), "  [%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);
+
+               iter = g_slist_next(iter);
+
+               if (NULL == iter)
+                       break;
+       }
+
+       return 0;
+}
diff --git a/common/vc_info_parser.h b/common/vc_info_parser.h
new file mode 100644 (file)
index 0000000..14a7ed8
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __VC_CMD_PARSER_H_
+#define __VC_CMD_PARSER_H_
+
+#include <glib.h>
+
+#include "vc_command.h"
+#include "voice_control_command.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+typedef struct _demandable_client_s{
+       char*   appid;
+}vc_demandable_client_s;
+
+typedef struct _client_s{
+       int     pid;
+       bool    fg_cmd;
+       bool    bg_cmd;
+       bool    exclusive_cmd;
+}vc_client_info_s;
+
+
+int vc_cmd_parser_save_file(int pid, vc_cmd_type_e type, GSList* cmd_list);
+
+int vc_cmd_parser_delete_file(int pid, vc_cmd_type_e type);
+
+int vc_cmd_parser_get_commands(int pid, vc_cmd_type_e type, GSList** cmd_list);
+
+int vc_cmd_parser_get_command_info(int pid, vc_cmd_type_e type, int index, vc_cmd_s** info);
+
+int vc_cmd_parser_append_commands(int pid, vc_cmd_type_e type, vc_cmd_list_h vc_cmd_list);
+
+
+/* client request rule */
+int vc_info_parser_set_demandable_client(const char* filepath);
+
+int vc_info_parser_get_demandable_clients(GSList** client_list);
+
+
+/* Result info */
+int vc_info_parser_set_result(const char* result_text, int event, const char* msg, vc_cmd_list_h vc_cmd_list, bool exclusive);
+
+int vc_info_parser_get_result(char** result_text, int* event, char** result_message, int pid, vc_cmd_list_h vc_cmd_list, bool exclusive);
+
+int vc_info_parser_unset_result(bool exclusive);
+
+int vc_info_parser_get_result_pid_list(GSList** pid_list);
+
+
+/* Client info */
+int vc_info_parser_set_client_info(GSList* client_info_list);
+
+int vc_info_parser_get_client_info(GSList** client_info_list);
+
+
+/* for debug */
+int __vc_cmd_parser_print_commands(GSList* cmd_list);
+
+int __vc_info_parser_print_results(GSList* result_list);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_CMD_PARSER_H_ */
diff --git a/common/vc_main.h b/common/vc_main.h
new file mode 100644 (file)
index 0000000..b94c446
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#ifndef __VC_MAIN_H_
+#define __VC_MAIN_H_
+
+#include <dbus/dbus.h>
+#include <dlog.h>
+#include <Ecore.h>
+#include <Ecore_X.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <string.h>
+#include <unistd.h>
+
+#include "vc_defs.h"
+#include "voice_control_common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define TAG_VCC                "vcc"           /* Normal client log tag */
+#define TAG_VCW                "vcw"           /* Widget client log tag */
+#define TAG_VCM                "vcm"           /* Manager client log tag */
+#define TAG_VCS                "vcsetting"     /* Setting client log tag */
+#define TAG_VCINFO     "vcinfo"        /* info lib log tag */
+#define TAG_VCCONFIG   "vcinfo"        /* config lib log tag */
+#define TAG_VCCMD      "vccmd"         /* Command log tag */
+
+/** 
+* @brief A structure of handle for identification
+*/
+struct vc_s {
+       int handle;
+};
+
+typedef struct vc_s *vc_h;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VC_CLIENT_H_ */
diff --git a/doc/doxyfile b/doc/doxyfile
new file mode 100644 (file)
index 0000000..68061dd
--- /dev/null
@@ -0,0 +1,2373 @@
+# Doxyfile 1.8.7
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project.
+#
+# All text after a double hash (##) is considered a comment and is placed in
+# front of the TAG it is preceding.
+#
+# All text after a single hash (#) is considered a comment and will be ignored.
+# The format is:
+# TAG = value [value, ...]
+# For lists, items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (\" \").
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file
+# that follow. The default is UTF-8 which is also the encoding used for all text
+# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv
+# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv
+# for the list of possible encodings.
+# The default value is: UTF-8.
+
+DOXYFILE_ENCODING      = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded by
+# double-quotes, unless you are using Doxywizard) that should identify the
+# project for which the documentation is generated. This name is used in the
+# title of most generated pages and in a few other places.
+# The default value is: My Project.
+
+PROJECT_NAME           = VoiceControl
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number. This
+# could be handy for archiving the generated documentation or if some version
+# control system is used.
+
+PROJECT_NUMBER         = 
+
+# Using the PROJECT_BRIEF tag one can provide an optional one line description
+# for a project that appears at the top of each page and should give viewer a
+# quick idea about the purpose of the project. Keep the description short.
+
+PROJECT_BRIEF          = 
+
+# With the PROJECT_LOGO tag one can specify an logo or icon that is included in
+# the documentation. The maximum height of the logo should not exceed 55 pixels
+# and the maximum width should not exceed 200 pixels. Doxygen will copy the logo
+# to the output directory.
+
+PROJECT_LOGO           = 
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) path
+# into which the generated documentation will be written. If a relative path is
+# entered, it will be relative to the location where doxygen was started. If
+# left blank the current directory will be used.
+
+OUTPUT_DIRECTORY       = .
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create 4096 sub-
+# directories (in 2 levels) under the output directory of each output format and
+# will distribute the generated files over these directories. Enabling this
+# option can be useful when feeding doxygen a huge amount of source files, where
+# putting all generated files in the same directory would otherwise causes
+# performance problems for the file system.
+# The default value is: NO.
+
+CREATE_SUBDIRS         = NO
+
+# If the ALLOW_UNICODE_NAMES tag is set to YES, doxygen will allow non-ASCII
+# characters to appear in the names of generated files. If set to NO, non-ASCII
+# characters will be escaped, for example _xE3_x81_x84 will be used for Unicode
+# U+3044.
+# The default value is: NO.
+
+ALLOW_UNICODE_NAMES    = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# Possible values are: Afrikaans, Arabic, Armenian, Brazilian, Catalan, Chinese,
+# Chinese-Traditional, Croatian, Czech, Danish, Dutch, English (United States),
+# Esperanto, Farsi (Persian), Finnish, French, German, Greek, Hungarian,
+# Indonesian, Italian, Japanese, Japanese-en (Japanese with English messages),
+# Korean, Korean-en (Korean with English messages), Latvian, Lithuanian,
+# Macedonian, Norwegian, Persian (Farsi), Polish, Portuguese, Romanian, Russian,
+# Serbian, Serbian-Cyrillic, Slovak, Slovene, Spanish, Swedish, Turkish,
+# Ukrainian and Vietnamese.
+# The default value is: English.
+
+OUTPUT_LANGUAGE        = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES doxygen will include brief member
+# descriptions after the members that are listed in the file and class
+# documentation (similar to Javadoc). Set to NO to disable this.
+# The default value is: YES.
+
+BRIEF_MEMBER_DESC      = YES
+
+# If the REPEAT_BRIEF tag is set to YES doxygen will prepend the brief
+# description of a member or function before the detailed description
+#
+# Note: If both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+# The default value is: YES.
+
+REPEAT_BRIEF           = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator that is
+# used to form the text in various listings. Each string in this list, if found
+# as the leading text of the brief description, will be stripped from the text
+# and the result, after processing the whole list, is used as the annotated
+# text. Otherwise, the brief description is used as-is. If left blank, the
+# following values are used ($name is automatically replaced with the name of
+# the entity):The $name class, The $name widget, The $name file, is, provides,
+# specifies, contains, represents, a, an and the.
+
+ABBREVIATE_BRIEF       = "The $name class" \
+                         "The $name widget" \
+                         "The $name file" \
+                         is \
+                         provides \
+                         specifies \
+                         contains \
+                         represents \
+                         a \
+                         an \
+                         the
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# doxygen will generate a detailed section even if there is only a brief
+# description.
+# The default value is: NO.
+
+ALWAYS_DETAILED_SEC    = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+# The default value is: NO.
+
+INLINE_INHERITED_MEMB  = NO
+
+# If the FULL_PATH_NAMES tag is set to YES doxygen will prepend the full path
+# before files name in the file list and in the header files. If set to NO the
+# shortest path that makes the file name unique will be used
+# The default value is: YES.
+
+FULL_PATH_NAMES        = YES
+
+# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path.
+# Stripping is only done if one of the specified strings matches the left-hand
+# part of the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the path to
+# strip.
+#
+# Note that you can specify absolute paths here, but also relative paths, which
+# will be relative from the directory where doxygen is started.
+# This tag requires that the tag FULL_PATH_NAMES is set to YES.
+
+STRIP_FROM_PATH        = 
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of the
+# path mentioned in the documentation of a class, which tells the reader which
+# header file to include in order to use a class. If left blank only the name of
+# the header file containing the class definition is used. Otherwise one should
+# specify the list of include paths that are normally passed to the compiler
+# using the -I flag.
+
+STRIP_FROM_INC_PATH    = 
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter (but
+# less readable) file names. This can be useful is your file systems doesn't
+# support long names like on DOS, Mac, or CD-ROM.
+# The default value is: NO.
+
+SHORT_NAMES            = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then doxygen will interpret the
+# first line (until the first dot) of a Javadoc-style comment as the brief
+# description. If set to NO, the Javadoc-style will behave just like regular Qt-
+# style comments (thus requiring an explicit @brief command for a brief
+# description.)
+# The default value is: NO.
+
+JAVADOC_AUTOBRIEF      = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
+# line (until the first dot) of a Qt-style comment as the brief description. If
+# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
+# requiring an explicit \brief command for a brief description.)
+# The default value is: NO.
+
+QT_AUTOBRIEF           = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make doxygen treat a
+# multi-line C++ special comment block (i.e. a block of //! or /// comments) as
+# a brief description. This used to be the default behavior. The new default is
+# to treat a multi-line C++ comment block as a detailed description. Set this
+# tag to YES if you prefer the old behavior instead.
+#
+# Note that setting this tag to YES also means that rational rose comments are
+# not recognized any more.
+# The default value is: NO.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the INHERIT_DOCS tag is set to YES then an undocumented member inherits the
+# documentation from any documented member that it re-implements.
+# The default value is: YES.
+
+INHERIT_DOCS           = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce a
+# new page for each member. If set to NO, the documentation of a member will be
+# part of the file/class/namespace that contains it.
+# The default value is: NO.
+
+SEPARATE_MEMBER_PAGES  = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab. Doxygen
+# uses this value to replace tabs by spaces in code fragments.
+# Minimum value: 1, maximum value: 16, default value: 4.
+
+TAB_SIZE               = 8
+
+# This tag can be used to specify a number of aliases that act as commands in
+# the documentation. An alias has the form:
+# name=value
+# For example adding
+# "sideeffect=@par Side Effects:\n"
+# will allow you to put the command \sideeffect (or @sideeffect) in the
+# documentation, which will result in a user-defined paragraph with heading
+# "Side Effects:". You can put \n's in the value part of an alias to insert
+# newlines.
+
+ALIASES                = 
+
+# This tag can be used to specify a number of word-keyword mappings (TCL only).
+# A mapping has the form "name=value". For example adding "class=itcl::class"
+# will allow you to use the command class in the itcl::class meaning.
+
+TCL_SUBST              = 
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C sources
+# only. Doxygen will then generate output that is more tailored for C. For
+# instance, some of the names that are used will be different. The list of all
+# members will be omitted, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_FOR_C  = YES
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java or
+# Python sources only. Doxygen will then generate output that is more tailored
+# for that language. For instance, namespaces will be presented as packages,
+# qualified scopes will look different, etc.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_JAVA   = NO
+
+# Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran
+# sources. Doxygen will then generate output that is tailored for Fortran.
+# The default value is: NO.
+
+OPTIMIZE_FOR_FORTRAN   = NO
+
+# Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL
+# sources. Doxygen will then generate output that is tailored for VHDL.
+# The default value is: NO.
+
+OPTIMIZE_OUTPUT_VHDL   = NO
+
+# Doxygen selects the parser to use depending on the extension of the files it
+# parses. With this tag you can assign which parser to use for a given
+# extension. Doxygen has a built-in mapping, but you can override or extend it
+# using this tag. The format is ext=language, where ext is a file extension, and
+# language is one of the parsers supported by doxygen: IDL, Java, Javascript,
+# C#, C, C++, D, PHP, Objective-C, Python, Fortran (fixed format Fortran:
+# FortranFixed, free formatted Fortran: FortranFree, unknown formatted Fortran:
+# Fortran. In the later case the parser tries to guess whether the code is fixed
+# or free formatted code, this is the default for Fortran type files), VHDL. For
+# instance to make doxygen treat .inc files as Fortran files (default is PHP),
+# and .f files as C (default is Fortran), use: inc=Fortran f=C.
+#
+# Note For files without extension you can use no_extension as a placeholder.
+#
+# Note that for custom extensions you also need to set FILE_PATTERNS otherwise
+# the files are not read by doxygen.
+
+EXTENSION_MAPPING      = 
+
+# If the MARKDOWN_SUPPORT tag is enabled then doxygen pre-processes all comments
+# according to the Markdown format, which allows for more readable
+# documentation. See http://daringfireball.net/projects/markdown/ for details.
+# The output of markdown processing is further processed by doxygen, so you can
+# mix doxygen, HTML, and XML commands with Markdown formatting. Disable only in
+# case of backward compatibilities issues.
+# The default value is: YES.
+
+MARKDOWN_SUPPORT       = YES
+
+# When enabled doxygen tries to link words that correspond to documented
+# classes, or namespaces to their corresponding documentation. Such a link can
+# be prevented in individual cases by by putting a % sign in front of the word
+# or globally by setting AUTOLINK_SUPPORT to NO.
+# The default value is: YES.
+
+AUTOLINK_SUPPORT       = YES
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want
+# to include (a tag file for) the STL sources as input, then you should set this
+# tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string);
+# versus func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+# The default value is: NO.
+
+BUILTIN_STL_SUPPORT    = NO
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+# The default value is: NO.
+
+CPP_CLI_SUPPORT        = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip (see:
+# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen
+# will parse them like normal C++ but will assume all classes use public instead
+# of private inheritance when no explicit protection keyword is present.
+# The default value is: NO.
+
+SIP_SUPPORT            = NO
+
+# For Microsoft's IDL there are propget and propput attributes to indicate
+# getter and setter methods for a property. Setting this option to YES will make
+# doxygen to replace the get and set methods by a property in the documentation.
+# This will only work if the methods are indeed getting or setting a simple
+# type. If this is not the case, or you want to show the methods anyway, you
+# should set this option to NO.
+# The default value is: YES.
+
+IDL_PROPERTY_SUPPORT   = YES
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+# The default value is: NO.
+
+DISTRIBUTE_GROUP_DOC   = NO
+
+# Set the SUBGROUPING tag to YES to allow class member groups of the same type
+# (for instance a group of public functions) to be put as a subgroup of that
+# type (e.g. under the Public Functions section). Set it to NO to prevent
+# subgrouping. Alternatively, this can be done per class using the
+# \nosubgrouping command.
+# The default value is: YES.
+
+SUBGROUPING            = YES
+
+# When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and unions
+# are shown inside the group in which they are included (e.g. using \ingroup)
+# instead of on a separate page (for HTML and Man pages) or section (for LaTeX
+# and RTF).
+#
+# Note that this feature does not work in combination with
+# SEPARATE_MEMBER_PAGES.
+# The default value is: NO.
+
+INLINE_GROUPED_CLASSES = NO
+
+# When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and unions
+# with only public data fields or simple typedef fields will be shown inline in
+# the documentation of the scope in which they are defined (i.e. file,
+# namespace, or group documentation), provided this scope is documented. If set
+# to NO, structs, classes, and unions are shown on a separate page (for HTML and
+# Man pages) or section (for LaTeX and RTF).
+# The default value is: NO.
+
+INLINE_SIMPLE_STRUCTS  = NO
+
+# When TYPEDEF_HIDES_STRUCT tag is enabled, a typedef of a struct, union, or
+# enum is documented as struct, union, or enum with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically be
+# useful for C code in case the coding convention dictates that all compound
+# types are typedef'ed and only the typedef is referenced, never the tag name.
+# The default value is: NO.
+
+TYPEDEF_HIDES_STRUCT   = NO
+
+# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This
+# cache is used to resolve symbols given their name and scope. Since this can be
+# an expensive process and often the same symbol appears multiple times in the
+# code, doxygen keeps a cache of pre-resolved symbols. If the cache is too small
+# doxygen will become slower. If the cache is too large, memory is wasted. The
+# cache size is given by this formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range
+# is 0..9, the default is 0, corresponding to a cache size of 2^16=65536
+# symbols. At the end of a run doxygen will report the cache usage and suggest
+# the optimal cache size from a speed point of view.
+# Minimum value: 0, maximum value: 9, default value: 0.
+
+LOOKUP_CACHE_SIZE      = 0
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available. Private
+# class members and static file members will be hidden unless the
+# EXTRACT_PRIVATE respectively EXTRACT_STATIC tags are set to YES.
+# Note: This will also disable the warnings about undocumented members that are
+# normally produced when WARNINGS is set to YES.
+# The default value is: NO.
+
+EXTRACT_ALL            = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class will
+# be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PRIVATE        = NO
+
+# If the EXTRACT_PACKAGE tag is set to YES all members with package or internal
+# scope will be included in the documentation.
+# The default value is: NO.
+
+EXTRACT_PACKAGE        = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file will be
+# included in the documentation.
+# The default value is: NO.
+
+EXTRACT_STATIC         = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) defined
+# locally in source files will be included in the documentation. If set to NO
+# only classes defined in header files are included. Does not have any effect
+# for Java sources.
+# The default value is: YES.
+
+EXTRACT_LOCAL_CLASSES  = YES
+
+# This flag is only useful for Objective-C code. When set to YES local methods,
+# which are defined in the implementation section but not in the interface are
+# included in the documentation. If set to NO only methods in the interface are
+# included.
+# The default value is: NO.
+
+EXTRACT_LOCAL_METHODS  = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be
+# extracted and appear in the documentation as a namespace called
+# 'anonymous_namespace{file}', where file will be replaced with the base name of
+# the file that contains the anonymous namespace. By default anonymous namespace
+# are hidden.
+# The default value is: NO.
+
+EXTRACT_ANON_NSPACES   = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, doxygen will hide all
+# undocumented members inside documented classes or files. If set to NO these
+# members will be included in the various overviews, but no documentation
+# section is generated. This option has no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_MEMBERS     = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy. If set
+# to NO these classes will be included in the various overviews. This option has
+# no effect if EXTRACT_ALL is enabled.
+# The default value is: NO.
+
+HIDE_UNDOC_CLASSES     = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend
+# (class|struct|union) declarations. If set to NO these declarations will be
+# included in the documentation.
+# The default value is: NO.
+
+HIDE_FRIEND_COMPOUNDS  = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any
+# documentation blocks found inside the body of a function. If set to NO these
+# blocks will be appended to the function's detailed documentation block.
+# The default value is: NO.
+
+HIDE_IN_BODY_DOCS      = NO
+
+# The INTERNAL_DOCS tag determines if documentation that is typed after a
+# \internal command is included. If the tag is set to NO then the documentation
+# will be excluded. Set it to YES to include the internal documentation.
+# The default value is: NO.
+
+INTERNAL_DOCS          = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file
+# names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+# The default value is: system dependent.
+
+CASE_SENSE_NAMES       = NO
+
+# If the HIDE_SCOPE_NAMES tag is set to NO then doxygen will show members with
+# their full class and namespace scopes in the documentation. If set to YES the
+# scope will be hidden.
+# The default value is: NO.
+
+HIDE_SCOPE_NAMES       = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES then doxygen will put a list of
+# the files that are included by a file in the documentation of that file.
+# The default value is: YES.
+
+SHOW_INCLUDE_FILES     = YES
+
+# If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each
+# grouped member an include statement to the documentation, telling the reader
+# which file to include in order to use the member.
+# The default value is: NO.
+
+SHOW_GROUPED_MEMB_INC  = NO
+
+# If the FORCE_LOCAL_INCLUDES tag is set to YES then doxygen will list include
+# files with double quotes in the documentation rather than with sharp brackets.
+# The default value is: NO.
+
+FORCE_LOCAL_INCLUDES   = NO
+
+# If the INLINE_INFO tag is set to YES then a tag [inline] is inserted in the
+# documentation for inline members.
+# The default value is: YES.
+
+INLINE_INFO            = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES then doxygen will sort the
+# (detailed) documentation of file and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order.
+# The default value is: YES.
+
+SORT_MEMBER_DOCS       = YES
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief
+# descriptions of file, namespace and class members alphabetically by member
+# name. If set to NO the members will appear in declaration order. Note that
+# this will also influence the order of the classes in the class list.
+# The default value is: NO.
+
+SORT_BRIEF_DOCS        = NO
+
+# If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen will sort the
+# (brief and detailed) documentation of class members so that constructors and
+# destructors are listed first. If set to NO the constructors will appear in the
+# respective orders defined by SORT_BRIEF_DOCS and SORT_MEMBER_DOCS.
+# Note: If SORT_BRIEF_DOCS is set to NO this option is ignored for sorting brief
+# member documentation.
+# Note: If SORT_MEMBER_DOCS is set to NO this option is ignored for sorting
+# detailed member documentation.
+# The default value is: NO.
+
+SORT_MEMBERS_CTORS_1ST = NO
+
+# If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy
+# of group names into alphabetical order. If set to NO the group names will
+# appear in their defined order.
+# The default value is: NO.
+
+SORT_GROUP_NAMES       = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be sorted by
+# fully-qualified names, including namespaces. If set to NO, the class list will
+# be sorted only by class name, not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the alphabetical
+# list.
+# The default value is: NO.
+
+SORT_BY_SCOPE_NAME     = NO
+
+# If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to do proper
+# type resolution of all parameters of a function it will reject a match between
+# the prototype and the implementation of a member function even if there is
+# only one candidate or it is obvious which candidate to choose by doing a
+# simple string match. By disabling STRICT_PROTO_MATCHING doxygen will still
+# accept a match between prototype and implementation in such cases.
+# The default value is: NO.
+
+STRICT_PROTO_MATCHING  = NO
+
+# The GENERATE_TODOLIST tag can be used to enable ( YES) or disable ( NO) the
+# todo list. This list is created by putting \todo commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TODOLIST      = YES
+
+# The GENERATE_TESTLIST tag can be used to enable ( YES) or disable ( NO) the
+# test list. This list is created by putting \test commands in the
+# documentation.
+# The default value is: YES.
+
+GENERATE_TESTLIST      = YES
+
+# The GENERATE_BUGLIST tag can be used to enable ( YES) or disable ( NO) the bug
+# list. This list is created by putting \bug commands in the documentation.
+# The default value is: YES.
+
+GENERATE_BUGLIST       = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable ( YES) or disable ( NO)
+# the deprecated list. This list is created by putting \deprecated commands in
+# the documentation.
+# The default value is: YES.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional documentation
+# sections, marked by \if <section_label> ... \endif and \cond <section_label>
+# ... \endcond blocks.
+
+ENABLED_SECTIONS       = 
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines that the
+# initial value of a variable or macro / define can have for it to appear in the
+# documentation. If the initializer consists of more lines than specified here
+# it will be hidden. Use a value of 0 to hide initializers completely. The
+# appearance of the value of individual variables and macros / defines can be
+# controlled using \showinitializer or \hideinitializer command in the
+# documentation regardless of this setting.
+# Minimum value: 0, maximum value: 10000, default value: 30.
+
+MAX_INITIALIZER_LINES  = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated at
+# the bottom of the documentation of classes and structs. If set to YES the list
+# will mention the files that were used to generate the documentation.
+# The default value is: YES.
+
+SHOW_USED_FILES        = YES
+
+# Set the SHOW_FILES tag to NO to disable the generation of the Files page. This
+# will remove the Files entry from the Quick Index and from the Folder Tree View
+# (if specified).
+# The default value is: YES.
+
+SHOW_FILES             = YES
+
+# Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces
+# page. This will remove the Namespaces entry from the Quick Index and from the
+# Folder Tree View (if specified).
+# The default value is: YES.
+
+SHOW_NAMESPACES        = YES
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from
+# the version control system). Doxygen will invoke the program by executing (via
+# popen()) the command command input-file, where command is the value of the
+# FILE_VERSION_FILTER tag, and input-file is the name of an input file provided
+# by doxygen. Whatever the program writes to standard output is used as the file
+# version. For an example see the documentation.
+
+FILE_VERSION_FILTER    = 
+
+# The LAYOUT_FILE tag can be used to specify a layout file which will be parsed
+# by doxygen. The layout file controls the global structure of the generated
+# output files in an output format independent way. To create the layout file
+# that represents doxygen's defaults, run doxygen with the -l option. You can
+# optionally specify a file name after the option, if omitted DoxygenLayout.xml
+# will be used as the name of the layout file.
+#
+# Note that if you run doxygen from a directory containing a file called
+# DoxygenLayout.xml, doxygen will parse it automatically even if the LAYOUT_FILE
+# tag is left empty.
+
+LAYOUT_FILE            = 
+
+# The CITE_BIB_FILES tag can be used to specify one or more bib files containing
+# the reference definitions. This must be a list of .bib files. The .bib
+# extension is automatically appended if omitted. This requires the bibtex tool
+# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info.
+# For LaTeX the style of the bibliography can be controlled using
+# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the
+# search path. Do not use file names with spaces, bibtex cannot handle them. See
+# also \cite for info how to create references.
+
+CITE_BIB_FILES         = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated to
+# standard output by doxygen. If QUIET is set to YES this implies that the
+# messages are off.
+# The default value is: NO.
+
+QUIET                  = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated to standard error ( stderr) by doxygen. If WARNINGS is set to YES
+# this implies that the warnings are on.
+#
+# Tip: Turn warnings on while writing the documentation.
+# The default value is: YES.
+
+WARNINGS               = YES
+
+# If the WARN_IF_UNDOCUMENTED tag is set to YES, then doxygen will generate
+# warnings for undocumented members. If EXTRACT_ALL is set to YES then this flag
+# will automatically be disabled.
+# The default value is: YES.
+
+WARN_IF_UNDOCUMENTED   = YES
+
+# If the WARN_IF_DOC_ERROR tag is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some parameters
+# in a documented function, or documenting parameters that don't exist or using
+# markup commands wrongly.
+# The default value is: YES.
+
+WARN_IF_DOC_ERROR      = YES
+
+# This WARN_NO_PARAMDOC option can be enabled to get warnings for functions that
+# are documented, but have no documentation for their parameters or return
+# value. If set to NO doxygen will only warn about wrong or incomplete parameter
+# documentation, but not about the absence of documentation.
+# The default value is: NO.
+
+WARN_NO_PARAMDOC       = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that doxygen
+# can produce. The string should contain the $file, $line, and $text tags, which
+# will be replaced by the file and line number from which the warning originated
+# and the warning text. Optionally the format may contain $version, which will
+# be replaced by the version of the file (if it could be obtained via
+# FILE_VERSION_FILTER)
+# The default value is: $file:$line: $text.
+
+WARN_FORMAT            = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning and error
+# messages should be written. If left blank the output is written to standard
+# error (stderr).
+
+WARN_LOGFILE           = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag is used to specify the files and/or directories that contain
+# documented source files. You may enter file names like myfile.cpp or
+# directories like /usr/src/myproject. Separate the files or directories with
+# spaces.
+# Note: If this tag is empty the current directory is searched.
+
+INPUT                  = ../include/voice_control.h \
+                         ../include/voice_control_command.h \
+                         ../include/voice_control_common.h \
+                         uix_vc_doc.h
+
+# This tag can be used to specify the character encoding of the source files
+# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
+# libiconv (or the iconv built into libc) for the transcoding. See the libiconv
+# documentation (see: http://www.gnu.org/software/libiconv) for the list of
+# possible encodings.
+# The default value is: UTF-8.
+
+INPUT_ENCODING         = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard patterns (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank the
+# following patterns are tested:*.c, *.cc, *.cxx, *.cpp, *.c++, *.java, *.ii,
+# *.ixx, *.ipp, *.i++, *.inl, *.idl, *.ddl, *.odl, *.h, *.hh, *.hxx, *.hpp,
+# *.h++, *.cs, *.d, *.php, *.php4, *.php5, *.phtml, *.inc, *.m, *.markdown,
+# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
+# *.qsf, *.as and *.js.
+
+FILE_PATTERNS          = *.c \
+                         *.cc \
+                         *.cxx \
+                         *.cpp \
+                         *.c++ \
+                         *.d \
+                         *.java \
+                         *.ii \
+                         *.ixx \
+                         *.ipp \
+                         *.i++ \
+                         *.inl \
+                         *.h \
+                         *.hh \
+                         *.hxx \
+                         *.hpp \
+                         *.h++ \
+                         *.idl \
+                         *.odl \
+                         *.cs \
+                         *.php \
+                         *.php3 \
+                         *.inc \
+                         *.m \
+                         *.mm \
+                         *.dox \
+                         *.py \
+                         *.f90 \
+                         *.f \
+                         *.vhd \
+                         *.vhdl
+
+# The RECURSIVE tag can be used to specify whether or not subdirectories should
+# be searched for input files as well.
+# The default value is: NO.
+
+RECURSIVE              = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should be
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+#
+# Note that relative paths are relative to the directory from which doxygen is
+# run.
+
+EXCLUDE                = 
+
+# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or
+# directories that are symbolic links (a Unix file system feature) are excluded
+# from the input.
+# The default value is: NO.
+
+EXCLUDE_SYMLINKS       = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories.
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories for example use the pattern */test/*
+
+EXCLUDE_PATTERNS       = 
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the
+# output. The symbol name can be a fully qualified name, a word, or if the
+# wildcard * is used, a substring. Examples: ANamespace, AClass,
+# AClass::ANamespace, ANamespace::*Test
+#
+# Note that the wildcards are matched against the file with absolute path, so to
+# exclude all test directories use the pattern */test/*
+
+EXCLUDE_SYMBOLS        = 
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or directories
+# that contain example code fragments that are included (see the \include
+# command).
+
+EXAMPLE_PATH           = 
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
+# *.h) to filter out the source-files in the directories. If left blank all
+# files are included.
+
+EXAMPLE_PATTERNS       = *
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude commands
+# irrespective of the value of the RECURSIVE tag.
+# The default value is: NO.
+
+EXAMPLE_RECURSIVE      = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or directories
+# that contain images that are to be included in the documentation (see the
+# \image command).
+
+IMAGE_PATH             = images/capi_uix_voice_control_state_diagram.png \
+                         images/capi_uix_voice_control_service_state_diagram.png
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command:
+#
+# <filter> <input-file>
+#
+# where <filter> is the value of the INPUT_FILTER tag, and <input-file> is the
+# name of an input file. Doxygen will then use the output that the filter
+# program writes to standard output. If FILTER_PATTERNS is specified, this tag
+# will be ignored.
+#
+# Note that the filter must not add or remove lines; it is applied before the
+# code is scanned, but not when the output code is generated. If lines are added
+# or removed, the anchors will not be placed correctly.
+
+INPUT_FILTER           = 
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form: pattern=filter
+# (like *.cpp=my_cpp_filter). See INPUT_FILTER for further information on how
+# filters are used. If the FILTER_PATTERNS tag is empty or if none of the
+# patterns match the file name, INPUT_FILTER is applied.
+
+FILTER_PATTERNS        = 
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER ) will also be used to filter the input files that are used for
+# producing the source files to browse (i.e. when SOURCE_BROWSER is set to YES).
+# The default value is: NO.
+
+FILTER_SOURCE_FILES    = NO
+
+# The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file
+# pattern. A pattern will override the setting for FILTER_PATTERN (if any) and
+# it is also possible to disable source filtering for a specific pattern using
+# *.ext= (so without naming a filter).
+# This tag requires that the tag FILTER_SOURCE_FILES is set to YES.
+
+FILTER_SOURCE_PATTERNS = 
+
+# If the USE_MDFILE_AS_MAINPAGE tag refers to the name of a markdown file that
+# is part of the input, its contents will be placed on the main page
+# (index.html). This can be useful if you have a project on for instance GitHub
+# and want to reuse the introduction page also for the doxygen output.
+
+USE_MDFILE_AS_MAINPAGE = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will be
+# generated. Documented entities will be cross-referenced with these sources.
+#
+# Note: To get rid of all source code in the generated output, make sure that
+# also VERBATIM_HEADERS is set to NO.
+# The default value is: NO.
+
+SOURCE_BROWSER         = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body of functions,
+# classes and enums directly into the documentation.
+# The default value is: NO.
+
+INLINE_SOURCES         = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES will instruct doxygen to hide any
+# special comment blocks from generated source code fragments. Normal C, C++ and
+# Fortran comments will always remain visible.
+# The default value is: YES.
+
+STRIP_CODE_COMMENTS    = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES then for each documented
+# function all documented functions referencing it will be listed.
+# The default value is: NO.
+
+REFERENCED_BY_RELATION = NO
+
+# If the REFERENCES_RELATION tag is set to YES then for each documented function
+# all documented entities called/used by that function will be listed.
+# The default value is: NO.
+
+REFERENCES_RELATION    = NO
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES and SOURCE_BROWSER tag is set
+# to YES, then the hyperlinks from functions in REFERENCES_RELATION and
+# REFERENCED_BY_RELATION lists will link to the source code. Otherwise they will
+# link to the documentation.
+# The default value is: YES.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If SOURCE_TOOLTIPS is enabled (the default) then hovering a hyperlink in the
+# source code will show a tooltip with additional information such as prototype,
+# brief description and links to the definition and documentation. Since this
+# will make the HTML file larger and loading of large files a bit slower, you
+# can opt to disable this feature.
+# The default value is: YES.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+SOURCE_TOOLTIPS        = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code will
+# point to the HTML generated by the htags(1) tool instead of doxygen built-in
+# source browser. The htags tool is part of GNU's global source tagging system
+# (see http://www.gnu.org/software/global/global.html). You will need version
+# 4.8.6 or higher.
+#
+# To use it do the following:
+# - Install the latest version of global
+# - Enable SOURCE_BROWSER and USE_HTAGS in the config file
+# - Make sure the INPUT points to the root of the source tree
+# - Run doxygen as normal
+#
+# Doxygen will invoke htags (and that will in turn invoke gtags), so these
+# tools must be available from the command line (i.e. in the search path).
+#
+# The result: instead of the source browser generated by doxygen, the links to
+# source code will now point to the output of htags.
+# The default value is: NO.
+# This tag requires that the tag SOURCE_BROWSER is set to YES.
+
+USE_HTAGS              = NO
+
+# If the VERBATIM_HEADERS tag is set the YES then doxygen will generate a
+# verbatim copy of the header file for each class for which an include is
+# specified. Set to NO to disable this.
+# See also: Section \class.
+# The default value is: YES.
+
+VERBATIM_HEADERS       = YES
+
+# If the CLANG_ASSISTED_PARSING tag is set to YES, then doxygen will use the
+# clang parser (see: http://clang.llvm.org/) for more accurate parsing at the
+# cost of reduced performance. This can be particularly helpful with template
+# rich C++ code for which doxygen's built-in parser lacks the necessary type
+# information.
+# Note: The availability of this option depends on whether or not doxygen was
+# compiled with the --with-libclang option.
+# The default value is: NO.
+
+CLANG_ASSISTED_PARSING = NO
+
+# If clang assisted parsing is enabled you can provide the compiler with command
+# line options that you would normally use when invoking the compiler. Note that
+# the include paths will already be set by doxygen for the files and directories
+# specified with INPUT and INCLUDE_PATH.
+# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES.
+
+CLANG_OPTIONS          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index of all
+# compounds will be generated. Enable this if the project contains a lot of
+# classes, structs, unions or interfaces.
+# The default value is: YES.
+
+ALPHABETICAL_INDEX     = YES
+
+# The COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns in
+# which the alphabetical index list will be split.
+# Minimum value: 1, maximum value: 20, default value: 5.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+COLS_IN_ALPHA_INDEX    = 5
+
+# In case all classes in a project start with a common prefix, all classes will
+# be put under the same header in the alphabetical index. The IGNORE_PREFIX tag
+# can be used to specify a prefix (or a list of prefixes) that should be ignored
+# while generating the index headers.
+# This tag requires that the tag ALPHABETICAL_INDEX is set to YES.
+
+IGNORE_PREFIX          = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES doxygen will generate HTML output
+# The default value is: YES.
+
+GENERATE_HTML          = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_OUTPUT            = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for each
+# generated HTML page (for example: .htm, .php, .asp).
+# The default value is: .html.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FILE_EXTENSION    = .html
+
+# The HTML_HEADER tag can be used to specify a user-defined HTML header file for
+# each generated HTML page. If the tag is left blank doxygen will generate a
+# standard header.
+#
+# To get valid HTML the header file that includes any scripts and style sheets
+# that doxygen needs, which is dependent on the configuration options used (e.g.
+# the setting GENERATE_TREEVIEW). It is highly recommended to start with a
+# default header using
+# doxygen -w html new_header.html new_footer.html new_stylesheet.css
+# YourConfigFile
+# and then modify the file new_header.html. See also section "Doxygen usage"
+# for information on how to generate the default header that doxygen normally
+# uses.
+# Note: The header is subject to change so you typically have to regenerate the
+# default header when upgrading to a newer version of doxygen. For a description
+# of the possible markers and block names see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_HEADER            = 
+
+# The HTML_FOOTER tag can be used to specify a user-defined HTML footer for each
+# generated HTML page. If the tag is left blank doxygen will generate a standard
+# footer. See HTML_HEADER for more information on how to generate a default
+# footer and what special commands can be used inside the footer. See also
+# section "Doxygen usage" for information on how to generate the default footer
+# that doxygen normally uses.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_FOOTER            = 
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading style
+# sheet that is used by each HTML page. It can be used to fine-tune the look of
+# the HTML output. If left blank doxygen will generate a default style sheet.
+# See also section "Doxygen usage" for information on how to generate the style
+# sheet that doxygen normally uses.
+# Note: It is recommended to use HTML_EXTRA_STYLESHEET instead of this tag, as
+# it is more robust and this tag (HTML_STYLESHEET) will in the future become
+# obsolete.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_STYLESHEET        = 
+
+# The HTML_EXTRA_STYLESHEET tag can be used to specify an additional user-
+# defined cascading style sheet that is included after the standard style sheets
+# created by doxygen. Using this option one can overrule certain style aspects.
+# This is preferred over using HTML_STYLESHEET since it does not replace the
+# standard style sheet and is therefor more robust against future updates.
+# Doxygen will copy the style sheet file to the output directory. For an example
+# see the documentation.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_STYLESHEET  = 
+
+# The HTML_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the HTML output directory. Note
+# that these files will be copied to the base HTML output directory. Use the
+# $relpath^ marker in the HTML_HEADER and/or HTML_FOOTER files to load these
+# files. In the HTML_STYLESHEET file, use the file name only. Also note that the
+# files will be copied as-is; there are no commands or markers available.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_EXTRA_FILES       = 
+
+# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen
+# will adjust the colors in the stylesheet and background images according to
+# this color. Hue is specified as an angle on a colorwheel, see
+# http://en.wikipedia.org/wiki/Hue for more information. For instance the value
+# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300
+# purple, and 360 is red again.
+# Minimum value: 0, maximum value: 359, default value: 220.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_HUE    = 220
+
+# The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of the colors
+# in the HTML output. For a value of 0 the output will use grayscales only. A
+# value of 255 will produce the most vivid colors.
+# Minimum value: 0, maximum value: 255, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_SAT    = 100
+
+# The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to the
+# luminance component of the colors in the HTML output. Values below 100
+# gradually make the output lighter, whereas values above 100 make the output
+# darker. The value divided by 100 is the actual gamma applied, so 80 represents
+# a gamma of 0.8, The value 220 represents a gamma of 2.2, and 100 does not
+# change the gamma.
+# Minimum value: 40, maximum value: 240, default value: 80.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_COLORSTYLE_GAMMA  = 80
+
+# If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML
+# page will contain the date and time when the page was generated. Setting this
+# to NO can help when comparing the output of multiple runs.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_TIMESTAMP         = YES
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_DYNAMIC_SECTIONS  = NO
+
+# With HTML_INDEX_NUM_ENTRIES one can control the preferred number of entries
+# shown in the various tree structured indices initially; the user can expand
+# and collapse entries dynamically later on. Doxygen will expand the tree to
+# such a level that at most the specified number of entries are visible (unless
+# a fully collapsed tree already exceeds this amount). So setting the number of
+# entries 1 will produce a full collapsed tree by default. 0 is a special value
+# representing an infinite number of entries and will result in a full expanded
+# tree by default.
+# Minimum value: 0, maximum value: 9999, default value: 100.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+HTML_INDEX_NUM_ENTRIES = 100
+
+# If the GENERATE_DOCSET tag is set to YES, additional index files will be
+# generated that can be used as input for Apple's Xcode 3 integrated development
+# environment (see: http://developer.apple.com/tools/xcode/), introduced with
+# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a
+# Makefile in the HTML output directory. Running make will produce the docset in
+# that directory and running make install will install the docset in
+# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at
+# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html
+# for more information.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_DOCSET        = NO
+
+# This tag determines the name of the docset feed. A documentation feed provides
+# an umbrella under which multiple documentation sets from a single provider
+# (such as a company or product suite) can be grouped.
+# The default value is: Doxygen generated docs.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_FEEDNAME        = "Doxygen generated docs"
+
+# This tag specifies a string that should uniquely identify the documentation
+# set bundle. This should be a reverse domain-name style string, e.g.
+# com.mycompany.MyDocSet. Doxygen will append .docset to the name.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_BUNDLE_ID       = org.doxygen.Project
+
+# The DOCSET_PUBLISHER_ID tag specifies a string that should uniquely identify
+# the documentation publisher. This should be a reverse domain-name style
+# string, e.g. com.mycompany.MyDocSet.documentation.
+# The default value is: org.doxygen.Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_ID    = org.doxygen.Publisher
+
+# The DOCSET_PUBLISHER_NAME tag identifies the documentation publisher.
+# The default value is: Publisher.
+# This tag requires that the tag GENERATE_DOCSET is set to YES.
+
+DOCSET_PUBLISHER_NAME  = Publisher
+
+# If the GENERATE_HTMLHELP tag is set to YES then doxygen generates three
+# additional HTML index files: index.hhp, index.hhc, and index.hhk. The
+# index.hhp is a project file that can be read by Microsoft's HTML Help Workshop
+# (see: http://www.microsoft.com/en-us/download/details.aspx?id=21138) on
+# Windows.
+#
+# The HTML Help Workshop contains a compiler that can convert all HTML output
+# generated by doxygen into a single compiled HTML file (.chm). Compiled HTML
+# files are now used as the Windows 98 help format, and will replace the old
+# Windows help format (.hlp) on all Windows platforms in the future. Compressed
+# HTML files also contain an index, a table of contents, and you can search for
+# words in the documentation. The HTML workshop also contains a viewer for
+# compressed HTML files.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_HTMLHELP      = NO
+
+# The CHM_FILE tag can be used to specify the file name of the resulting .chm
+# file. You can add a path in front of the file if the result should not be
+# written to the html output directory.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_FILE               = 
+
+# The HHC_LOCATION tag can be used to specify the location (absolute path
+# including file name) of the HTML help compiler ( hhc.exe). If non-empty
+# doxygen will try to run the HTML help compiler on the generated index.hhp.
+# The file has to be specified with full path.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+HHC_LOCATION           = 
+
+# The GENERATE_CHI flag controls if a separate .chi index file is generated (
+# YES) or that it should be included in the master .chm file ( NO).
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+GENERATE_CHI           = NO
+
+# The CHM_INDEX_ENCODING is used to encode HtmlHelp index ( hhk), content ( hhc)
+# and project file content.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+CHM_INDEX_ENCODING     = 
+
+# The BINARY_TOC flag controls whether a binary table of contents is generated (
+# YES) or a normal table of contents ( NO) in the .chm file. Furthermore it
+# enables the Previous and Next buttons.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+BINARY_TOC             = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members to
+# the table of contents of the HTML help documentation and to the tree view.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTMLHELP is set to YES.
+
+TOC_EXPAND             = NO
+
+# If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and
+# QHP_VIRTUAL_FOLDER are set, an additional index file will be generated that
+# can be used as input for Qt's qhelpgenerator to generate a Qt Compressed Help
+# (.qch) of the generated HTML documentation.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_QHP           = NO
+
+# If the QHG_LOCATION tag is specified, the QCH_FILE tag can be used to specify
+# the file name of the resulting .qch file. The path specified is relative to
+# the HTML output folder.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QCH_FILE               = 
+
+# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help
+# Project output. For more information please see Qt Help Project / Namespace
+# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace).
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_NAMESPACE          = org.doxygen.Project
+
+# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt
+# Help Project output. For more information please see Qt Help Project / Virtual
+# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual-
+# folders).
+# The default value is: doc.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_VIRTUAL_FOLDER     = doc
+
+# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom
+# filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_NAME   = 
+
+# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the
+# custom filter to add. For more information please see Qt Help Project / Custom
+# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom-
+# filters).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_CUST_FILTER_ATTRS  = 
+
+# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this
+# project's filter section matches. Qt Help Project / Filter Attributes (see:
+# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes).
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHP_SECT_FILTER_ATTRS  = 
+
+# The QHG_LOCATION tag can be used to specify the location of Qt's
+# qhelpgenerator. If non-empty doxygen will try to run qhelpgenerator on the
+# generated .qhp file.
+# This tag requires that the tag GENERATE_QHP is set to YES.
+
+QHG_LOCATION           = 
+
+# If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files will be
+# generated, together with the HTML files, they form an Eclipse help plugin. To
+# install this plugin and make it available under the help contents menu in
+# Eclipse, the contents of the directory containing the HTML and XML files needs
+# to be copied into the plugins directory of eclipse. The name of the directory
+# within the plugins directory should be the same as the ECLIPSE_DOC_ID value.
+# After copying Eclipse needs to be restarted before the help appears.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_ECLIPSEHELP   = NO
+
+# A unique identifier for the Eclipse help plugin. When installing the plugin
+# the directory name containing the HTML and XML files should also have this
+# name. Each documentation set should have its own identifier.
+# The default value is: org.doxygen.Project.
+# This tag requires that the tag GENERATE_ECLIPSEHELP is set to YES.
+
+ECLIPSE_DOC_ID         = org.doxygen.Project
+
+# If you want full control over the layout of the generated HTML pages it might
+# be necessary to disable the index and replace it with your own. The
+# DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) at top
+# of each HTML page. A value of NO enables the index and the value YES disables
+# it. Since the tabs in the index contain the same information as the navigation
+# tree, you can set this option to YES if you also set GENERATE_TREEVIEW to YES.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+DISABLE_INDEX          = NO
+
+# The GENERATE_TREEVIEW tag is used to specify whether a tree-like index
+# structure should be generated to display hierarchical information. If the tag
+# value is set to YES, a side panel will be generated containing a tree-like
+# index structure (just like the one that is generated for HTML Help). For this
+# to work a browser that supports JavaScript, DHTML, CSS and frames is required
+# (i.e. any modern browser). Windows users are probably better off using the
+# HTML help feature. Via custom stylesheets (see HTML_EXTRA_STYLESHEET) one can
+# further fine-tune the look of the index. As an example, the default style
+# sheet generated by doxygen has an example that shows how to put an image at
+# the root of the tree instead of the PROJECT_NAME. Since the tree basically has
+# the same information as the tab index, you could consider setting
+# DISABLE_INDEX to YES when enabling this option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+GENERATE_TREEVIEW      = NO
+
+# The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values that
+# doxygen will group on one line in the generated HTML documentation.
+#
+# Note that a value of 0 will completely suppress the enum values from appearing
+# in the overview section.
+# Minimum value: 0, maximum value: 20, default value: 4.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+ENUM_VALUES_PER_LINE   = 4
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be used
+# to set the initial width (in pixels) of the frame in which the tree is shown.
+# Minimum value: 0, maximum value: 1500, default value: 250.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+TREEVIEW_WIDTH         = 250
+
+# When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open links to
+# external symbols imported via tag files in a separate window.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+EXT_LINKS_IN_WINDOW    = NO
+
+# Use this tag to change the font size of LaTeX formulas included as images in
+# the HTML documentation. When you change the font size after a successful
+# doxygen run you need to manually remove any form_*.png images from the HTML
+# output directory to force them to be regenerated.
+# Minimum value: 8, maximum value: 50, default value: 10.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_FONTSIZE       = 10
+
+# Use the FORMULA_TRANPARENT tag to determine whether or not the images
+# generated for formulas are transparent PNGs. Transparent PNGs are not
+# supported properly for IE 6.0, but are supported on all modern browsers.
+#
+# Note that when changing this option you need to delete any form_*.png files in
+# the HTML output directory before the changes have effect.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+FORMULA_TRANSPARENT    = YES
+
+# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see
+# http://www.mathjax.org) which uses client side Javascript for the rendering
+# instead of using prerendered bitmaps. Use this if you do not have LaTeX
+# installed or if you want to formulas look prettier in the HTML output. When
+# enabled you may also need to install MathJax separately and configure the path
+# to it using the MATHJAX_RELPATH option.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+USE_MATHJAX            = NO
+
+# When MathJax is enabled you can set the default output format to be used for
+# the MathJax output. See the MathJax site (see:
+# http://docs.mathjax.org/en/latest/output.html) for more details.
+# Possible values are: HTML-CSS (which is slower, but has the best
+# compatibility), NativeMML (i.e. MathML) and SVG.
+# The default value is: HTML-CSS.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_FORMAT         = HTML-CSS
+
+# When MathJax is enabled you need to specify the location relative to the HTML
+# output directory using the MATHJAX_RELPATH option. The destination directory
+# should contain the MathJax.js script. For instance, if the mathjax directory
+# is located at the same level as the HTML output directory, then
+# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax
+# Content Delivery Network so you can quickly see the result without installing
+# MathJax. However, it is strongly recommended to install a local copy of
+# MathJax from http://www.mathjax.org before deployment.
+# The default value is: http://cdn.mathjax.org/mathjax/latest.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_RELPATH        = http://cdn.mathjax.org/mathjax/latest
+
+# The MATHJAX_EXTENSIONS tag can be used to specify one or more MathJax
+# extension names that should be enabled during MathJax rendering. For example
+# MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_EXTENSIONS     = 
+
+# The MATHJAX_CODEFILE tag can be used to specify a file with javascript pieces
+# of code that will be used on startup of the MathJax code. See the MathJax site
+# (see: http://docs.mathjax.org/en/latest/output.html) for more details. For an
+# example see the documentation.
+# This tag requires that the tag USE_MATHJAX is set to YES.
+
+MATHJAX_CODEFILE       = 
+
+# When the SEARCHENGINE tag is enabled doxygen will generate a search box for
+# the HTML output. The underlying search engine uses javascript and DHTML and
+# should work on any modern browser. Note that when using HTML help
+# (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets (GENERATE_DOCSET)
+# there is already a search function so this one should typically be disabled.
+# For large projects the javascript based search engine can be slow, then
+# enabling SERVER_BASED_SEARCH may provide a better solution. It is possible to
+# search using the keyboard; to jump to the search box use <access key> + S
+# (what the <access key> is depends on the OS and browser, but it is typically
+# <CTRL>, <ALT>/<option>, or both). Inside the search box use the <cursor down
+# key> to jump into the search results window, the results can be navigated
+# using the <cursor keys>. Press <Enter> to select an item or <escape> to cancel
+# the search. The filter options can be selected when the cursor is inside the
+# search box by pressing <Shift>+<cursor down>. Also here use the <cursor keys>
+# to select a filter and <Enter> or <escape> to activate or cancel the filter
+# option.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_HTML is set to YES.
+
+SEARCHENGINE           = YES
+
+# When the SERVER_BASED_SEARCH tag is enabled the search engine will be
+# implemented using a web server instead of a web client using Javascript. There
+# are two flavors of web server based searching depending on the EXTERNAL_SEARCH
+# setting. When disabled, doxygen will generate a PHP script for searching and
+# an index file used by the script. When EXTERNAL_SEARCH is enabled the indexing
+# and searching needs to be provided by external tools. See the section
+# "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SERVER_BASED_SEARCH    = NO
+
+# When EXTERNAL_SEARCH tag is enabled doxygen will no longer generate the PHP
+# script for searching. Instead the search results are written to an XML file
+# which needs to be processed by an external indexer. Doxygen will invoke an
+# external search engine pointed to by the SEARCHENGINE_URL option to obtain the
+# search results.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/).
+#
+# See the section "External Indexing and Searching" for details.
+# The default value is: NO.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH        = NO
+
+# The SEARCHENGINE_URL should point to a search engine hosted by a web server
+# which will return the search results when EXTERNAL_SEARCH is enabled.
+#
+# Doxygen ships with an example indexer ( doxyindexer) and search engine
+# (doxysearch.cgi) which are based on the open source search engine library
+# Xapian (see: http://xapian.org/). See the section "External Indexing and
+# Searching" for details.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHENGINE_URL       = 
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed
+# search data is written to a file for indexing by an external tool. With the
+# SEARCHDATA_FILE tag the name of this file can be specified.
+# The default file is: searchdata.xml.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+SEARCHDATA_FILE        = searchdata.xml
+
+# When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the
+# EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is
+# useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple
+# projects and redirect the results back to the right project.
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTERNAL_SEARCH_ID     = 
+
+# The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen
+# projects other than the one defined by this configuration file, but that are
+# all added to the same external search index. Each project needs to have a
+# unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id of
+# to a relative location where the documentation can be found. The format is:
+# EXTRA_SEARCH_MAPPINGS = tagname1=loc1 tagname2=loc2 ...
+# This tag requires that the tag SEARCHENGINE is set to YES.
+
+EXTRA_SEARCH_MAPPINGS  = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES doxygen will generate LaTeX output.
+# The default value is: YES.
+
+GENERATE_LATEX         = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_OUTPUT           = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked.
+#
+# Note that when enabling USE_PDFLATEX this option is only used for generating
+# bitmaps for formulas in the HTML output, but not in the Makefile that is
+# written to the output directory.
+# The default file is: latex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_CMD_NAME         = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to generate
+# index for LaTeX.
+# The default file is: makeindex.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+MAKEINDEX_CMD_NAME     = makeindex
+
+# If the COMPACT_LATEX tag is set to YES doxygen generates more compact LaTeX
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+COMPACT_LATEX          = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used by the
+# printer.
+# Possible values are: a4 (210 x 297 mm), letter (8.5 x 11 inches), legal (8.5 x
+# 14 inches) and executive (7.25 x 10.5 inches).
+# The default value is: a4.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PAPER_TYPE             = a4wide
+
+# The EXTRA_PACKAGES tag can be used to specify one or more LaTeX package names
+# that should be included in the LaTeX output. To get the times font for
+# instance you can specify
+# EXTRA_PACKAGES=times
+# If left blank no extra packages will be included.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+EXTRA_PACKAGES         = 
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for the
+# generated LaTeX document. The header should contain everything until the first
+# chapter. If it is left blank doxygen will generate a standard header. See
+# section "Doxygen usage" for information on how to let doxygen write the
+# default header to a separate file.
+#
+# Note: Only use a user-defined header if you know what you are doing! The
+# following commands have a special meaning inside the header: $title,
+# $datetime, $date, $doxygenversion, $projectname, $projectnumber. Doxygen will
+# replace them by respectively the title of the page, the current date and time,
+# only the current date, the version number of doxygen, the project name (see
+# PROJECT_NAME), or the project number (see PROJECT_NUMBER).
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HEADER           = 
+
+# The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for the
+# generated LaTeX document. The footer should contain everything after the last
+# chapter. If it is left blank doxygen will generate a standard footer.
+#
+# Note: Only use a user-defined footer if you know what you are doing!
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_FOOTER           = 
+
+# The LATEX_EXTRA_FILES tag can be used to specify one or more extra images or
+# other source files which should be copied to the LATEX_OUTPUT output
+# directory. Note that the files will be copied as-is; there are no commands or
+# markers available.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_EXTRA_FILES      = 
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated is
+# prepared for conversion to PDF (using ps2pdf or pdflatex). The PDF file will
+# contain links (just like the HTML output) instead of page references. This
+# makes the output suitable for online browsing using a PDF viewer.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+PDF_HYPERLINKS         = YES
+
+# If the LATEX_PDFLATEX tag is set to YES, doxygen will use pdflatex to generate
+# the PDF file directly from the LaTeX files. Set this option to YES to get a
+# higher quality PDF documentation.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+USE_PDFLATEX           = YES
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \batchmode
+# command to the generated LaTeX files. This will instruct LaTeX to keep running
+# if errors occur, instead of asking the user for help. This option is also used
+# when generating formulas in HTML.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BATCHMODE        = NO
+
+# If the LATEX_HIDE_INDICES tag is set to YES then doxygen will not include the
+# index chapters (such as File Index, Compound Index, etc.) in the output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_HIDE_INDICES     = NO
+
+# If the LATEX_SOURCE_CODE tag is set to YES then doxygen will include source
+# code with syntax highlighting in the LaTeX output.
+#
+# Note that which sources are shown also depends on other settings such as
+# SOURCE_BROWSER.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_SOURCE_CODE      = NO
+
+# The LATEX_BIB_STYLE tag can be used to specify the style to use for the
+# bibliography, e.g. plainnat, or ieeetr. See
+# http://en.wikipedia.org/wiki/BibTeX and \cite for more info.
+# The default value is: plain.
+# This tag requires that the tag GENERATE_LATEX is set to YES.
+
+LATEX_BIB_STYLE        = plain
+
+#---------------------------------------------------------------------------
+# Configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES doxygen will generate RTF output. The
+# RTF output is optimized for Word 97 and may not look too pretty with other RTF
+# readers/editors.
+# The default value is: NO.
+
+GENERATE_RTF           = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: rtf.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_OUTPUT             = rtf
+
+# If the COMPACT_RTF tag is set to YES doxygen generates more compact RTF
+# documents. This may be useful for small projects and may help to save some
+# trees in general.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+COMPACT_RTF            = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated will
+# contain hyperlink fields. The RTF file will contain links (just like the HTML
+# output) instead of page references. This makes the output suitable for online
+# browsing using Word or some other Word compatible readers that support those
+# fields.
+#
+# Note: WordPad (write) and others do not support links.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_HYPERLINKS         = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's config
+# file, i.e. a series of assignments. You only have to provide replacements,
+# missing definitions are set to their default value.
+#
+# See also section "Doxygen usage" for information on how to generate the
+# default style sheet that doxygen normally uses.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_STYLESHEET_FILE    = 
+
+# Set optional variables used in the generation of an RTF document. Syntax is
+# similar to doxygen's config file. A template extensions file can be generated
+# using doxygen -e rtf extensionFile.
+# This tag requires that the tag GENERATE_RTF is set to YES.
+
+RTF_EXTENSIONS_FILE    = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES doxygen will generate man pages for
+# classes and files.
+# The default value is: NO.
+
+GENERATE_MAN           = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it. A directory man3 will be created inside the directory specified by
+# MAN_OUTPUT.
+# The default directory is: man.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_OUTPUT             = man
+
+# The MAN_EXTENSION tag determines the extension that is added to the generated
+# man pages. In case the manual section does not start with a number, the number
+# 3 is prepended. The dot (.) at the beginning of the MAN_EXTENSION tag is
+# optional.
+# The default value is: .3.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_EXTENSION          = .3
+
+# The MAN_SUBDIR tag determines the name of the directory created within
+# MAN_OUTPUT in which the man pages are placed. If defaults to man followed by
+# MAN_EXTENSION with the initial . removed.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_SUBDIR             = 
+
+# If the MAN_LINKS tag is set to YES and doxygen generates man output, then it
+# will generate one additional man file for each entity documented in the real
+# man page(s). These additional files only source the real man page, but without
+# them the man command would be unable to find the correct page.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_MAN is set to YES.
+
+MAN_LINKS              = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES doxygen will generate an XML file that
+# captures the structure of the code including all documentation.
+# The default value is: NO.
+
+GENERATE_XML           = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put. If a
+# relative path is entered the value of OUTPUT_DIRECTORY will be put in front of
+# it.
+# The default directory is: xml.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_OUTPUT             = xml
+
+# If the XML_PROGRAMLISTING tag is set to YES doxygen will dump the program
+# listings (including syntax highlighting and cross-referencing information) to
+# the XML output. Note that enabling this will significantly increase the size
+# of the XML output.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_XML is set to YES.
+
+XML_PROGRAMLISTING     = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to the DOCBOOK output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_DOCBOOK tag is set to YES doxygen will generate Docbook files
+# that can be used to generate PDF.
+# The default value is: NO.
+
+GENERATE_DOCBOOK       = NO
+
+# The DOCBOOK_OUTPUT tag is used to specify where the Docbook pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be put in
+# front of it.
+# The default directory is: docbook.
+# This tag requires that the tag GENERATE_DOCBOOK is set to YES.
+
+DOCBOOK_OUTPUT         = docbook
+
+#---------------------------------------------------------------------------
+# Configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES doxygen will generate an AutoGen
+# Definitions (see http://autogen.sf.net) file that captures the structure of
+# the code including all documentation. Note that this feature is still
+# experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_AUTOGEN_DEF   = NO
+
+#---------------------------------------------------------------------------
+# Configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES doxygen will generate a Perl module
+# file that captures the structure of the code including all documentation.
+#
+# Note that this feature is still experimental and incomplete at the moment.
+# The default value is: NO.
+
+GENERATE_PERLMOD       = NO
+
+# If the PERLMOD_LATEX tag is set to YES doxygen will generate the necessary
+# Makefile rules, Perl scripts and LaTeX code to be able to generate PDF and DVI
+# output from the Perl module output.
+# The default value is: NO.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_LATEX          = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be nicely
+# formatted so it can be parsed by a human reader. This is useful if you want to
+# understand what is going on. On the other hand, if this tag is set to NO the
+# size of the Perl module output will be much smaller and Perl will parse it
+# just the same.
+# The default value is: YES.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_PRETTY         = YES
+
+# The names of the make variables in the generated doxyrules.make file are
+# prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. This is useful
+# so different doxyrules.make files included by the same Makefile don't
+# overwrite each other's variables.
+# This tag requires that the tag GENERATE_PERLMOD is set to YES.
+
+PERLMOD_MAKEVAR_PREFIX = 
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES doxygen will evaluate all
+# C-preprocessor directives found in the sources and include files.
+# The default value is: YES.
+
+ENABLE_PREPROCESSING   = YES
+
+# If the MACRO_EXPANSION tag is set to YES doxygen will expand all macro names
+# in the source code. If set to NO only conditional compilation will be
+# performed. Macro expansion can be done in a controlled way by setting
+# EXPAND_ONLY_PREDEF to YES.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+MACRO_EXPANSION        = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES then
+# the macro expansion is limited to the macros specified with the PREDEFINED and
+# EXPAND_AS_DEFINED tags.
+# The default value is: NO.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_ONLY_PREDEF     = NO
+
+# If the SEARCH_INCLUDES tag is set to YES the includes files in the
+# INCLUDE_PATH will be searched if a #include is found.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SEARCH_INCLUDES        = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by the
+# preprocessor.
+# This tag requires that the tag SEARCH_INCLUDES is set to YES.
+
+INCLUDE_PATH           = 
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will be
+# used.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+INCLUDE_FILE_PATTERNS  = 
+
+# The PREDEFINED tag can be used to specify one or more macro names that are
+# defined before the preprocessor is started (similar to the -D option of e.g.
+# gcc). The argument of the tag is a list of macros of the form: name or
+# name=definition (no spaces). If the definition and the "=" are omitted, "=1"
+# is assumed. To prevent a macro definition from being undefined via #undef or
+# recursively expanded use the := operator instead of the = operator.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+PREDEFINED             = 
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then this
+# tag can be used to specify a list of macro names that should be expanded. The
+# macro definition that is found in the sources will be used. Use the PREDEFINED
+# tag if you want to use a different macro definition that overrules the
+# definition found in the source code.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+EXPAND_AS_DEFINED      = 
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES then doxygen's preprocessor will
+# remove all references to function-like macros that are alone on a line, have
+# an all uppercase name, and do not end with a semicolon. Such function macros
+# are typically used for boiler-plate code, and will confuse the parser if not
+# removed.
+# The default value is: YES.
+# This tag requires that the tag ENABLE_PREPROCESSING is set to YES.
+
+SKIP_FUNCTION_MACROS   = YES
+
+#---------------------------------------------------------------------------
+# Configuration options related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES tag can be used to specify one or more tag files. For each tag
+# file the location of the external documentation should be added. The format of
+# a tag file without this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where loc1 and loc2 can be relative or absolute paths or URLs. See the
+# section "Linking to external documentation" for more information about the use
+# of tag files.
+# Note: Each tag file must have a unique name (where the name does NOT include
+# the path). If a tag file is not located in the directory in which doxygen is
+# run, you must also specify the path to the tagfile here.
+
+TAGFILES               = 
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create a
+# tag file that is based on the input files it reads. See section "Linking to
+# external documentation" for more information about the usage of tag files.
+
+GENERATE_TAGFILE       = 
+
+# If the ALLEXTERNALS tag is set to YES all external class will be listed in the
+# class index. If set to NO only the inherited external classes will be listed.
+# The default value is: NO.
+
+ALLEXTERNALS           = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed in
+# the modules index. If set to NO, only the current project's groups will be
+# listed.
+# The default value is: YES.
+
+EXTERNAL_GROUPS        = YES
+
+# If the EXTERNAL_PAGES tag is set to YES all external pages will be listed in
+# the related pages index. If set to NO, only the current project's pages will
+# be listed.
+# The default value is: YES.
+
+EXTERNAL_PAGES         = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of 'which perl').
+# The default file (with absolute path) is: /usr/bin/perl.
+
+PERL_PATH              = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES doxygen will generate a class diagram
+# (in HTML and LaTeX) for classes with base or super classes. Setting the tag to
+# NO turns the diagrams off. Note that this option also works with HAVE_DOT
+# disabled, but it is recommended to install and use dot, since it yields more
+# powerful graphs.
+# The default value is: YES.
+
+CLASS_DIAGRAMS         = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see:
+# http://www.mcternan.me.uk/mscgen/)) to produce the chart and insert it in the
+# documentation. The MSCGEN_PATH tag allows you to specify the directory where
+# the mscgen tool resides. If left empty the tool is assumed to be found in the
+# default search path.
+
+MSCGEN_PATH            = 
+
+# You can include diagrams made with dia in doxygen documentation. Doxygen will
+# then run dia to produce the diagram and insert it in the documentation. The
+# DIA_PATH tag allows you to specify the directory where the dia binary resides.
+# If left empty dia is assumed to be found in the default search path.
+
+DIA_PATH               = 
+
+# If set to YES, the inheritance and collaboration graphs will hide inheritance
+# and usage relations if the target is undocumented or is not a class.
+# The default value is: YES.
+
+HIDE_UNDOC_RELATIONS   = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz (see:
+# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent
+# Bell Labs. The other options in this section have no effect if this option is
+# set to NO
+# The default value is: NO.
+
+HAVE_DOT               = NO
+
+# The DOT_NUM_THREADS specifies the number of dot invocations doxygen is allowed
+# to run in parallel. When set to 0 doxygen will base this on the number of
+# processors available in the system. You can set it explicitly to a value
+# larger than 0 to get control over the balance between CPU load and processing
+# speed.
+# Minimum value: 0, maximum value: 32, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_NUM_THREADS        = 0
+
+# When you want a differently looking font n the dot files that doxygen
+# generates you can specify the font name using DOT_FONTNAME. You need to make
+# sure dot is able to find the font, which can be done by putting it in a
+# standard location or by setting the DOTFONTPATH environment variable or by
+# setting DOT_FONTPATH to the directory containing the font.
+# The default value is: Helvetica.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTNAME           = FreeSans.ttf
+
+# The DOT_FONTSIZE tag can be used to set the size (in points) of the font of
+# dot graphs.
+# Minimum value: 4, maximum value: 24, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTSIZE           = 10
+
+# By default doxygen will tell dot to use the default font as specified with
+# DOT_FONTNAME. If you specify a different font using DOT_FONTNAME you can set
+# the path where dot can find it using this tag.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_FONTPATH           = 
+
+# If the CLASS_GRAPH tag is set to YES then doxygen will generate a graph for
+# each documented class showing the direct and indirect inheritance relations.
+# Setting this tag to YES will force the CLASS_DIAGRAMS tag to NO.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CLASS_GRAPH            = YES
+
+# If the COLLABORATION_GRAPH tag is set to YES then doxygen will generate a
+# graph for each documented class showing the direct and indirect implementation
+# dependencies (inheritance, containment, and class references variables) of the
+# class with other documented classes.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+COLLABORATION_GRAPH    = YES
+
+# If the GROUP_GRAPHS tag is set to YES then doxygen will generate a graph for
+# groups, showing the direct groups dependencies.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GROUP_GRAPHS           = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LOOK               = NO
+
+# If the UML_LOOK tag is enabled, the fields and methods are shown inside the
+# class node. If there are many fields or methods and many nodes the graph may
+# become too big to be useful. The UML_LIMIT_NUM_FIELDS threshold limits the
+# number of items for each type to make the size more manageable. Set this to 0
+# for no limit. Note that the threshold may be exceeded by 50% before the limit
+# is enforced. So when you set the threshold to 10, up to 15 fields may appear,
+# but if the number exceeds 15, the total amount of fields shown is limited to
+# 10.
+# Minimum value: 0, maximum value: 100, default value: 10.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+UML_LIMIT_NUM_FIELDS   = 10
+
+# If the TEMPLATE_RELATIONS tag is set to YES then the inheritance and
+# collaboration graphs will show the relations between templates and their
+# instances.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+TEMPLATE_RELATIONS     = NO
+
+# If the INCLUDE_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are set to
+# YES then doxygen will generate a graph for each documented file showing the
+# direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDE_GRAPH          = YES
+
+# If the INCLUDED_BY_GRAPH, ENABLE_PREPROCESSING and SEARCH_INCLUDES tags are
+# set to YES then doxygen will generate a graph for each documented file showing
+# the direct and indirect include dependencies of the file with other documented
+# files.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INCLUDED_BY_GRAPH      = YES
+
+# If the CALL_GRAPH tag is set to YES then doxygen will generate a call
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALL_GRAPH             = NO
+
+# If the CALLER_GRAPH tag is set to YES then doxygen will generate a caller
+# dependency graph for every global function or class method.
+#
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+CALLER_GRAPH           = NO
+
+# If the GRAPHICAL_HIERARCHY tag is set to YES then doxygen will graphical
+# hierarchy of all classes instead of a textual one.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GRAPHICAL_HIERARCHY    = YES
+
+# If the DIRECTORY_GRAPH tag is set to YES then doxygen will show the
+# dependencies a directory has on other directories in a graphical way. The
+# dependency relations are determined by the #include relations between the
+# files in the directories.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DIRECTORY_GRAPH        = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot.
+# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order
+# to make the SVG files visible in IE 9+ (other browsers do not have this
+# requirement).
+# Possible values are: png, jpg, gif and svg.
+# The default value is: png.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_IMAGE_FORMAT       = png
+
+# If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to
+# enable generation of interactive SVG images that allow zooming and panning.
+#
+# Note that this requires a modern browser other than Internet Explorer. Tested
+# and working are Firefox, Chrome, Safari, and Opera.
+# Note: For IE 9+ you need to set HTML_FILE_EXTENSION to xhtml in order to make
+# the SVG files visible. Older versions of IE do not have SVG support.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+INTERACTIVE_SVG        = NO
+
+# The DOT_PATH tag can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_PATH               = 
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the \dotfile
+# command).
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOTFILE_DIRS           = 
+
+# The MSCFILE_DIRS tag can be used to specify one or more directories that
+# contain msc files that are included in the documentation (see the \mscfile
+# command).
+
+MSCFILE_DIRS           = 
+
+# The DIAFILE_DIRS tag can be used to specify one or more directories that
+# contain dia files that are included in the documentation (see the \diafile
+# command).
+
+DIAFILE_DIRS           = 
+
+# The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of nodes
+# that will be shown in the graph. If the number of nodes in a graph becomes
+# larger than this value, doxygen will truncate the graph, which is visualized
+# by representing a node as a red box. Note that doxygen if the number of direct
+# children of the root node in a graph is already larger than
+# DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note that
+# the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+# Minimum value: 0, maximum value: 10000, default value: 50.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_GRAPH_MAX_NODES    = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the graphs
+# generated by dot. A depth value of 3 means that only nodes reachable from the
+# root by following a path via at most 3 edges will be shown. Nodes that lay
+# further from the root node will be omitted. Note that setting this option to 1
+# or 2 may greatly reduce the computation time needed for large code bases. Also
+# note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+# Minimum value: 0, maximum value: 1000, default value: 0.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+MAX_DOT_GRAPH_DEPTH    = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, because dot on Windows does not seem
+# to support this out of the box.
+#
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_TRANSPARENT        = NO
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10) support
+# this, this feature is disabled by default.
+# The default value is: NO.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_MULTI_TARGETS      = NO
+
+# If the GENERATE_LEGEND tag is set to YES doxygen will generate a legend page
+# explaining the meaning of the various boxes and arrows in the dot generated
+# graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+GENERATE_LEGEND        = YES
+
+# If the DOT_CLEANUP tag is set to YES doxygen will remove the intermediate dot
+# files that are used to generate the various graphs.
+# The default value is: YES.
+# This tag requires that the tag HAVE_DOT is set to YES.
+
+DOT_CLEANUP            = YES
diff --git a/doc/images/capi_uix_voice_control_service_state_diagram.png b/doc/images/capi_uix_voice_control_service_state_diagram.png
new file mode 100644 (file)
index 0000000..6108aa7
Binary files /dev/null and b/doc/images/capi_uix_voice_control_service_state_diagram.png differ
diff --git a/doc/images/capi_uix_voice_control_state_diagram.png b/doc/images/capi_uix_voice_control_state_diagram.png
new file mode 100644 (file)
index 0000000..e401eab
Binary files /dev/null and b/doc/images/capi_uix_voice_control_state_diagram.png differ
diff --git a/doc/uix_vc_doc.h b/doc/uix_vc_doc.h
new file mode 100644 (file)
index 0000000..ae2ccca
--- /dev/null
@@ -0,0 +1,199 @@
+/*
+ * Copyright (c) 2011-2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+
+
+#ifndef __TIZEN_UIX_VOICE_CONTROL_DOC_H__
+#define __TIZEN_UIX_VOICE_CONTROL_DOC_H__
+
+/**
+ * @defgroup CAPI_UIX_VOICE_CONTROL_MODULE Voice control
+ * @ingroup CAPI_UIX_FRAMEWORK
+ * @brief The @ref CAPI_UIX_VOICE_CONTROL_MODULE API provides functions for registering command and getting notification when registered command is recognized.
+ * 
+ * @section CAPI_UIX_VOICE_CONTROL_MODULE_HEADER Required Header
+ *   \#include <voice_control.h><br>
+ * 
+ * @section CAPI_UIX_VOICE_CONTROL_MODULE_OVERVIEW Overview
+ * A main function of Voice Control API register command and gets notification for recognition result.
+ * Applications can add their own commands and be provided result when their command is recognized by user voice input.
+ * 
+ * To use of Voice Control, use the following steps:
+ * 1. Initialize <br>
+ * 2. Register callback functions for notifications <br> 
+ * 3. Connect to voice control service asynchronously. The state should be changed to Ready <br>
+ * 4. Make command list as the following step <br>
+ * 4-1. Create command list handle <br>
+ * 4-2. Create command handle <br>
+ * 4-3. Set command and type for command handle <br>
+ * 4-4. Add command handle to command list <br>
+ * Step 4 is called repeatedly for each command which an application wants <br>
+ * 5. Set command list for recognition <br>
+ * 6. If an application wants to finish voice control,<br>
+ * 6-1. Destroy command and command list handle <br>
+ * 6-2. Deinitialize <br>
+ *
+ * An application can obtain command handle from command list, and also get information from handle. 
+ *
+ *
+ * The Voice Control API also notifies you (by callback mechanism) when the states of client and service are changed, 
+ * command is recognized, current language is changed or error occurred.
+ * An application should register callback functions: vc_state_changed_cb(), vc_service_state_changed_cb(), vc_result_cb(), 
+ * vc_current_language_changed_cb(), vc_error_cb().
+ *
+ * @section CAPI_UIX_VOICE_CONTROL_MODULE_STATE_DIAGRAM State Diagram
+ * The following diagram shows the life cycle and the states of the Voice Control.
+ *
+ * @image html capi_uix_voice_control_state_diagram.png "<State diagram>    "
+ * The following diagram shows the states of Voice Control service.
+ * @image html capi_uix_voice_control_service_state_diagram.png "<Service state diagram>"
+ *
+ * @section CAPI_UIX_VOICE_CONTROL_MODULE_STATE_TRANSITIONS State Transitions
+ *
+ * <table>
+ * <tr>
+ * <th>FUNCTION</th>
+ * <th>PRE-STATE</th>
+ * <th>POST-STATE</th>
+ * <th>SYNC TYPE</th>
+ * </tr>
+ * <tr>
+ * <td>vc_initialize()</td>
+ * <td>None</td>
+ * <td>Initialized</td>
+ * <td>SYNC</td>
+ * </tr>
+ * <tr>
+ * <td>vc_deinitialize()</td>
+ * <td>Initialized</td>
+ * <td>None</td>
+ * <td>SYNC</td>
+ * </tr>
+ * <tr>
+ * <td>vc_prepare()</td>
+ * <td>Initialized</td>
+ * <td>Ready</td>
+ * <td>ASYNC</td>
+ * </tr>
+ * <tr>
+ * <td>vc_unprepare()</td>
+ * <td>Ready</td>
+ * <td>Initialized</td>
+ * <td>SYNC</td>
+ * </tr>
+
+ * </table>
+ *
+ * @section CAPI_UIX_VOICE_CONTROL_MODULE_STATE_DEPENDENT_FUNCTION_CALLS State Dependent Function Calls
+ * The following table shows state-dependent function calls.
+ * It is forbidden to call functions listed below in wrong states.
+ * Violation of this rule may result in an unpredictable behavior.
+ * 
+ * <table>
+ * <tr>
+ * <th>FUNCTION</th>
+ * <th>VALID STATES</th>
+ * <th>DESCRIPTION</th>
+ * </tr>
+ * <tr>
+ * <td>vc_initialize()</td>
+ * <td>None</td>
+ * <td>All functions must be called after vc_initialize()</td>
+ * </tr>
+ * <tr>
+ * <td>vc_deinitialize()</td>
+ * <td>Initialized, Ready</td>
+ * <td>This function should be called when an application want to finalize voice control using</td>
+ * </tr>
+ * <tr>
+ * <td>vc_prepare()</td>
+ * <td>Initialized</td>
+ * <td>This function works asynchronously. If service start is failed, application gets the error callback.</td>
+ * </tr>
+ * <tr>
+ * <td>vc_unprepare()</td>
+ * <td>Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>vc_foreach_supported_languages()</td>
+ * <td>Initialized, Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>vc_get_current_language()</td>
+ * <td>Initialized, Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>vc_get_state()</td>
+ * <td>Initialized, Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>vc_get_service_state()</td>
+ * <td>Initialized, Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>vc_set_app_state()</td>
+ * <td>Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>vc_get_app_state()</td>
+ * <td>Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>vc_set_command_list()</td>
+ * <td>Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>vc_unset_command_list()</td>
+ * <td>Ready</td>
+ * <td></td>
+ * </tr>
+ * <tr>
+ * <td>
+ * vc_set_result_cb()<br>
+ * vc_unset_result_cb()<br>
+ * vc_set_state_changed_cb()<br>
+ * vc_unset_state_changed_cb()<br>
+ * vc_set_service_state_changed_cb()<br>
+ * vc_unset_service_state_changed_cb()<br>
+ * vc_set_current_language_changed_cb()<br>
+ * vc_unset_current_language_changed_cb()<br>
+ * vc_set_error_cb()<br>
+ * vc_unset_error_cb()</td>
+ * <td>Initialized</td>
+ * <td> All callback function should be registered in Initialized state </td>
+ * </tr>
+ * </table>
+ * 
+ * @section CAPI_UIX_STT_MODULE_FEATURE Related Features
+ * This API is related with the following features:<br>
+ *  - http://tizen.org/feature/microphone<br>
+ *
+ * It is recommended to design feature related codes in your application for reliability.<br>
+ * You can check if a device supports the related features for this API by using @ref CAPI_SYSTEM_SYSTEM_INFO_MODULE, thereby controlling the procedure of your application.<br>
+ * To ensure your application is only running on the device with specific features, please define the features in your manifest file using the manifest editor in the SDK.<br>
+ * More details on featuring your application can be found from <a href="../org.tizen.mobile.native.appprogramming/html/ide_sdk_tools/feature_element.htm"><b>Feature Element</b>.</a>
+ *
+ */
+
+#endif /* __TIZEN_UIX_VOICE_CONTROL_DOC_H__ */
+
diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d40a4de
--- /dev/null
@@ -0,0 +1,25 @@
+## configure pkgconfig files ##
+CONFIGURE_FILE(voice-control.pc.in voice-control.pc @ONLY)
+CONFIGURE_FILE(voice-control-setting.pc.in voice-control-setting.pc @ONLY)
+CONFIGURE_FILE(voice-control-widget.pc.in voice-control-widget.pc @ONLY)
+CONFIGURE_FILE(voice-control-engine.pc.in voice-control-engine.pc @ONLY)
+CONFIGURE_FILE(voice-control-manager.pc.in voice-control-manager.pc @ONLY)
+
+## Install pc files ##
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice-control.pc DESTINATION ${LIBDIR}/pkgconfig)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice-control-setting.pc DESTINATION ${LIBDIR}/pkgconfig)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice-control-widget.pc DESTINATION ${LIBDIR}/pkgconfig)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice-control-manager.pc DESTINATION ${LIBDIR}/pkgconfig)
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice-control-engine.pc DESTINATION ${LIBDIR}/pkgconfig)
+
+## Install header files ##
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_authority.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_command.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_command_expand.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_common.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_key_defines.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_manager.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_plugin_engine.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_setting.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_BINARY_DIR}/include/voice_control_widget.h DESTINATION ${INCLUDEDIR})
diff --git a/include/voice-control-engine.pc.in b/include/voice-control-engine.pc.in
new file mode 100644 (file)
index 0000000..7808dfb
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: lib@PROJECT_NAME@_engine
+Description: Voice control engine header
+Requires: glib-2.0 dbus-1 capi-base-common
+Version: @VERSION@
+Cflags: -I${includedir}
diff --git a/include/voice-control-manager.pc.in b/include/voice-control-manager.pc.in
new file mode 100644 (file)
index 0000000..74ddccf
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: lib@PROJECT_NAME@_manager
+Description: Voice control manager client library
+Version: @VERSION@
+Libs: -L${libdir} -l@PROJECT_NAME@_manager
+Cflags: -I${includedir}
diff --git a/include/voice-control-setting.pc.in b/include/voice-control-setting.pc.in
new file mode 100644 (file)
index 0000000..e250626
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: lib@PROJECT_NAME@_setting
+Description: Voice control setting library
+Version: @VERSION@
+Libs: -L${libdir} -l@PROJECT_NAME@_setting
+Cflags: -I${includedir}
diff --git a/include/voice-control-widget.pc.in b/include/voice-control-widget.pc.in
new file mode 100644 (file)
index 0000000..51ba1ca
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: lib@PROJECT_NAME@_widget
+Description: Voice control library for widget
+Version: @VERSION@
+Libs: -L${libdir} -l@PROJECT_NAME@_widget
+Cflags: -I${includedir}
diff --git a/include/voice-control.pc.in b/include/voice-control.pc.in
new file mode 100644 (file)
index 0000000..fe29d64
--- /dev/null
@@ -0,0 +1,10 @@
+prefix=@PREFIX@
+exec_prefix=@EXEC_PREFIX@
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: lib@PROJECT_NAME@
+Description: Voice control client library
+Version: @VERSION@
+Libs: -L${libdir} -l@PROJECT_NAME@
+Cflags: -I${includedir}
diff --git a/include/voice_control.h b/include/voice_control.h
new file mode 100644 (file)
index 0000000..85985e7
--- /dev/null
@@ -0,0 +1,494 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_H__
+#define __VOICE_CONTROL_H__
+
+#include <voice_control_command.h>
+#include <voice_control_common.h>
+
+/**
+* @addtogroup CAPI_UIX_VOICE_CONTROL_MODULE
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/**
+* @file voice_control.h
+* @brief This file contains the voice control client API and related callback definitions and enums.
+*/
+
+/**
+* @file voice_control_command.h
+* @brief This file contains the command list and command API and related handle definitions and enums.
+*/
+
+/**
+* @file voice_control_common.h
+* @brief This file contains the callback function definitions and enums.
+*/
+
+/**
+* @brief Definitions for foreground command type.
+* @since_tizen 2.4
+*/
+#define VC_COMMAND_TYPE_FOREGROUND     1
+
+/**
+* @brief Definitions for background command type.
+* @since_tizen 2.4
+*/
+#define VC_COMMAND_TYPE_BACKGROUND     2
+
+
+/**
+* @brief Initializes voice control.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @remarks If the function succeeds, @a vc must be released with vc_deinitialize().
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @post If this function is called, the state will be #VC_STATE_INITIALIZED.
+*
+* @see vc_deinitialize()
+*/
+int vc_initialize();
+
+/**
+* @brief Deinitializes voice control.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_deinitialize()
+*/
+int vc_deinitialize();
+
+/**
+* @brief Connects the voice control service.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+* @post If this function is called, the state will be #VC_STATE_READY.
+*
+* @see vc_unprepare()
+*/
+int vc_prepare();
+
+/**
+* @brief Disconnects the voice control service.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_READY.
+* @post If this function is called, the state will be #VC_STATE_INITIALIZED.
+*
+* @see vc_prepare()
+*/
+int vc_unprepare();
+
+/**
+* @brief Retrieves all supported languages using callback function.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[in] callback Callback function to invoke
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED or #VC_STATE_READY.
+* @post        This function invokes vc_supported_language_cb() repeatedly for getting languages.
+*
+* @see vc_supported_language_cb()
+* @see vc_get_current_language()
+*/
+int vc_foreach_supported_languages(vc_supported_language_cb callback, void* user_data);
+
+/**
+* @brief Gets current language.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @remark If the function succeeds, @a language must be released with free() by you when you no longer need it.
+*
+* @param[out] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n
+*                      followed by ISO 639-1 for the two-letter language code. \n
+*                      For example, "ko_KR" for Korean, "en_US" for American English.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED or #VC_STATE_READY.
+*
+* @see vc_foreach_supported_languages()
+*/
+int vc_get_current_language(char** language);
+
+/**
+* @brief Gets current state of voice control client.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[out] state The current state
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_state_changed_cb() 
+* @see vc_set_state_changed_cb()
+*/
+int vc_get_state(vc_state_e* state);
+
+/**
+* @brief Gets current state of voice control service.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[out] state The current state
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED or #VC_STATE_READY.
+*
+* @see vc_request_start()
+* @see vc_request_stop()
+* @see vc_request_cancel()
+* @see vc_set_service_state_changed_cb() 
+* @see vc_unset_service_state_changed_cb()
+*/
+int vc_get_service_state(vc_service_state_e* state);
+
+/**
+* @brief Sets command list.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @remarks The command type is valid for #VC_COMMAND_TYPE_FOREGROUND or #VC_COMMAND_TYPE_BACKGROUND. \n
+*      The matched commands of command list should be set and they should include type and command text at least.
+*
+* @param[in] vc_cmd_list Command list handle
+* @param[in] type Command type
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_unset_command_list() 
+*/
+int vc_set_command_list(vc_cmd_list_h vc_cmd_list, int type);
+
+/**
+* @brief Unsets command list.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[in] type Command type
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_set_command_list() 
+*/
+int vc_unset_command_list(int type);
+
+
+/**
+* @brief Registers a callback function for getting recognition result.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_result_cb()
+* @see vc_unset_result_cb()
+*/
+int vc_set_result_cb(vc_result_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_set_result_cb()
+*/
+int vc_unset_result_cb();
+
+/**
+* @brief Registers a callback function to be called when state is changed.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_service_state_changed_cb()
+* @see vc_unset_service_state_changed_cb()
+*/
+int vc_set_service_state_changed_cb(vc_service_state_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_set_service_state_changed_cb()
+*/
+int vc_unset_service_state_changed_cb();
+
+/**
+* @brief Registers a callback function to be called when state is changed.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_state_changed_cb()
+* @see vc_unset_state_changed_cb()
+*/
+int vc_set_state_changed_cb(vc_state_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_set_state_changed_cb()
+*/
+int vc_unset_state_changed_cb();
+
+/**
+* @brief Registers a callback function to be called when current language is changed.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_current_language_changed_cb()
+* @see vc_unset_current_language_changed_cb()
+*/
+int vc_set_current_language_changed_cb(vc_current_language_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_set_current_language_changed_cb()
+*/
+int vc_unset_current_language_changed_cb();
+
+/**
+* @brief Registers a callback function to be called when an error occurred.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_error_cb()
+* @see vc_unset_error_cb()
+*/
+int vc_set_error_cb(vc_error_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+* @since_tizen 2.4
+* @privlevel public
+* @privilege %http://tizen.org/privilege/recorder
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_set_error_cb()
+*/
+int vc_unset_error_cb();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* __VOICE_CONTROL_H__ */
diff --git a/include/voice_control_authority.h b/include/voice_control_authority.h
new file mode 100644 (file)
index 0000000..38948c8
--- /dev/null
@@ -0,0 +1,188 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_AUTHORITY_H__
+#define __VOICE_CONTROL_AUTHORITY_H__
+
+#include <voice_control_common.h>
+
+/**
+* @addtogroup VOICE_CONTROL_AUTHORITY
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/* Authority */
+
+typedef enum {
+       VC_AUTH_STATE_NONE      = 0,
+       VC_AUTH_STATE_VALID     = 1,
+       VC_AUTH_STATE_INVALID   = 2
+}vc_auth_state_e;
+
+
+/**
+* @brief Called when authority state of client is changed.
+*
+* @param[in] previous Previous state
+* @param[in] current Current state
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers callback function.
+*
+* @see vc_set_auth_state_changed_cb()
+*/
+typedef void (*vc_auth_state_changed_cb)(vc_auth_state_e previous, vc_auth_state_e current, void* user_data);
+
+/**
+* @brief Enable authority about start/stop/cancel recognition.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_auth_disable()
+*/
+int vc_auth_enable();
+
+/**
+* @brief Disable authority.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_auth_enable()
+*/
+int vc_auth_disable();
+
+/**
+* @brief Get current authority state.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*/
+int vc_auth_get_state(vc_auth_state_e* status);
+
+/**
+* @brief Set callback for authority state changing.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre This function should be called when the authority state is #VC_AUTH_STATE_VALID or #VC_AUTH_STATE_INVALID.
+*
+* @see vc_auth_unset_state_changed_cb()
+* @see vc_auth_state_changed_cb()
+*/
+int vc_auth_set_state_changed_cb(vc_auth_state_changed_cb callback, void* user_data);
+
+/**
+* @brief Unset callback for authority state changing.
+*
+* @remarks This function will be called in vc_auth_disable() automatically.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre This function should be called when the authority state is #VC_AUTH_STATE_VALID or #VC_AUTH_STATE_INVALID.
+*
+* @see vc_auth_set_state_changed_cb()
+*/
+int vc_auth_unset_state_changed_cb();
+
+/**
+* @brief Start recognition.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY. \n
+* The authority status should be #VC_AUTHORITY_STATUS_VALID.
+* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n
+* If this function succeeds, the service state will be #VC_SERVICE_STATE_RECORDING.
+*
+* @see vc_auth_stop()
+* @see vc_auth_cancel()
+*/
+int vc_auth_start();
+
+/**
+* @brief Stop recognition.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre The service state should be #VC_SERVICE_STATE_RECORDING. \n
+* The authority status should be #VC_AUTHORITY_STATUS_VALID.
+* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n
+* If this function succeeds, the service state will be #VC_SERVICE_STATE_PROCESSING.
+*
+* @see vc_auth_start()
+* @see vc_auth_cancel()
+*/
+int vc_auth_stop();
+
+/**
+* @brief Cancel recognition.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre The service state should be #VC_SERVICE_STATE_RECORDING or #VC_SERVICE_STATE_PROCESSING. \n
+* The authority status should be #VC_AUTHORITY_STAUS_VALID.
+* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n
+* If this function succeeds, the service state will be #VC_SERVICE_STATE_READY.
+*
+* @see vc_auth_start()
+* @see vc_auth_stop()
+*/
+int vc_auth_cancel();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* __VOICE_CONTROL_AUTHORITY_H__ */
diff --git a/include/voice_control_command.h b/include/voice_control_command.h
new file mode 100644 (file)
index 0000000..bbdc847
--- /dev/null
@@ -0,0 +1,379 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_COMMAND_H__
+#define __VOICE_CONTROL_COMMAND_H__
+
+#include <tizen.h>
+
+
+/**
+* @addtogroup Voice_control_command
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+
+/**
+* @brief The voice command handle.
+* @since_tizen 2.4
+*/
+typedef struct vc_cmd_s* vc_cmd_h;
+
+/**
+* @brief The voice command list handle.
+* @since_tizen 2.4
+*/
+typedef struct vc_cmd_list_s* vc_cmd_list_h;
+
+/**
+* @brief Called to retrieve The commands in list.
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[in] user_data The user data passed from the foreach function
+*
+* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop.
+* @pre vc_cmd_list_foreach_commands() will invoke this callback.
+*
+* @see vc_cmd_list_foreach_commands()
+*/
+typedef bool (*vc_cmd_list_cb)(vc_cmd_h vc_command, void* user_data);
+
+
+/**
+* @brief Creates a handle for command list.
+* @since_tizen 2.4
+*
+* @remarks If the function succeeds, @a The list handle must be released with vc_cmd_list_destroy().
+*
+* @param[out] vc_cmd_list The command list handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_destroy()
+*/
+int vc_cmd_list_create(vc_cmd_list_h* vc_cmd_list);
+
+/**
+* @brief Destroys the handle for command list.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+* @param[in] free_command The command free option @c true = release each commands in list, 
+*                      @c false = remove command from list
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_create()
+*/
+int vc_cmd_list_destroy(vc_cmd_list_h vc_cmd_list, bool free_command);
+
+/**
+* @brief Gets command count of list.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+* @param[out] count The count
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*/
+int vc_cmd_list_get_count(vc_cmd_list_h vc_cmd_list, int* count);
+
+/**
+* @brief Adds command to command list.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+* @param[in] vc_command The command handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_remove()
+*/
+int vc_cmd_list_add(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command);
+
+/**
+* @brief Removes command from command list.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+* @param[in] vc_command The command handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_add()
+*/
+int vc_cmd_list_remove(vc_cmd_list_h vc_cmd_list, vc_cmd_h vc_command);
+
+/**
+* @brief Retrieves all commands of command list using callback function.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+* @param[in] callback Callback function to invoke
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @post        This function invokes vc_cmd_list_cb() repeatedly for getting commands.
+*
+* @see vc_cmd_list_cb()
+*/
+int vc_cmd_list_foreach_commands(vc_cmd_list_h vc_cmd_list, vc_cmd_list_cb callback, void* user_data);
+
+/**
+* @brief Moves index to first command.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_EMPTY List empty
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_last()
+*/
+int vc_cmd_list_first(vc_cmd_list_h vc_cmd_list);
+
+/**
+* @brief Moves index to last command.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_EMPTY List empty
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_first()
+*/
+int vc_cmd_list_last(vc_cmd_list_h vc_cmd_list);
+
+/**
+* @brief Moves index to next command.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_EMPTY List empty
+* @retval #VC_ERROR_ITERATION_END List reached end
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_prev()
+*/
+int vc_cmd_list_next(vc_cmd_list_h vc_cmd_list);
+
+/**
+* @brief Moves index to previous command.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_EMPTY List empty
+* @retval #VC_ERROR_ITERATION_END List reached end
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_next()
+*/
+int vc_cmd_list_prev(vc_cmd_list_h vc_cmd_list);
+
+/**
+* @brief Get current command from command list by index.
+* @since_tizen 2.4
+*
+* @param[in] vc_cmd_list The command list handle
+* @param[out] vc_command The command handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_EMPTY List empty
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_list_first()
+* @see vc_cmd_list_last()
+* @see vc_cmd_list_prev()
+* @see vc_cmd_list_next()
+*/
+int vc_cmd_list_get_current(vc_cmd_list_h vc_cmd_list, vc_cmd_h* vc_command);
+
+
+/**
+* @brief Creates a handle for command.
+* @since_tizen 2.4
+*
+* @remarks If the function succeeds, @a The command handle must be released 
+*      with vc_cmd_destroy() or vc_cmd_list_destroy().
+*      You should set command and type if command is valid
+*
+* @param[out] vc_command The command handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_destroy()
+*/
+int vc_cmd_create(vc_cmd_h* vc_command);
+
+/**
+* @brief Destroys the handle.
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_create()
+*/
+int vc_cmd_destroy(vc_cmd_h vc_command);
+
+/**
+* @brief Sets command.
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[in] command The command text
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_get_command()
+*/
+int vc_cmd_set_command(vc_cmd_h vc_command, const char* command);
+
+/**
+* @brief Gets command.
+* @since_tizen 2.4
+*
+* @remark If the function succeeds, @a command must be released with free() by you if they are not NULL.
+*
+* @param[in] vc_command The command handle
+* @param[out] command The command text
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_set_command()
+*/
+int vc_cmd_get_command(vc_cmd_h vc_command, char** command);
+
+/**
+* @brief Sets command type.
+* @since_tizen 2.4
+*
+* @remark If you do not set the command type, the default value is -1.
+*      You should set type if command is valid
+*
+* @param[in] vc_command The command handle
+* @param[in] type The command type
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_get_type()
+*/
+int vc_cmd_set_type(vc_cmd_h vc_command, int type);
+
+/**
+* @brief Gets command type.
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[out] type The command type
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported
+*
+* @see vc_cmd_set_type()
+*/
+int vc_cmd_get_type(vc_cmd_h vc_command, int* type);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* __VOICE_CONTROL_COMMAND_H__ */
diff --git a/include/voice_control_command_expand.h b/include/voice_control_command_expand.h
new file mode 100644 (file)
index 0000000..e2e507c
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_COMMAND_EXPAND_H__
+#define __VOICE_CONTROL_COMMAND_EXPAND_H__
+
+#include <tizen.h>
+#include <voice_control_command.h>
+
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+
+/**
+* @brief Enumerations of command format.
+* @since_tizen 2.4
+*/
+typedef enum {
+       VC_CMD_FORMAT_FIXED = 0,        /**< fixed command only */
+       VC_CMD_FORMAT_FIXED_AND_EXTRA,  /**< Fixed + extra unfixed command */
+       VC_CMD_FORMAT_EXTRA_AND_FIXED,  /**< Extra unfixed + fixed command */
+       VC_CMD_FORMAT_UNFIXED_ONLY      /**< Unfixed command */
+}vc_cmd_format_e;
+
+
+/**
+* @brief Gets extra unfixed command.
+* @since_tizen 2.4
+*
+* @remark If the function succeeds, @a The command must be released with free() by you if they are not NULL.
+*      If you get the result command list in result callback and the command type of commands has non-fixed format, 
+*      you should check non-fixed result using this function.
+*
+* @param[in] vc_command The command handle
+* @param[out] command The unfixed command text
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature
+*/
+int vc_cmd_get_unfixed_command(vc_cmd_h vc_command, char** command);
+
+/**
+* @brief Sets command format.
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[in] format The command format
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature
+*
+* @see vc_cmd_get_format()
+*/
+int vc_cmd_set_format(vc_cmd_h vc_command, vc_cmd_format_e format);
+
+/**
+* @brief Gets command format.
+* @since_tizen 2.4
+*
+* @remark If you do not set the format, the default format is #VC_CMD_FORMAT_FIXED.
+*
+* @param[in] vc_command The command handle
+* @param[out] format The command format
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature
+*
+* @see vc_cmd_set_format()
+*/
+int vc_cmd_get_format(vc_cmd_h vc_command, vc_cmd_format_e* format);
+
+/**
+* @brief Sets command domain
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[in] domain The domain
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature
+*
+* @see vc_cmd_get_domain()
+*/
+int vc_cmd_set_domain(vc_cmd_h vc_command, int domain);
+
+/**
+* @brief Gets command domain.
+* @since_tizen 2.4
+*
+* @param[in] vc_command The command handle
+* @param[out] domain The domain
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ERROR_NOT_SUPPORTED Not supported feature
+*
+* @see vc_cmd_set_domain()
+*/
+int vc_cmd_get_domain(vc_cmd_h vc_command, int* domain);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* __VOICE_CONTROL_COMMAND_EXPAND_H__ */
diff --git a/include/voice_control_common.h b/include/voice_control_common.h
new file mode 100644 (file)
index 0000000..7bd8055
--- /dev/null
@@ -0,0 +1,184 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_COMMON_H__
+#define __VOICE_CONTROL_COMMON_H__
+
+#include <voice_control_command.h>
+
+/**
+* @addtogroup Voice_control_common
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+* @brief Enumerations of error codes.
+* @since_tizen 2.4
+*/
+typedef enum {
+       VC_ERROR_NONE                   = TIZEN_ERROR_NONE,                     /**< Successful */
+       VC_ERROR_OUT_OF_MEMORY          = TIZEN_ERROR_OUT_OF_MEMORY,            /**< Out of Memory */
+       VC_ERROR_IO_ERROR               = TIZEN_ERROR_IO_ERROR,                 /**< I/O error */
+       VC_ERROR_INVALID_PARAMETER      = TIZEN_ERROR_INVALID_PARAMETER,        /**< Invalid parameter */
+       VC_ERROR_TIMED_OUT              = TIZEN_ERROR_TIMED_OUT,                /**< No answer from service */
+       VC_ERROR_RECORDER_BUSY          = TIZEN_ERROR_RESOURCE_BUSY,            /**< Busy recorder */
+       VC_ERROR_PERMISSION_DENIED      = TIZEN_ERROR_PERMISSION_DENIED,        /**< Permission denied */
+       VC_ERROR_NOT_SUPPORTED          = TIZEN_ERROR_NOT_SUPPORTED,            /**< VC NOT supported */
+       VC_ERROR_INVALID_STATE          = TIZEN_ERROR_VOICE_CONTROL | 0x011,    /**< Invalid state */
+       VC_ERROR_INVALID_LANGUAGE       = TIZEN_ERROR_VOICE_CONTROL | 0x012,    /**< Invalid language */
+       VC_ERROR_ENGINE_NOT_FOUND       = TIZEN_ERROR_VOICE_CONTROL | 0x013,    /**< No available engine */
+       VC_ERROR_OPERATION_FAILED       = TIZEN_ERROR_VOICE_CONTROL | 0x014,    /**< Operation failed */
+       VC_ERROR_OPERATION_REJECTED     = TIZEN_ERROR_VOICE_CONTROL | 0x015,    /**< Operation rejected */
+       VC_ERROR_ITERATION_END          = TIZEN_ERROR_VOICE_CONTROL | 0x016,    /**< List reached end */
+       VC_ERROR_EMPTY                  = TIZEN_ERROR_VOICE_CONTROL | 0x017     /**< List empty */
+}vc_error_e;
+
+/**
+* @brief Enumerations of result event.
+* @since_tizen 2.4
+*/
+typedef enum {
+       VC_RESULT_EVENT_RESULT_SUCCESS  = 0,    /**< Normal result */
+       VC_RESULT_EVENT_REJECTED        = 1     /**< Rejected result */
+}vc_result_event_e;
+
+/**
+* @brief Enumerations of service state.
+* @since_tizen 2.4
+*/
+typedef enum {
+       VC_SERVICE_STATE_NONE           = 0,    /**< 'None' state */
+       VC_SERVICE_STATE_READY          = 1,    /**< 'Ready' state */
+       VC_SERVICE_STATE_RECORDING      = 2,    /**< 'Recording' state */
+       VC_SERVICE_STATE_PROCESSING     = 3     /**< 'Processing' state */
+}vc_service_state_e;
+
+/**
+* @brief Enumerations of client state.
+* @since_tizen 2.4
+*/
+typedef enum {
+       VC_STATE_NONE                   = 0,    /**< 'None' state */
+       VC_STATE_INITIALIZED            = 1,    /**< 'Initialized' state */
+       VC_STATE_READY                  = 2     /**< 'Ready' state */
+}vc_state_e;
+
+
+/**
+* @brief Called when client gets the recognition result.
+* @since_tizen 2.4
+*
+* @remarks If the duplicated commands are recognized, the event(e.g. #VC_RESULT_EVENT_REJECTED) of command may be rejected \n
+*      for selecting command as priority. If you set similar or same commands or the recognized results are multi-results, 
+*      vc_cmd_list has the multi commands. 
+*
+* @param[in] event The result event (e.g. #VC_RESULT_EVENT_RESULT_SUCCESS, #VC_RESULT_EVENT_REJECTED)
+* @param[in] vc_cmd_list The recognized command list
+* @param[in] result The spoken text
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers callback function.
+*
+* @see vc_set_result_cb()
+*/
+typedef void (*vc_result_cb)(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, const char* result, void *user_data);
+
+/**
+* @brief Called when default language is changed.
+* @since_tizen 2.4
+*
+* @param[in] previous Previous language
+* @param[in] current Current language
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers this callback to detect changing mode.
+*
+* @see vc_set_current_language_changed_cb()
+*/
+typedef void (*vc_current_language_changed_cb)(const char* previous, const char* current, void* user_data);
+
+/**
+* @brief Called to retrieve supported language.
+* @since_tizen 2.4
+*
+* @param[in] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n
+*              followed by ISO 639-1 for the two-letter language code. \n
+*              For example, "ko_KR" for Korean, "en_US" for American English.
+* @param[in] user_data The user data passed from the foreach function
+*
+* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop.
+*
+* @pre The function will invoke this callback.
+*/
+typedef bool (*vc_supported_language_cb)(const char* language, void* user_data);
+
+/**
+* @brief Called when the state of voice control client is changed.
+* @since_tizen 2.4
+*
+* @param[in] previous A previous state
+* @param[in] current A current state
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers this callback to detect changing state.
+*
+* @see vc_set_state_changed_cb()
+*/
+typedef void (*vc_state_changed_cb)(vc_state_e previous, vc_state_e current, void* user_data);
+
+/**
+* @brief Called when the state of voice control service is changed.
+* @since_tizen 2.4
+*
+* @param[in] previous A previous state
+* @param[in] current A current state
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers this callback to detect changing service state.
+*
+* @see vc_set_service_state_changed_cb()
+*/
+typedef void (*vc_service_state_changed_cb)(vc_service_state_e previous, vc_service_state_e current, void* user_data);
+
+/**
+* @brief Called when error occurred.
+* @since_tizen 2.4
+*
+* @param[in] reason The error type (e.g. #VC_ERROR_OUT_OF_MEMORY, #VC_ERROR_TIMED_OUT)
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers this callback to detect error.
+*
+* @see vc_set_error_cb()
+*/
+typedef void (*vc_error_cb)(vc_error_e reason, void *user_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* VOICE_CONTROL_COMMON */
diff --git a/include/voice_control_key_defines.h b/include/voice_control_key_defines.h
new file mode 100644 (file)
index 0000000..2cc3315
--- /dev/null
@@ -0,0 +1,130 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_KEY_DEFINES_H__
+#define __VOICE_CONTROL_KEY_DEFINES_H__
+
+
+/**
+* @addtogroup VOICE_CONTROL_KEY_DEFINES
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/*
+* Modifier defines
+*/
+#define VC_MODIFIER_NONE       0x00000000
+#define VC_MODIFIER_CTRL       0x01000000
+#define VC_MODIFIER_ALT                0x00100000
+#define VC_MODIFIER_SHIFT      0x00010000
+
+/*
+* Key defines
+*/
+#define VC_KEY_NONE            0x00000000
+
+#define VC_KEY_NUMBER_BASE     0x00001000
+#define VC_KEY_0               VC_KEY_NUMBER_BASE | 0x00
+#define VC_KEY_1               VC_KEY_NUMBER_BASE | 0x01
+#define VC_KEY_2               VC_KEY_NUMBER_BASE | 0x02
+#define VC_KEY_3               VC_KEY_NUMBER_BASE | 0x03
+#define VC_KEY_4               VC_KEY_NUMBER_BASE | 0x04
+#define VC_KEY_5               VC_KEY_NUMBER_BASE | 0x05
+#define VC_KEY_6               VC_KEY_NUMBER_BASE | 0x06
+#define VC_KEY_7               VC_KEY_NUMBER_BASE | 0x07
+#define VC_KEY_8               VC_KEY_NUMBER_BASE | 0x08
+#define VC_KEY_9               VC_KEY_NUMBER_BASE | 0x09
+
+
+#define VC_KEY_FUNCTION_BASE   0x00002000
+#define VC_KEY_F1              VC_KEY_FUNCTION_BASE | 0x01
+#define VC_KEY_F2              VC_KEY_FUNCTION_BASE | 0x02
+#define VC_KEY_F3              VC_KEY_FUNCTION_BASE | 0x03
+#define VC_KEY_F4              VC_KEY_FUNCTION_BASE | 0x04
+#define VC_KEY_F5              VC_KEY_FUNCTION_BASE | 0x05
+#define VC_KEY_F6              VC_KEY_FUNCTION_BASE | 0x06
+#define VC_KEY_F7              VC_KEY_FUNCTION_BASE | 0x07
+#define VC_KEY_F8              VC_KEY_FUNCTION_BASE | 0x08
+#define VC_KEY_F9              VC_KEY_FUNCTION_BASE | 0x09
+#define VC_KEY_F10             VC_KEY_FUNCTION_BASE | 0x10
+#define VC_KEY_F11             VC_KEY_FUNCTION_BASE | 0x11
+#define VC_KEY_F12             VC_KEY_FUNCTION_BASE | 0x12
+
+#define VC_KEY_UP              VC_KEY_FUNCTION_BASE | 0x40
+#define VC_KEY_DOWN            VC_KEY_FUNCTION_BASE | 0x41
+#define VC_KEY_RIGHT           VC_KEY_FUNCTION_BASE | 0x42
+#define VC_KEY_LEFT            VC_KEY_FUNCTION_BASE | 0x43
+#define VC_KEY_INSERT          VC_KEY_FUNCTION_BASE | 0x44
+#define VC_KEY_HOME            VC_KEY_FUNCTION_BASE | 0x45
+#define VC_KEY_END             VC_KEY_FUNCTION_BASE | 0x46
+#define VC_KEY_PAGE_UP         VC_KEY_FUNCTION_BASE | 0x47
+#define VC_KEY_PAGE_DOWN       VC_KEY_FUNCTION_BASE | 0x48
+
+
+#define VC_KEY_ALPHABET_BASE   0x00003000
+#define VC_KEY_A               VC_KEY_ALPHABET_BASE | 0x01
+#define VC_KEY_B               VC_KEY_ALPHABET_BASE | 0x02
+#define VC_KEY_C               VC_KEY_ALPHABET_BASE | 0x03
+#define VC_KEY_D               VC_KEY_ALPHABET_BASE | 0x04
+#define VC_KEY_E               VC_KEY_ALPHABET_BASE | 0x05
+#define VC_KEY_F               VC_KEY_ALPHABET_BASE | 0x06
+#define VC_KEY_G               VC_KEY_ALPHABET_BASE | 0x07
+#define VC_KEY_H               VC_KEY_ALPHABET_BASE | 0x08
+#define VC_KEY_I               VC_KEY_ALPHABET_BASE | 0x09
+#define VC_KEY_J               VC_KEY_ALPHABET_BASE | 0x10
+#define VC_KEY_K               VC_KEY_ALPHABET_BASE | 0x11
+#define VC_KEY_L               VC_KEY_ALPHABET_BASE | 0x12
+#define VC_KEY_M               VC_KEY_ALPHABET_BASE | 0x13
+#define VC_KEY_N               VC_KEY_ALPHABET_BASE | 0x14
+#define VC_KEY_O               VC_KEY_ALPHABET_BASE | 0x15
+#define VC_KEY_P               VC_KEY_ALPHABET_BASE | 0x16
+#define VC_KEY_Q               VC_KEY_ALPHABET_BASE | 0x17
+#define VC_KEY_R               VC_KEY_ALPHABET_BASE | 0x18
+#define VC_KEY_S               VC_KEY_ALPHABET_BASE | 0x19
+#define VC_KEY_T               VC_KEY_ALPHABET_BASE | 0x20
+#define VC_KEY_U               VC_KEY_ALPHABET_BASE | 0x21
+#define VC_KEY_V               VC_KEY_ALPHABET_BASE | 0x22
+#define VC_KEY_W               VC_KEY_ALPHABET_BASE | 0x23
+#define VC_KEY_X               VC_KEY_ALPHABET_BASE | 0x24
+#define VC_KEY_Y               VC_KEY_ALPHABET_BASE | 0x25
+#define VC_KEY_Z               VC_KEY_ALPHABET_BASE | 0x26
+
+
+#define VC_KEY_SYMBOL_BASE     0x00004000
+#define VC_KEY_COLON           VC_KEY_SYMBOL_BASE | 0x01
+#define VC_KEY_SEMICOLON       VC_KEY_SYMBOL_BASE | 0x02
+#define VC_KEY_LESS            VC_KEY_SYMBOL_BASE | 0x03
+#define VC_KEY_EQUAL           VC_KEY_SYMBOL_BASE | 0x04
+#define VC_KEY_GREATER         VC_KEY_SYMBOL_BASE | 0x05
+#define VC_KEY_QUESTION                VC_KEY_SYMBOL_BASE | 0x06
+#define VC_KEY_AT              VC_KEY_SYMBOL_BASE | 0x07
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* __VOICE_CONTROL_KEY_DEFINES_H__ */
diff --git a/include/voice_control_manager.h b/include/voice_control_manager.h
new file mode 100644 (file)
index 0000000..f151589
--- /dev/null
@@ -0,0 +1,685 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_MANAGER_H__
+#define __VOICE_CONTROL_MANAGER_H__
+
+#include <voice_control_command.h>
+#include <voice_control_command_expand.h>
+#include <voice_control_common.h>
+
+/**
+* @addtogroup VOICE_CONTROL_MANAGER
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+
+/** 
+ * @brief Defines of audio-in type.
+*/
+#define VC_AUDIO_TYPE_BLUETOOTH                "VC_AUDIO_ID_BLUETOOTH"         /**< Bluetooth audio type */
+
+/**
+* @brief Definitions for system command type.
+* @since_tizen 2.4
+*/
+#define VC_COMMAND_TYPE_SYSTEM         4
+
+/**
+* @brief Definitions for exclusive command type.
+* @since_tizen 2.4
+*/
+#define VC_COMMAND_TYPE_EXCLUSIVE      5
+
+/**
+* @brief Definition for none message.
+*/
+#define VC_RESULT_MESSAGE_NONE                 "vc.result.message.none"
+
+/**
+* @brief Definition for failed recognition because the speech is too loud to listen.
+*/
+#define VC_RESULT_MESSAGE_ERROR_TOO_LOUD       "vc.result.message.error.too.loud"
+
+/**
+* @brief Called when client gets the all recognition results from vc-daemon.
+*
+* @remark temp_command is valid in callback function.
+*
+* @param[in] event The result event
+* @param[in] vc_cmd_list_h Command list handle
+* @param[in] result Command text
+* @param[in] msg Engine message (e.g. #VC_RESULT_MESSAGE_NONE, #VC_RESULT_MESSAGE_ERROR_TOO_LOUD)
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @return @c true to release command to client, \n @c false to wait for selecting command.
+* @pre An application registers callback function using vc_mgr_set_all_result_cb().
+*
+* @see vc_mgr_set_all_result_cb()
+* @see vc_mgr_unset_all_result_cb()
+*/
+typedef bool (*vc_mgr_all_result_cb)(vc_result_event_e event, vc_cmd_list_h vc_cmd_list, 
+                                 const char* result, const char* msg, void *user_data);
+
+/**
+* @brief Called when user speaking is detected.
+*
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers callback function using vc_mgr_set_speech_detected_cb().
+*
+* @see vc_mgr_set_speech_detected_cb()
+* @see vc_mgr_unset_speech_detected_cb()
+*/
+typedef void (*vc_mgr_begin_speech_detected_cb)(void *user_data);
+
+
+/**
+* @brief Initialize voice control manager.
+*
+* @remarks If the function succeeds, @a vc mgr must be released with vc_mgr_deinitialize().
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory
+* @retval #VC_ERROR_OPERATION_FAILED Operation fail
+*
+* @pre The state should be #VC_STATE_NONE.
+* @post If this function is called, the state will be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_deinitialize()
+*/
+int vc_mgr_initialize();
+
+/**
+* @brief Deinitialize voice control manager.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @post If this function is called, the state will be #VC_STATE_NONE.
+*
+* @see vc_mgr_deinitialize()
+*/
+int vc_mgr_deinitialize();
+
+/**
+* @brief Connects the vc-daemon. 
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+* @post If this function is called, the state will be #VC_STATE_READY.
+*
+* @see vc_mgr_unprepare()
+*/
+int vc_mgr_prepare();
+
+/**
+* @brief Disconnects the vc-daemon.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+* @post If this function is called, the state will be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_prepare()
+*/
+int vc_mgr_unprepare();
+
+/**
+* @brief Retrieves all supported languages using callback function.
+*
+* @param[in] callback Callback function to invoke
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should NOT be #VC_SERVICE_STATE_NONE.
+* @post        This function invokes vc_supported_language_cb() repeatedly for getting languages. 
+*
+* @see vc_supported_language_cb()
+* @see vc_mgr_get_current_language()
+*/
+int vc_mgr_foreach_supported_languages(vc_supported_language_cb callback, void* user_data);
+
+/**
+* @brief Gets current language set by user.
+*
+* @remark If the function succeeds, @a language must be released with free() by you when you no longer need it.
+*
+* @param[out] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n
+*                      followed by ISO 639-1 for the two-letter language code. \n
+*                      For example, "ko_KR" for Korean, "en_US" for American English.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should NOT be #VC_SERVICE_STATE_NONE.
+*
+* @see vc_mgr_foreach_supported_languages()
+*/
+int vc_mgr_get_current_language(char** language);
+
+/**
+* @brief Gets current state of voice control manager.
+*
+* @param[out] state The current state
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @pre The state should NOT be #VC_SERVICE_STATE_NONE.
+*
+* @see vc_state_changed_cb() 
+* @see vc_set_state_changed_cb()
+*/
+int vc_mgr_get_state(vc_state_e* state);
+
+/**
+* @brief Gets current state of voice control service.
+*
+* @param[out] state The current state
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @pre The state should NOT be #VC_SERVICE_STATE_NONE.
+*
+* @see vc_mgr_start()
+* @see vc_mgr_stop()
+* @see vc_mgr_cancel()
+* @see vc_set_service_state_changed_cb() 
+* @see vc_unset_service_state_changed_cb()
+*/
+int vc_mgr_get_service_state(vc_service_state_e* state);
+
+/**
+* @brief Sets demandable client list.
+*
+* @param[in] rule demandable client list rule path
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_mgr_get_demandable_client_rule() 
+*/
+int vc_mgr_set_demandable_client_rule(const char* rule);
+
+/**
+* @brief Gets demandable client list.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_mgr_set_demandable_client_rule() 
+*/
+int vc_mgr_unset_demandable_client_rule();
+
+/**
+* @brief Checks whether the command format is supported.
+*
+* @param[in] format The command format
+* @param[out] support The result status @c true = supported, @c false = not supported
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*/
+int vc_mgr_is_command_format_supported(vc_cmd_format_e format, bool* support);
+
+/**
+* @brief Sets system or exclusive commands.
+*
+* @remarks The command type is valid for VC_COMMAND_TYPE_SYSTEM or VC_COMMAND_TYPE_EXCLUSIVE.
+*      The commands should include type, command text, format.
+*
+* @param[in] vc_cmd_list The command list handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_mgr_unset_command_list() 
+*/
+int vc_mgr_set_command_list(vc_cmd_list_h vc_cmd_list);
+
+/**
+* @brief Unsets system or exclusive commands.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_mgr_set_command_list()
+*/
+int vc_mgr_unset_command_list();
+
+/**
+* @brief Retrieves all available commands.
+*
+* @remarks If the function succeeds, @a vc_cmd_list must be released with vc_cmd_list_destroy(vc_cmd_list, true).
+*
+* @param[in] vc_cmd_list The command list
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY.
+*/
+int vc_mgr_get_current_commands(vc_cmd_list_h* vc_cmd_list);
+
+/**
+* @brief Sets audio in type.
+*
+* @param[in] audio_id audio type (e.g. #VC_AUDIO_TYPE_BLUETOOTH or usb device id)
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY.
+*
+* @see vc_mgr_get_audio_type() 
+*/
+int vc_mgr_set_audio_type(const char* audio_id);
+
+/**
+* @brief Gets audio-in type.
+*
+* @remarks audio_id must be released using free() when it is no longer required.
+*
+* @param[out] audio_id audio id (e.g. #VC_AUDIO_TYPE_BLUETOOTH or usb device id)
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY.
+*
+* @see vc_mgr_set_audio_type()
+*/
+int vc_mgr_get_audio_type(char** audio_id);
+
+/**
+* @brief Starts recognition.
+*
+* @param[in] stop_by_silence Silence detection option
+* @param[in] exclusive_command_option Exclusive command option
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The state should be #VC_STATE_READY and the service state should be #VC_SERVICE_STATE_READY.
+* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n
+* If this function succeeds, the service state will be #VC_SERVICE_STATE_RECORDING.
+*
+* @see vc_mgr_stop()
+* @see vc_mgr_cancel()
+* @see vc_service_state_changed_cb()
+*/
+int vc_mgr_start(bool stop_by_silence, bool exclusive_command_option);
+
+/**
+* @brief Stop recognition.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The service state should be #VC_SERVICE_STATE_RECORDING.
+* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n
+* If this function succeeds, the service state will be #VC_SERVICE_STATE_PROCESSING.
+*
+* @see vc_mgr_start()
+* @see vc_mgr_cancel()
+* @see vc_service_state_changed_cb()
+* @see vc_mgr_result_cb()
+*/
+int vc_mgr_stop();
+
+/**
+* @brief Cancels recognition.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The service state should be #VC_SERVICE_STATE_RECORDING or #VC_SERVICE_STATE_PROCESSING.
+* @post It will invoke vc_service_state_changed_cb(), if you register a callback with vc_service_state_changed_cb(). \n
+* If this function succeeds, the service state will be #VC_SERVICE_STATE_READY.
+*
+* @see vc_mgr_start()
+* @see vc_mgr_stop()
+* @see vc_service_state_changed_cb()
+*/
+int vc_mgr_cancel();
+
+/**
+* @brief Gets the microphone volume during recording.
+*      
+* @param[out] volume Recording volume
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The service state should be #VC_SERVICE_STATE_RECORDING.
+* 
+* @see vc_mgr_start()
+*/
+int vc_mgr_get_recording_volume(float* volume);
+
+/**
+* @brief Select valid result from all results.
+*      
+* @param[in] vc_cmd_list The valid result list
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre vc_mgr_all_result_cb() should be called
+* 
+* @see vc_mgr_all_result_cb()
+*/
+int vc_mgr_set_selected_results(vc_cmd_list_h vc_cmd_list);
+
+
+/**
+* @brief Registers a callback function for getting recognition result.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_all_result_cb()
+* @see vc_mgr_unset_all_result_cb()
+*/
+int vc_mgr_set_all_result_cb(vc_mgr_all_result_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_set_all_result_cb()
+*/
+int vc_mgr_unset_all_result_cb();
+
+/**
+* @brief Registers a callback function for getting system or exclusive recognition result.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_result_cb()
+* @see vc_mgr_unset_result_cb()
+*/
+int vc_mgr_set_result_cb(vc_result_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_set_result_cb()
+*/
+int vc_mgr_unset_result_cb();
+
+/**
+* @brief Registers a callback function to be called when state is changed.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_state_changed_cb()
+* @see vc_mgr_unset_state_changed_cb()
+*/
+int vc_mgr_set_state_changed_cb(vc_state_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_set_state_changed_cb()
+*/
+int vc_mgr_unset_state_changed_cb();
+
+/**
+* @brief Registers a callback function to be called when state is changed.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_service_state_changed_cb()
+* @see vc_mgr_unset_service_state_changed_cb()
+*/
+int vc_mgr_set_service_state_changed_cb(vc_service_state_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_set_service_state_changed_cb()
+*/
+int vc_mgr_unset_service_state_changed_cb();
+
+/**
+* @brief Registers a callback function to be called when begin of speech is detected.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_begin_speech_detected_cb()
+* @see vc_mgr_unset_speech_detected_cb()
+*/
+int vc_mgr_set_speech_detected_cb(vc_mgr_begin_speech_detected_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_set_speech_detected_cb()
+*/
+int vc_mgr_unset_speech_detected_cb();
+
+/**
+* @brief Registers a callback function to be called when current language is changed.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_current_language_changed_cb()
+* @see vc_mgr_unset_current_language_changed_cb()
+*/
+int vc_mgr_set_current_language_changed_cb(vc_current_language_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_set_current_language_changed_cb()
+*/
+int vc_mgr_unset_current_language_changed_cb();
+
+/**
+* @brief Registers a callback function to be called when an error occurred.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_error_cb()
+* @see vc_mgr_unset_error_cb()
+*/
+int vc_mgr_set_error_cb(vc_error_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_mgr_set_error_cb()
+*/
+int vc_mgr_unset_error_cb();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* __VOICE_CONTROL_MANAGER_H__ */
+
diff --git a/include/voice_control_plugin_engine.h b/include/voice_control_plugin_engine.h
new file mode 100644 (file)
index 0000000..256bb48
--- /dev/null
@@ -0,0 +1,516 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_PLUGIN_ENGINE_H__
+#define __VOICE_CONTROL_PLUGIN_ENGINE_H__
+
+#include <tizen.h>
+
+/**
+* @addtogroup VOICE_CONTROL_PLUGIN_ENGINE
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** 
+* @brief Enumerations of error codes.
+*/
+typedef enum {
+       VCP_ERROR_NONE                  = TIZEN_ERROR_NONE,             /**< Successful */
+       VCP_ERROR_OUT_OF_MEMORY         = TIZEN_ERROR_OUT_OF_MEMORY,    /**< Out of Memory */
+       VCP_ERROR_IO_ERROR              = TIZEN_ERROR_IO_ERROR,         /**< I/O error */
+       VCP_ERROR_INVALID_PARAMETER     = TIZEN_ERROR_INVALID_PARAMETER,/**< Invalid parameter */
+       VCP_ERROR_OUT_OF_NETWORK        = TIZEN_ERROR_NETWORK_DOWN,     /**< Out of network */
+       VCP_ERROR_INVALID_STATE         = -0x0100031,                   /**< Invalid state */
+       VCP_ERROR_INVALID_LANGUAGE      = -0x0100032,                   /**< Invalid language */
+       VCP_ERROR_OPERATION_FAILED      = -0x0100034,                   /**< Operation failed */
+       VCP_ERROR_NOT_SUPPORTED_FEATURE = -0x0100035                    /**< Not supported feature */
+}vcp_error_e;
+
+/**
+* @brief Enumerations of audio type.
+*/
+typedef enum {
+       VCP_AUDIO_TYPE_PCM_S16_LE = 0,  /**< Signed 16bit audio type, Little endian */
+       VCP_AUDIO_TYPE_PCM_U8           /**< Unsigned 8bit audio type */
+}vcp_audio_type_e;
+
+/**
+* @brief Enumerations of callback event.
+*/
+typedef enum {
+       VCP_RESULT_EVENT_SUCCESS = 0,           /**< Event when the recognition full result is ready  */
+       VCP_RESULT_EVENT_REJECTED,              /**< Event when the recognition result is rejected */
+       VCP_RESULT_EVENT_ERROR                  /**< Event when the recognition has failed */
+}vcp_result_event_e;
+
+/**
+* @brief Enumerations of command type.
+*/
+typedef enum {
+       VCP_COMMAND_TYPE_FIXED = 0,             /**< Fixed command */
+       VCP_COMMAND_TYPE_FIXED_AND_NON_FIXED,   /**< Fixed command + Non-fixed command */
+       VCP_COMMAND_TYPE_NON_FIXED_AND_FIXED    /**< Non-fixed command + Fixed command */
+}vcp_command_type_e;
+
+/**
+* @brief Enumerations of speech detect.
+*/
+typedef enum {
+       VCP_SPEECH_DETECT_NONE = 0,     /**< No event */
+       VCP_SPEECH_DETECT_BEGIN,        /**< Begin of speech detected */
+       VCP_SPEECH_DETECT_END,          /**< End of speech detected */
+}vcp_speech_detect_e;
+
+/** 
+* @brief A structure of handle for VC command
+*/
+typedef int vcp_cmd_h;
+
+/** 
+ * @brief Defines of bluetooth audio id.
+*/
+#define VCP_AUDIO_ID_BLUETOOTH         "VC_AUDIO_ID_BLUETOOTH"         /**< Bluetooth audio id */
+
+/**
+* @brief Definition for none message.
+*/
+#define VC_RESULT_MESSAGE_NONE                 "vc.result.message.none"
+
+/**
+* @brief Definition for failed recognition because the speech is too loud to listen.
+*/
+#define VC_RESULT_MESSAGE_ERROR_TOO_LOUD       "vc.result.message.error.too.loud"
+
+
+/** 
+* @brief Called when the daemon gets synthesized result.
+* 
+* @param[in] event A result event
+* @param[in] result_id Result ids
+* @param[in] count Result count
+* @param[in] all_result All result text
+* @param[in] non_fixed_result Non-fixed command result text
+* @param[in] msg Engine message (e.g. #VC_RESULT_MESSAGE_NONE, #VC_RESULT_MESSAGE_ERROR_TOO_LOUD)
+* @param[in] user_data The user data passed from the start synthesis function
+*
+* @pre vcpe_stop() will invoke this callback.
+*
+* @see vcpe_stop()
+*/
+typedef void (*vcpe_result_cb)(vcp_result_event_e event, int* result_id, int count, 
+                              const char* all_result, const char* non_fixed_result, const char* msg, void *user_data);
+
+/**
+* @brief Called to retrieve the supported languages. 
+*
+* @param[in] language A language is specified as an ISO 3166 alpha-2 two letter country-code
+*              followed by ISO 639-1 for the two-letter language code \n
+*              For example, "ko_KR" for Korean, "en_US" for American English
+* @param[in] user_data The user data passed from the foreach function
+*
+* @return @c true to continue with the next iteration of the loop \n @c false to break out of the loop
+*
+* @pre vcpe_foreach_supported_languages() will invoke this callback. 
+*
+* @see vcpe_foreach_supported_languages()
+*/
+typedef bool (*vcpe_supported_language_cb)(const char* language, void* user_data);
+
+/**
+* @brief Initializes the engine.
+*
+* @param[in] result_cb A callback function for recognition result
+* @param[in] silence_cb A callback function for silence detection
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_INVALID_STATE Already initialized
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failed
+* 
+* @see vcpe_deinitialize()
+*/
+typedef int (* vcpe_initialize)(void);
+
+/**
+* @brief Deinitializes the engine
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_STATE Not initialized
+* 
+* @see vcpe_initialize()
+*/
+typedef void (* vcpe_deinitialize)(void);
+
+/**
+* @brief Registers a callback function for getting recognition result.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @see vcpe_result_cb()
+*/
+typedef int (* vcpe_set_result_cb)(vcpe_result_cb callback, void* user_data);
+
+/**
+* @brief Gets recording format of the engine.
+*
+* @param[in] audio_id The audio device id.
+* @param[out] types The format used by the recorder.
+* @param[out] rate The sample rate used by the recorder.
+* @param[out] channels The number of channels used by the recorder.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Not initialized
+*/
+typedef int (* vcpe_get_recording_format)(const char* audio_id, vcp_audio_type_e* types, int* rate, int* channels);
+
+/**
+* @brief Retrieves all supported languages of the engine.
+*
+* @param[in] callback a callback function
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_INVALID_STATE Not initialized
+*
+* @post        This function invokes vcpe_supported_language_cb() repeatedly for getting supported languages. 
+*
+* @see vcpe_supported_language_cb()
+*/
+typedef int (* vcpe_foreach_supported_languages)(vcpe_supported_language_cb callback, void* user_data);
+
+/**
+* @brief Checks whether a language is supported or not.
+*
+* @param[in] language A language
+*
+* @return @c true = supported, \n @c false = not supported.
+*/
+typedef bool (* vcpe_is_language_supported)(const char* language);
+
+/**
+* @brief Sets language. 
+*
+* @param[in] language language.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_LANGUAGE Invalid language
+* @retval #VCP_ERROR_INVALID_STATE Not initialized
+*/
+typedef int (*vcpe_set_language)(const char* language);
+
+/**
+* @brief Sets command list before recognition.
+*
+* @remark This function should set commands via vcpd_foreach_command().
+*
+* @param[in] vcp_command command handle. 
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_INVALID_STATE Invalid state
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failed
+* @retval #VCP_ERROR_NOT_SUPPORTED_FEATURE Not supported command type
+*
+* @post vcpe_start() is called after this function is successful.
+*
+* @see vcpe_start()
+* @see vcpd_foreach_command()
+* @see vcpe_unset_commands()
+*/
+typedef int (* vcpe_set_commands)(vcp_cmd_h vcp_command);
+
+/**
+* @brief Unset command list for reset.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_INVALID_STATE Invalid state
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failed
+*
+* @see vcpe_set_commands()
+*/
+typedef int (* vcpe_unset_commands)();
+
+/**
+* @brief Start recognition.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_INVALID_STATE Invalid state
+* @retval #VCP_ERROR_INVALID_LANGUAGE Invalid language
+* @retval #VCP_ERROR_OUT_OF_NETWORK Out of network
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre vcpd_foreach_command() is successful.
+*
+* @see vcpe_set_recording_data()
+* @see vcpe_stop()
+* @see vcpe_cancel()
+*/
+typedef int (* vcpe_start)(bool stop_by_silence);
+
+/**
+* @brief Sets recording data for speech recognition from recorder. 
+*
+* @remark This function should be returned immediately after recording data copy. 
+* 
+* @param[in] data A recording data
+* @param[in] length A length of recording data
+* @param[out] silence_detected @c true Silence detected \n @c false No silence detected
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_INVALID_STATE Invalid state
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre vcpe_start() is successful.
+*
+* @see vcpe_start()
+* @see vcpe_cancel()
+* @see vcpe_stop()
+*/
+typedef int(*vcpe_set_recording_data)(const void* data, unsigned int length, vcp_speech_detect_e* speech_detected);
+
+/**
+* @brief Stops to get the result of recognition.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_STATE Invalid state
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failed
+* @retval #VCP_ERROR_OUT_OF_NETWORK Out of network
+*
+* @pre vcpe_set_recording_data() is successful.
+*
+* @see vcpe_start()
+* @see vcpe_set_recording_data()
+* @see vcpe_result_cb()
+* @see vcpe_cancel()
+*/
+typedef int (* vcpe_stop)(void);
+
+/**
+* @brief Cancels the recognition process.
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VCP_ERROR_NONE Successful.
+* @retval #VCP_ERROR_INVALID_STATE Invalid state.
+*
+* @pre vcpe_start() is successful.
+*
+* @see vcpe_start()
+* @see vcpe_stop()
+*/
+typedef int (* vcpe_cancel)(void);
+
+
+/**
+* Daemon API.
+*/
+
+/**
+* @brief Called to retrieve the commands. 
+*
+* @param[in] id command id
+* @param[in] type command type
+* @param[in] command command text
+* @param[in] param parameter text
+* @param[in] domain command domain
+* @param[in] user_data The user data passed from the foreach function
+*
+* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop.
+* @pre vcpd_foreach_command() will invoke this callback. 
+*
+* @see vcpd_foreach_command()
+*/
+typedef bool (* vcpd_foreach_command_cb)(int id, int type, const char* command, const char* param, int domain, void* user_data);
+
+/**
+* @brief Retrieves all commands using callback function.
+*
+* @param[in] vcp_command The handle to be passed to the vcpe_set_commands() function
+* @param[in] callback The callback function to invoke
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failure
+* @retval #VCP_ERROR_INVALID_STATE Invalid state
+*
+* @post        This function invokes vcpd_foreach_command_cb() repeatedly for getting commands. 
+*
+* @see vcpd_foreach_command_cb()
+* @see vcpe_set_commands()
+*/
+typedef int (* vcpd_foreach_command)(vcp_cmd_h vcp_command, vcpd_foreach_command_cb callback, void* user_data);
+
+/**
+* @brief Gets command length.
+*
+* @param[in] vcp_command The handle to be passed to the vcpe_set_commands() function
+*
+* @return the value greater than 0 on success, otherwise a negative error value
+*
+* @see vcpe_set_commands()
+*/
+typedef int (* vcpd_get_command_count)(vcp_cmd_h vcp_command);
+
+/**
+* @brief Gets current audio type.
+*
+* @remarks audio_type must be released using free() when it is no longer required.
+*
+* @param[in] audio_type Current audio type  (e.g. #VCP_AUDIO_ID_BLUETOOTH or usb device id)
+*
+* @return the value greater than 0 on success, otherwise a negative error value
+*
+*/
+typedef int (* vcpd_get_audio_type)(char** audio_type);
+
+/**
+* @brief A structure of the engine functions.
+*/
+typedef struct {
+       int size;                                               /**< Size of structure */
+       int version;                                            /**< Version */
+
+       vcpe_initialize                 initialize;             /**< Initialize engine */
+       vcpe_deinitialize               deinitialize;           /**< Shutdown engine */
+
+       /* Get engine information */
+       vcpe_get_recording_format       get_recording_format;   /**< Get recording format */
+       vcpe_foreach_supported_languages foreach_langs;         /**< Foreach language list */
+       vcpe_is_language_supported      is_lang_supported;      /**< Check language */
+
+       /* Set info */
+       vcpe_set_result_cb              set_result_cb;          /**< Set result callback */
+       vcpe_set_language               set_language;           /**< Set language */
+       vcpe_set_commands               set_commands;           /**< Request to set current commands */
+       vcpe_unset_commands             unset_commands;         /**< Request to unset current commands */
+
+       /* Control recognition */
+       vcpe_start                      start;                  /**< Start recognition */
+       vcpe_set_recording_data         set_recording;          /**< Set recording data */
+       vcpe_stop                       stop;                   /**< Stop recording for getting result */
+       vcpe_cancel                     cancel;                 /**< Cancel recording and processing */
+} vcpe_funcs_s;
+
+/**
+* @brief A structure of the daemon functions.
+*/
+typedef struct {
+       int size;                                               /**< Size of structure */
+       int version;                                            /**< Version */
+
+       vcpd_foreach_command            foreach_command;        /**< Foreach command */
+       vcpd_get_command_count          get_command_count;      /**< Get command count */
+
+       vcpd_get_audio_type             get_audio_type;         /**< Get audio type */
+} vcpd_funcs_s;
+
+/**
+* @brief Loads the engine. 
+*
+* @param[in] pdfuncs The daemon functions
+* @param[out] pefuncs The engine functions
+*
+* @return This function returns zero on success, or negative with error code on failure
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre The vcp_get_engine_info() should be successful.
+* @post The daemon calls engine functions of vcpe_funcs_s.
+*
+* @see vcp_get_engine_info()
+* @see vcp_unload_engine()
+*/
+int vcp_load_engine(vcpd_funcs_s* pdfuncs, vcpe_funcs_s* pefuncs);
+
+/**
+* @brief Unloads this engine by the daemon. 
+*
+* @pre The vcp_load_engine() should be successful.
+*
+* @see vcp_load_engine()
+*/
+void vcp_unload_engine(void);
+
+/**
+* @brief Called to get the engine base information.
+*
+* @param[in] engine_uuid The engine id
+* @param[in] engine_name The engine name
+* @param[in] engine_setting The setting ug name
+* @param[in] use_network @c true to need network @c false not to need network.
+* @param[in] user_data The User data passed from vcp_get_engine_info()
+*
+* @pre vcp_get_engine_info() will invoke this callback. 
+*
+* @see vcp_get_engine_info()
+*/
+typedef void (*vcpe_engine_info_cb)(const char* engine_uuid, const char* engine_name, const char* engine_setting, 
+                                   bool use_network, void* user_data);
+
+/**
+* @brief Gets the engine base information before the engine is loaded by the daemon. 
+*
+* @param[in] callback Callback function
+* @param[in] user_data User data to be passed to the callback function
+*
+* @return This function returns zero on success, or negative with error code on failure
+* @retval #VCP_ERROR_NONE Successful
+* @retval #VCP_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VCP_ERROR_OPERATION_FAILED Operation failed
+*
+* @post        This function invokes vcpe_engine_info_cb() for getting engine information.
+*
+* @see vcpe_engine_info_cb()
+* @see vcp_load_engine()
+*/
+int vcp_get_engine_info(vcpe_engine_info_cb callback, void* user_data);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+* @}@}
+*/
+
+#endif /* __VOICE_CONTROL_PLUGIN_ENGINE_H__ */
diff --git a/include/voice_control_setting.h b/include/voice_control_setting.h
new file mode 100644 (file)
index 0000000..28ed805
--- /dev/null
@@ -0,0 +1,245 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_SETTING_H__
+#define __VOICE_CONTROL_SETTING_H__
+
+#include <stdbool.h>
+
+
+/**
+* @addtogroup VOICE_CONTROL_SETTING_MODULE
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* @brief Defines of audio-in type.
+*/
+#define VC_SETTING_LANGUAGE_AUTO       "auto"
+
+/**
+* @brief Called when voice control service enabled is changed.
+*
+* @param[in] enabled Service enabled
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers this callback to detect changing service enabled.
+*
+* @see vc_setting_set_enabled_changed_cb()
+*/
+typedef void (*vc_setting_enabled_changed_cb)(bool enabled, void* user_data);
+
+/**
+* @brief Called to retrieve supported language.
+* @since_tizen 2.4
+*
+* @param[in] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n
+*              followed by ISO 639-1 for the two-letter language code. \n
+*              For example, "ko_KR" for Korean, "en_US" for American English.
+* @param[in] user_data The user data passed from the foreach function
+*
+* @return @c true to continue with the next iteration of the loop, \n @c false to break out of the loop.
+*
+* @pre The function will invoke this callback.
+*/
+typedef bool(*vc_setting_supported_language_cb)(const char* language, void* user_data);
+
+
+/**
+* @brief Initialize voice control setting 
+*
+* @remarks If the function succeeds, @a vc mgr must be released with vc_setting_finalize().
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_STATE VC setting has Already been initialized. 
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @see vc_setting_finalize()
+*/
+int vc_setting_initialize(void);
+
+/**
+* @brief Deinitialize vc setting
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized. 
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @see vc_setting_initialize()
+*/
+int vc_setting_deinitialize(void);
+
+/**
+* @brief Get supported languages of current engine
+*
+* @param[in] callback callback function
+* @param[in] user_data User data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized. 
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @post        This function invokes vc_setting_supported_language_cb() repeatedly for getting supported languages. 
+*
+* @see vc_setting_supported_language_cb()
+*/
+int vc_setting_foreach_supported_languages(vc_setting_supported_language_cb callback, void* user_data);
+
+/**
+* @brief Get the default language.
+*
+* @remark If the function is success, @a language must be released with free() by you.
+*
+* @param[out] language current language
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory.
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized. 
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @see vc_setting_set_language()
+*/
+int vc_setting_get_language(char** language);
+
+/**
+* @brief Set the default language.
+*
+* @param[in] language language
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized. 
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @see vc_setting_get_language()
+*/
+int vc_setting_set_language(const char* language);
+
+/**
+* @brief Set a automatic option of language.
+*
+* @param[in] value The automatic option
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized. 
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @see vc_setting_get_auto_language()
+*/
+int vc_setting_set_auto_language(bool value);
+
+/**
+* @brief Get a automatic option of voice.
+*
+* @param[out] value The automatic option
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized. 
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @see vc_setting_set_auto_language()
+*/
+int vc_setting_get_auto_language(bool* value);
+
+/**
+* @brief Set voice control service enabled.
+*
+* @param[in] value The enabled option
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized.
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @see vc_setting_get_enabled()
+*/
+int vc_setting_set_enabled(bool value);
+
+/**
+* @brief Get voice control service enabled.
+*
+* @param[out] value The enabled option
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized.
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @see vc_setting_set_enabled()
+*/
+int vc_setting_get_enabled(bool* value);
+
+/**
+* @brief Sets a callback function to be called when service enabled is changed.
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value.
+* @retval #VC_ERROR_NONE Success.
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter.
+* @retval #VC_ERROR_INVALID_STATE VC Not initialized.
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure.
+*
+* @pre vc_setting_initialize() should be successful.
+*
+* @see vc_setting_unset_enabled_changed_cb()
+*/
+int vc_setting_set_enabled_changed_cb(vc_setting_enabled_changed_cb callback, void* user_data);
+
+/**
+* @brief Unsets the callback function.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ELM_ERROR_NONE Successful
+* @retval #VC_ELM_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ELM_ERROR_PERMISSION_DENIED Permission denied
+* @retval #VC_ELM_ERROR_NOT_SUPPORTED Not supported
+*
+* @pre vc_setting_initialize() should be successful.
+*
+* @see vc_setting_set_enabled_changed_cb()
+*/
+int vc_setting_unset_enabled_changed_cb();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+* @}
+*/
+
+#endif /* __VOICE_CONTROL_SETTING_H__ */
diff --git a/include/voice_control_widget.h b/include/voice_control_widget.h
new file mode 100644 (file)
index 0000000..fb00d77
--- /dev/null
@@ -0,0 +1,527 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VOICE_CONTROL_WIDGET_H__
+#define __VOICE_CONTROL_WIDGET_H__
+
+#include <voice_control_command.h>
+#include <voice_control_command_expand.h>
+#include <voice_control_common.h>
+
+
+/**
+* @addtogroup VOICE_CONTROL_WIDGET
+* @{
+*/
+
+#ifdef __cplusplus
+extern "C" 
+{
+#endif
+
+/**
+* @brief Definitions for widget command type.
+* @since_tizen 2.4
+*/
+#define VC_COMMAND_TYPE_WIDGET         3
+
+/**
+* @brief Called when widget should show or hide tooltip.
+*
+* @param[in] vc_widget The voice control handle
+* @param[in] show Show or hide option
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers callback function using vc_widget_set_show_tooltip_cb().
+*
+* @see vc_widget_set_show_tooltip_cb()
+* @see vc_widget_unset_show_tooltip_cb()
+*/
+typedef void (*vc_widget_show_tooltip_cb)(bool show, void* user_data);
+
+/**
+* @brief Called when widget send current command list to vc daemon.
+*
+* @param[in] vc_widget The voice control handle
+* @param[out] vc_cmd_list Current command list
+* @param[in] user_data The user data passed from the callback registration function
+*
+* @pre An application registers callback function using vc_widget_set_send_current_command_group_cb().
+*
+* @see vc_widget_set_send_current_command_list_cb()
+* @see vc_widget_unsset_send_current_command_list_cb()
+*/
+typedef void (*vc_widget_send_current_command_list_cb)(vc_cmd_list_h* vc_cmd_list, void* user_data);
+
+
+/**
+* @brief Initialize voice control for widget. 
+*
+* @param[in] vc_widget The voice control handle
+*
+* @remarks If the function succeeds, @a vc widget must be released with vc_widget_deinitialize().
+*
+* @param[out] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @post If this function is called, the state will be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_deinitialize()
+*/
+int vc_widget_initialize();
+
+/**
+* @brief Deinitialize voice control for widget.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @see vc_widget_initialize()
+*/
+int vc_widget_deinitialize();
+
+/**
+* @brief Connects the voice control service asynchronously.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+* @post If this function is called, the state will be #VC_STATE_READY.
+*
+* @see vc_widget_unprepare()
+*/
+int vc_widget_prepare();
+
+/**
+* @brief Disconnects the voice control service.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+* @post If this function is called, the state will be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_prepare()
+*/
+int vc_widget_unprepare();
+
+/**
+* @brief Retrieves all supported languages using callback function.
+*
+* @param[in] vc_widget The voice control handle
+* @param[in] callback Callback function to invoke
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+* @post        This function invokes vc_supported_language_cb() repeatedly for getting languages. 
+*
+* @see vc_supported_language_cb()
+* @see vc_widget_get_current_language()
+*/
+int vc_widget_foreach_supported_languages(vc_supported_language_cb callback, void* user_data);
+
+/**
+* @brief Gets current language set by user.
+*
+* @remark If the function succeeds, @a language must be released with free() by you when you no longer need it.
+*
+* @param[in] vc_widget The voice control handle
+* @param[out] language A language is specified as an ISO 3166 alpha-2 two letter country-code \n
+*                      followed by ISO 639-1 for the two-letter language code. \n
+*                      For example, "ko_KR" for Korean, "en_US" for American English.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OUT_OF_MEMORY Out of memory
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*
+* @see vc_widget_foreach_supported_languages()
+*/
+int vc_widget_get_current_language(char** language);
+
+/**
+* @brief Gets current state of voice control widget.
+*
+* @param[in] vc_widget The voice control handle
+* @param[out] state Current state
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @see vc_widget_initialize()
+* @see vc_widget_deinitialize()
+* @see vc_widget_prepare()
+* @see vc_widget_unprepare()
+* @see vc_widget_set_state_changed_cb() 
+* @see vc_widget_unset_state_changed_cb()
+*/
+int vc_widget_get_state(vc_state_e* state);
+
+/**
+* @brief Gets current state of voice control service.
+*
+* @param[in] vc_widget The voice control handle
+* @param[out] state The current state
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+*
+* @see vc_widget_start()
+* @see vc_widget_stop()
+* @see vc_widget_cancel()
+* @see vc_set_service_state_changed_cb()
+* @see vc_unset_service_state_changed_cb()
+*/
+int vc_widget_get_service_state(vc_service_state_e* state);
+
+/**
+* @brief Checks whether the command format is supported.
+*
+* @param[in] vc_widget The voice control handle
+* @param[in] format The command format
+* @param[out] support The result status @c true = supported, @c false = not supported
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_READY.
+*/
+int vc_widget_is_command_format_supported(vc_cmd_format_e format, bool* support);
+
+
+/**
+* @brief Sets foreground state of application.
+*
+* @param[in] vc_widget The voice control handle
+* @param[in] value value @c true foreground, \n @c false background.
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failed
+*
+* @pre The state should be #VC_STATE_READY.
+*/
+int vc_widget_set_foreground(bool value);
+
+/**
+* @brief Cancels recognition.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_OUT_OF_MEMORY Not enough memory
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+* @retval #VC_ERROR_OPERATION_FAILED Operation failure
+*
+* @pre The service state should be #VC_SERVICE_STATE_RECORDING or #VC_SERVICE_STATE_PROCESSING.
+* @post It will invoke vc_state_changed_cb(), if you register a callback with vc_state_changed_cb(). \n
+* If this function succeeds, the state will be #VC_STATE_READY.
+*
+* @see vc_widget_start()
+* @see vc_widget_stop()
+* @see vc_state_changed_cb()
+*/
+int vc_widget_cancel();
+
+/**
+* @brief Registers a callback function for getting recognition result.
+*
+* @param[in] vc_widget The voice control handle
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_result_cb()
+* @see vc_widget_unset_result_cb()
+*/
+int vc_widget_set_result_cb(vc_result_cb callback, void* user_data);
+
+
+/**
+* @brief Unregisters the callback function.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_set_result_cb()
+*/
+int vc_widget_unset_result_cb();
+
+/**
+* @brief Registers a callback function for showing or hiding tooltip.
+*
+* @param[in] vc_widget The voice control handle
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_show_tooltip_cb()
+* @see vc_widget_unset_show_tooltip_cb()
+*/
+int vc_widget_set_show_tooltip_cb(vc_widget_show_tooltip_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_set_show_tooltip_cb()
+*/
+int vc_widget_unset_show_tooltip_cb();
+
+/**
+* @brief Registers a callback function for setting current command.
+*
+* @param[in] vc_widget The voice control handle
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_send_current_command_list_cb()
+* @see vc_widget_unset_send_current_command_list_cb()
+*/
+int vc_widget_set_send_current_command_list_cb(vc_widget_send_current_command_list_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_set_send_current_command_list_cb()
+*/
+int vc_widget_unsset_send_current_command_list_cb();
+
+/**
+* @brief Registers a callback function to be called when service state is changed.
+*
+* @param[in] vc_widget The voice control handle
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_service_state_changed_cb()
+* @see vc_widget_unset_service_state_changed_cb()
+*/
+int vc_widget_set_service_state_changed_cb(vc_service_state_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_set_service_state_changed_cb()
+*/
+int vc_widget_unset_service_state_changed_cb();
+
+/**
+* @brief Registers a callback function for getting state changed.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_state_changed_cb()
+* @see vc_widget_unset_state_changed_cb()
+*/
+int vc_widget_set_state_changed_cb(vc_state_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_set_state_changed_cb()
+*/
+int vc_widget_unset_state_changed_cb();
+
+/**
+* @brief Registers a callback function to be called when current language is changed.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_current_language_changed_cb()
+* @see vc_widget_unset_current_language_changed_cb()
+*/
+int vc_widget_set_current_language_changed_cb(vc_current_language_changed_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_set_current_language_changed_cb()
+*/
+int vc_widget_unset_current_language_changed_cb();
+
+/**
+* @brief Registers a callback function for an error occurred.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @param[in] callback Callback function to register
+* @param[in] user_data The user data to be passed to the callback function
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_PARAMETER Invalid parameter
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_error_cb()
+* @see vc_widget_unset_error_cb()
+*/
+int vc_widget_set_error_cb(vc_error_cb callback, void* user_data);
+
+/**
+* @brief Unregisters the callback function.
+*
+* @param[in] vc_widget The voice control handle
+*
+* @return 0 on success, otherwise a negative error value
+* @retval #VC_ERROR_NONE Successful
+* @retval #VC_ERROR_INVALID_STATE Invalid state
+*
+* @pre The state should be #VC_STATE_INITIALIZED.
+*
+* @see vc_widget_set_error_cb()
+*/
+int vc_widget_unset_error_cb();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+/**
+ * @}@}
+ */
+
+#endif /* __VOICE_CONTROL_WIDGET_H__ */
diff --git a/packaging/voice-control-devel.manifest b/packaging/voice-control-devel.manifest
new file mode 100644 (file)
index 0000000..c00c25b
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+        <request>
+                <domain name="_" />
+        </request>
+</manifest>
diff --git a/packaging/voice-control.manifest b/packaging/voice-control.manifest
new file mode 100644 (file)
index 0000000..c00c25b
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+        <request>
+                <domain name="_" />
+        </request>
+</manifest>
diff --git a/packaging/voice-control.spec b/packaging/voice-control.spec
new file mode 100644 (file)
index 0000000..5e3b8c8
--- /dev/null
@@ -0,0 +1,157 @@
+Name:       voice-control
+Summary:    Voice control client library and daemon
+Version:    0.2.7
+Release:    1
+Group:      Graphics & UI Framework/Voice Framework
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+Source1001: %{name}.manifest
+Source1002: %{name}-devel.manifest
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+BuildRequires:  pkgconfig(aul)
+BuildRequires:  pkgconfig(capi-base-common)
+BuildRequires:  pkgconfig(capi-media-audio-io)
+BuildRequires:  pkgconfig(capi-media-sound-manager)
+BuildRequires:  pkgconfig(capi-network-bluetooth)
+BuildRequires:  pkgconfig(dbus-1)
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(ecore)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(libprivilege-control)
+BuildRequires:  pkgconfig(libxml-2.0)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  cmake
+
+%description
+Voice Control client library and daemon
+
+
+%package devel
+Summary:    Voice control header files for VC development
+Group:      libdevel
+Requires:   %{name} = %{version}-%{release}
+
+%description devel
+Voice control header files for VC development.
+
+
+%package widget-devel
+Summary:    Voice control widget header files for VC development
+Group:      libdevel
+Requires:   %{name} = %{version}-%{release}
+
+%description widget-devel
+Voice control widget header files for VC development.
+
+
+%package manager-devel
+Summary:    Voice control manager header files for VC development
+Group:      libdevel
+Requires:   %{name} = %{version}-%{release}
+
+%description manager-devel
+Voice control manager header files for VC development.
+
+
+%package setting-devel
+Summary:    Voice control setting header files for VC development
+Group:      libdevel
+Requires:   %{name} = %{version}-%{release}
+
+%description setting-devel
+Voice control setting header files for VC development.
+
+
+%package engine-devel
+Summary:    Voice control engine header files for VC development
+Group:      libdevel
+Requires:   %{name} = %{version}-%{release}
+
+%description engine-devel
+Voice control engine header files for VC development.
+
+%prep
+%setup -q -n %{name}-%{version}
+cp %{SOURCE1001} %{SOURCE1002} .
+
+
+%build
+%if 0%{?tizen_build_binary_release_type_eng}
+export CFLAGS="$CFLAGS -DTIZEN_ENGINEER_MODE"
+export CXXFLAGS="$CXXFLAGS -DTIZEN_ENGINEER_MODE"
+export FFLAGS="$FFLAGS -DTIZEN_ENGINEER_MODE"
+%endif
+cmake . -DCMAKE_INSTALL_PREFIX=/usr -DLIBDIR=%{_libdir} -DINCLUDEDIR=%{_includedir}
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+mkdir -p %{buildroot}/usr/share/license
+install LICENSE %{buildroot}/usr/share/license/%{name}
+
+%make_install
+
+%post
+/sbin/ldconfig
+
+mkdir -p /usr/share/voice/vc
+chsmack -a '_' /usr/share/voice/vc
+
+mkdir -p /opt/home/app/.voice/vc
+chown 5000:5000 /opt/home/app/.voice/vc
+
+%postun -p /sbin/ldconfig
+
+%files
+%manifest %{name}.manifest
+%defattr(-,root,root,-)
+%{_libdir}/libvc.so
+%{_libdir}/libvc_setting.so
+%{_libdir}/libvc_widget.so
+%{_libdir}/libvc_manager.so
+%{_bindir}/vc-daemon
+/usr/lib/voice/vc/1.0/vc-config.xml
+/usr/share/license/%{name}
+
+%files devel
+%manifest %{name}-devel.manifest
+%defattr(-,root,root,-)
+%{_libdir}/pkgconfig/voice-control.pc
+%{_includedir}/voice_control.h
+%{_includedir}/voice_control_authority.h
+%{_includedir}/voice_control_command.h
+%{_includedir}/voice_control_common.h
+%{_includedir}/voice_control_key_defines.h
+%{_includedir}/voice_control_command_expand.h
+
+%files widget-devel
+%defattr(-,root,root,-)
+%{_libdir}/pkgconfig/voice-control-widget.pc
+%{_includedir}/voice_control_widget.h
+%{_includedir}/voice_control_command.h
+%{_includedir}/voice_control_common.h
+%{_includedir}/voice_control_key_defines.h
+%{_includedir}/voice_control_command_expand.h
+
+%files manager-devel
+%defattr(-,root,root,-)
+%{_libdir}/pkgconfig/voice-control-manager.pc
+%{_includedir}/voice_control_manager.h
+%{_includedir}/voice_control_command.h
+%{_includedir}/voice_control_common.h
+%{_includedir}/voice_control_key_defines.h
+%{_includedir}/voice_control_command_expand.h
+
+%files setting-devel
+%defattr(-,root,root,-)
+%{_libdir}/pkgconfig/voice-control-setting.pc
+%{_includedir}/voice_control_command.h
+%{_includedir}/voice_control_common.h
+%{_includedir}/voice_control_setting.h
+
+%files engine-devel
+%defattr(-,root,root,-)
+%{_libdir}/pkgconfig/voice-control-engine.pc
+%{_includedir}/voice_control_plugin_engine.h
diff --git a/server/CMakeLists.txt b/server/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c986dcc
--- /dev/null
@@ -0,0 +1,33 @@
+SET(SRCS
+       ../common/vc_command.c
+       ../common/vc_config_mgr.c
+       ../common/vc_config_parser.c
+       ../common/vc_info_parser.c
+       vcd_client_data.c
+       vcd_config.c
+       vcd_dbus_server.c
+       vcd_dbus.c
+       vcd_engine_agent.c
+       vcd_main.c
+       vcd_recorder.c
+       vcd_server.c
+)
+
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/common)
+INCLUDE_DIRECTORIES(${CMAKE_BINARY_DIR}/include)
+
+FOREACH(flag ${pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIE")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g -fPIE")
+SET(CMAKE_C_FLAGS_RELEASE "-O2 -fPIE")
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -pie")
+
+## Executable ##
+ADD_EXECUTABLE("${PROJECT_NAME}-daemon" ${SRCS})
+TARGET_LINK_LIBRARIES("${PROJECT_NAME}-daemon" -ldl -lm ${pkgs_LDFLAGS})
+
+## Install
+INSTALL(TARGETS "${PROJECT_NAME}-daemon" DESTINATION bin)
diff --git a/server/vcd_client_data.c b/server/vcd_client_data.c
new file mode 100644 (file)
index 0000000..8ae7b33
--- /dev/null
@@ -0,0 +1,1359 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include <aul.h>
+#include "vcd_client_data.h"
+#include "vcd_config.h"
+#include "vcd_main.h"
+
+/* Client list */
+static GSList* g_client_list = NULL;
+
+static GSList* g_widget_list = NULL;
+
+static manager_info_s g_manager;
+
+/* Command list */
+static current_commands_list_s g_cur_cmd_list;
+
+/* Demandable client list */
+static GSList* g_demandable_client = NULL;
+
+/* Runtime info */
+static bool g_silence_detection;
+
+
+/* Function definitions */
+widget_info_s* __widget_get_element(int pid);
+
+vc_client_info_s* __client_get_element(int pid);
+
+
+int vcd_client_manager_set(int pid)
+{
+       if (-1 != g_manager.pid) {
+               SLOG(LOG_DEBUG, TAG_VCD, "Manager has already registered");
+               return -1;
+       }
+       g_manager.pid = pid;
+       g_manager.manager_cmd = false;
+       g_manager.exclusive_cmd_option = false;
+
+       return 0;
+}
+
+int vcd_client_manager_unset()
+{
+       g_manager.pid = -1;
+       g_manager.manager_cmd = false;
+       g_manager.exclusive_cmd_option = false;
+
+       return 0;
+}
+
+bool vcd_client_manager_is_valid(int pid)
+{
+       if (-1 == g_manager.pid || pid == g_manager.pid) {
+               return true;
+       }
+       return false;
+}
+
+int vcd_client_manager_set_command(int pid)
+{
+       if (pid != g_manager.pid) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] pid(%d) is NOT valid", pid);
+               return -1;
+       }
+       g_manager.manager_cmd = true;
+       return 0;
+}
+
+int vcd_client_manager_unset_command(int pid)
+{
+       if (pid != g_manager.pid) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] pid(%d) is NOT valid", pid);
+               return -1;
+       }
+       g_manager.manager_cmd = false;
+       return 0;
+}
+
+int vcd_client_manager_set_demandable_client(int pid, GSList* client_list)
+{
+       if (0 != g_slist_length(g_demandable_client)) {
+               /* releaes data */
+               GSList *iter = NULL;
+               vc_demandable_client_s* temp_client;
+               iter = g_slist_nth(g_demandable_client, 0);
+               
+               while (NULL != iter) {
+                       temp_client = iter->data;
+
+                       if (NULL != temp_client) {
+                               if (NULL != temp_client->appid)         free(temp_client->appid);
+                               free(temp_client);
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+               g_demandable_client = NULL;
+       }
+
+       g_demandable_client = client_list;
+
+       return 0;
+}
+
+bool vcd_client_manager_check_demandable_client(int pid)
+{
+       if (0 == g_slist_length(g_demandable_client)) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] All client is available to request start");
+               return true;
+       }
+
+       /* Check demandable appid */
+       char appid[128] = {0, };
+       aul_app_get_appid_bypid(pid, appid, sizeof(appid));
+       
+       if (0 < strlen(appid)) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] %s(%d) requests start", appid, pid);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] daemon(%d) requests start", pid);
+       }
+
+       /* Compare appid */
+       GSList *iter = NULL;
+       vc_demandable_client_s* temp_client;
+       iter = g_slist_nth(g_demandable_client, 0);
+       
+       while (NULL != iter) {
+               temp_client = iter->data;
+
+               if (NULL != temp_client) {
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] demandable appid(%s)", temp_client->appid);
+
+                       if (NULL != temp_client->appid) {
+                               if (0 == strcmp(temp_client->appid, appid)) {
+                                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] pid(%d) is available", pid);
+                                       return true;
+                               }
+                       } else {
+                               if (0 == strlen(appid)) {
+                                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] pid(%d) is available", pid);
+                                       return true;
+                               }
+                       }
+               }
+
+               iter = g_slist_next(iter);
+       }
+
+       return false;
+}
+
+bool vcd_client_manager_get_exclusive()
+{
+       return g_manager.exclusive_cmd_option;
+}
+
+int vcd_client_manager_set_exclusive(bool value)
+{
+       g_manager.exclusive_cmd_option = value;
+       return 0;
+}
+
+int vcd_client_manager_get_pid()
+{
+       return g_manager.pid;
+}
+
+int __vcd_client_release_commands()
+{
+       g_cur_cmd_list.total_cmd_count = 0;
+       g_cur_cmd_list.foreground = VC_NO_FOREGROUND_PID;
+
+       GSList *iter = NULL;
+       vc_cmd_s* temp_cmd;
+
+       if (0 < g_slist_length(g_cur_cmd_list.widget_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.widget_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       if (NULL != temp_cmd) {
+                               if (NULL != temp_cmd->command)          free(temp_cmd->command);
+                               if (NULL != temp_cmd->parameter)        free(temp_cmd->parameter);
+                               free(temp_cmd);
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+               g_cur_cmd_list.widget_cmds = NULL;
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.foreground_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.foreground_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       if (NULL != temp_cmd) {
+                               if (NULL != temp_cmd->command)          free(temp_cmd->command);
+                               if (NULL != temp_cmd->parameter)        free(temp_cmd->parameter);
+                               free(temp_cmd);
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+               g_cur_cmd_list.foreground_cmds = NULL;
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.system_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.system_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       if (NULL != temp_cmd) {
+                               if (NULL != temp_cmd->command)          free(temp_cmd->command);
+                               if (NULL != temp_cmd->parameter)        free(temp_cmd->parameter);
+                               free(temp_cmd);
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+               g_cur_cmd_list.system_cmds = NULL;
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.exclusive_system_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.exclusive_system_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       if (NULL != temp_cmd) {
+                               if (NULL != temp_cmd->command)          free(temp_cmd->command);
+                               if (NULL != temp_cmd->parameter)        free(temp_cmd->parameter);
+                               free(temp_cmd);
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+               g_cur_cmd_list.exclusive_system_cmds = NULL;
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.background_cmds)) {
+               background_command_s* back_cmd_info;
+               iter = g_slist_nth(g_cur_cmd_list.background_cmds, 0);
+
+               GSList* back_iter = NULL;
+
+               while (NULL != iter) {
+                       back_cmd_info = iter->data;
+
+                       if (NULL != back_cmd_info) {
+                               back_iter = g_slist_nth(back_cmd_info->cmds, 0);
+
+                               while (NULL != back_iter) {
+                                       temp_cmd = back_iter->data;
+
+                                       if (NULL != temp_cmd) {
+                                               if (NULL != temp_cmd->command)          free(temp_cmd->command);
+                                               if (NULL != temp_cmd->parameter)        free(temp_cmd->parameter);
+                                               free(temp_cmd);
+                                       }
+
+                                       back_iter = g_slist_next(back_iter);
+                               }
+
+                               back_cmd_info->cmds = NULL;
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+
+               g_cur_cmd_list.background_cmds = NULL;
+       }
+
+       g_cur_cmd_list.bg_cmd_count = 0;
+
+       return 0;
+}
+
+int vcd_client_command_collect_command()
+{
+       /* 1. Get foreground pid */
+       int fg_pid = 0;
+       int ret = -1;
+       if (0 != vcd_config_get_foreground(&fg_pid)) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get foreground pid");
+               /* There is no foreground app for voice control */
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Foreground pid(%d)", fg_pid);
+
+       /* 2. Clean up command list */
+       __vcd_client_release_commands();
+
+       /* Check exclusive system command */
+       if (true == g_manager.exclusive_cmd_option) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Exclusive option of manager is ON");
+
+               GSList* ex_sys_cmd_list = NULL;
+               if (true == g_manager.manager_cmd) {
+                       ret = vc_cmd_parser_get_commands(g_manager.pid, VC_COMMAND_TYPE_EXCLUSIVE, &ex_sys_cmd_list);
+                       if (0 != ret) {
+                               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the system command list");
+                       } else {
+                               g_cur_cmd_list.exclusive_system_cmds = ex_sys_cmd_list;
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No exclusive system commands");
+               }
+
+               return 0;
+       }
+
+       /* 3. Set system command */
+       GSList* sys_cmd_list = NULL;
+       if (true == g_manager.manager_cmd) {
+               ret = vc_cmd_parser_get_commands(g_manager.pid, VC_COMMAND_TYPE_SYSTEM, &sys_cmd_list);
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the system command list");
+               } else {
+                       g_cur_cmd_list.system_cmds = sys_cmd_list;
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system commands");
+       }
+
+       vc_client_info_s* client_info = NULL;
+       GSList *iter = NULL;
+
+       /* 4. Set foreground commands and widget */
+       if (VC_NO_FOREGROUND_PID != fg_pid) {
+               GSList* fg_cmd_list = NULL;
+               GSList* widget_cmd_list = NULL;
+
+               g_cur_cmd_list.foreground = fg_pid;
+
+               /* 4-1. Set widget command */
+               widget_info_s* widget_info = NULL;
+               widget_info = __widget_get_element(fg_pid);
+               if (NULL != widget_info) {
+                       if (true == widget_info->widget_cmd) {
+                               ret = vc_cmd_parser_get_commands(fg_pid, VC_COMMAND_TYPE_WIDGET, &widget_cmd_list);
+                               if (0 != ret) {
+                                       SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the WIDGET command list");
+                               } else {
+                                       g_cur_cmd_list.widget_cmds = widget_cmd_list;
+                               }
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No widget commands");
+               }
+
+               /* Get handle */
+               client_info = __client_get_element(fg_pid);
+               if (NULL != client_info) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] fore cmd(%d)", client_info->fg_cmd);
+
+                       /* 4-2. Set foreground command */
+                       if (true == client_info->fg_cmd) {
+                               ret = vc_cmd_parser_get_commands(fg_pid, VC_COMMAND_TYPE_FOREGROUND, &fg_cmd_list);
+                               if (0 != ret) {
+                                       SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the fg command list");
+                               } else {
+                                       g_cur_cmd_list.foreground_cmds = fg_cmd_list;
+                               }
+                       } else {
+                               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No foreground commands");
+                       }
+
+                       /* 4-3. Check exclusive option */
+                       if (true == client_info->exclusive_cmd) {
+                               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Exclusive command is ON");
+
+                               /* 4-4. Set background command for exclusive option */
+                               if (true == client_info->bg_cmd) {
+                                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Set background command");
+                                       GSList* bg_cmd_list = NULL;
+                                       ret = vc_cmd_parser_get_commands(client_info->pid, VC_COMMAND_TYPE_BACKGROUND, &bg_cmd_list);
+                                       if (0 != ret) {
+                                               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the bg command list : pid(%d)", client_info->pid);
+                                       } else {
+                                               background_command_s* bg_cmd = (background_command_s*)calloc(1, sizeof(background_command_s));
+                                               if (NULL == bg_cmd) {
+                                                       SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
+                                                       return VCD_ERROR_OUT_OF_MEMORY;
+                                               }
+
+                                               bg_cmd->pid = client_info->pid;
+                                               bg_cmd->cmds = bg_cmd_list;
+                                               bg_cmd->cmd_count = g_slist_length(bg_cmd_list);
+
+                                               /* Add item to global command list */
+                                               g_cur_cmd_list.background_cmds = g_slist_append(g_cur_cmd_list.background_cmds, bg_cmd);
+                                       }
+                               }
+
+                               return 0;
+                       }
+               } else {
+                       SLOG(LOG_WARN, TAG_VCD, "[Client Data] No foreground client : pid(%d)", fg_pid);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No foreground app");
+       }
+
+       /* 5. Set background commands */
+       if (0 < g_slist_length(g_client_list)) {
+               iter = g_slist_nth(g_client_list, 0);
+
+               while (NULL != iter) {
+                       client_info = iter->data;
+                       GSList* bg_cmd_list = NULL;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Pid(%d) Back cmd(%d)", client_info->pid, client_info->bg_cmd);
+
+                       if (true == client_info->bg_cmd) {
+                               ret = vc_cmd_parser_get_commands(client_info->pid, VC_COMMAND_TYPE_BACKGROUND, &bg_cmd_list);
+                               if (0 != ret) {
+                                       SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to get the bg command list : pid(%d)", client_info->pid);
+                               } else {
+                                       background_command_s* bg_cmd = (background_command_s*)calloc(1, sizeof(background_command_s));
+                                       if (NULL == bg_cmd) {
+                                               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
+                                               return VCD_ERROR_OUT_OF_MEMORY;
+                                       }
+
+                                       bg_cmd->pid = client_info->pid;
+                                       bg_cmd->cmds = bg_cmd_list;
+                                       bg_cmd->cmd_count = g_slist_length(bg_cmd_list);
+
+                                       /* Add item to global command list */
+                                       g_cur_cmd_list.background_cmds = g_slist_append(g_cur_cmd_list.background_cmds, bg_cmd);
+                               }
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               /* NO client */
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No background commands");
+       }
+
+       return 0;
+}
+
+int vcd_client_get_length()
+{
+       int command_count = 0;
+       command_count += g_slist_length(g_cur_cmd_list.widget_cmds);
+       command_count += g_slist_length(g_cur_cmd_list.foreground_cmds);
+       command_count += g_slist_length(g_cur_cmd_list.system_cmds);
+       command_count += g_slist_length(g_cur_cmd_list.exclusive_system_cmds);
+
+       GSList *iter = NULL;
+       background_command_s* back_cmd_info;
+
+       if (0 < g_slist_length(g_cur_cmd_list.background_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.background_cmds, 0);
+
+               while (NULL != iter) {
+                       back_cmd_info = iter->data;
+
+                       command_count += g_slist_length(back_cmd_info->cmds);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] background commands count : %d", g_slist_length(back_cmd_info->cmds));
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               /* NO client */
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No background commands");
+       }
+
+       g_cur_cmd_list.total_cmd_count = command_count;
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Command count : %d ", g_cur_cmd_list.total_cmd_count);
+
+       return command_count;
+}
+
+int vcd_client_foreach_command(client_foreach_command_cb callback, void* user_data)
+{
+       if (NULL == callback) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] input parameter is NULL");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int id_count = 1;
+       GSList *iter = NULL;
+       vc_cmd_s* temp_cmd;
+
+       if (0 < g_slist_length(g_cur_cmd_list.widget_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.widget_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       temp_cmd->id = id_count;
+                       id_count++;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Widget : id(%d) index(%d) format(%d) command(%s) param(%s) domain(%d)"
+                               , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain);
+
+                       callback(temp_cmd->id, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data);
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No widget commands");
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.foreground_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.foreground_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       temp_cmd->id = id_count;
+                       id_count++;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Foreground : id(%d) index(%d) format(%d) command(%s) param(%s) domain(%d)"
+                               , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain);
+
+                       callback(temp_cmd->id, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data);
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No foreground commands");
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.system_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.system_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       temp_cmd->id = id_count;
+                       id_count++;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] System : id(%d) index(%d) format(%d) domain(%d) command(%s) param(%s)"
+                               , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->domain, temp_cmd->command, temp_cmd->parameter);
+
+                       callback(temp_cmd->id, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data);
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system commands");
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.exclusive_system_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.exclusive_system_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       temp_cmd->id = id_count;
+                       id_count++;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Exclusive system : id(%d) index(%d) format(%d) command(%s) param(%s) domain(%d)"
+                               , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain);
+
+                       callback(temp_cmd->id, temp_cmd->type, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data);
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No exclusive system commands");
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.background_cmds)) {
+               background_command_s* back_cmd_info;
+               iter = g_slist_nth(g_cur_cmd_list.background_cmds, 0);
+
+               while (NULL != iter) {
+                       back_cmd_info = iter->data;
+
+                       GSList* back_iter = NULL;
+                       back_iter = g_slist_nth(back_cmd_info->cmds, 0);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] pid(%d) command count(%d)", back_cmd_info->pid, back_cmd_info->cmd_count);
+
+                       while (NULL != back_iter) {
+                               temp_cmd = back_iter->data;
+
+                               temp_cmd->id = id_count;
+                               id_count++;
+
+                               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Background : id(%d) index(%d) format(%d) command(%s) param(%s) domain(%d)"
+                                       , temp_cmd->id, temp_cmd->index, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain);
+
+                               callback(temp_cmd->id, temp_cmd->format, temp_cmd->command, temp_cmd->parameter, temp_cmd->domain, user_data);
+
+                               back_iter = g_slist_next(back_iter);
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No background commands");
+       }
+
+       return 0;
+}
+
+static vc_cmd_s* __command_copy(vc_cmd_s* src_cmd)
+{
+       if (NULL == src_cmd) {
+               SLOG(LOG_WARN, TAG_VCD, "[Client Data] Input command is NULL");
+               return NULL;
+       }
+
+       vc_cmd_s* temp_cmd = NULL;
+       temp_cmd = (vc_cmd_s*)calloc(sizeof(vc_cmd_s), 1);
+       if (NULL == temp_cmd) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
+               return NULL;
+       }
+
+       temp_cmd->id = src_cmd->id;
+       temp_cmd->pid = src_cmd->pid;
+       temp_cmd->index = src_cmd->index;
+       temp_cmd->type = src_cmd->type;
+       temp_cmd->format = src_cmd->format;
+       temp_cmd->domain = src_cmd->domain;
+
+       if (NULL != src_cmd->command) {
+               temp_cmd->command = strdup(src_cmd->command);
+       }
+
+       if (NULL != src_cmd->parameter) {
+               temp_cmd->parameter = strdup(src_cmd->parameter);
+       }
+       
+       temp_cmd->key = src_cmd->key;
+       temp_cmd->modifier = src_cmd->modifier;
+
+       return temp_cmd;
+}
+
+//int vcd_client_get_cmd_info_from_result_id(int result_id, int* pid, int* cmd_type, vc_cmd_s** result)
+int vcd_client_get_cmd_from_result_id(int result_id, vc_cmd_s** result)
+{
+       GSList *iter = NULL;
+       vc_cmd_s* temp_cmd;
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Result id(%d)", result_id);
+
+       if (0 < g_slist_length(g_cur_cmd_list.widget_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.widget_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       if (result_id == temp_cmd->id) {
+                               //*pid = g_cur_cmd_list.foreground;
+                               //*cmd_type = VCD_CLIENT_COMMAND_GROUP_TYPE_UI_CONTROL;
+                               //SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Find result pid(%d) type(%d)", *pid, *cmd_type);
+
+                               *result = __command_copy(temp_cmd);
+
+                               return 0;
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No widget commands");
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.foreground_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.foreground_cmds, 0);
+
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] command id (%d)", temp_cmd->id);
+
+                       if (result_id == temp_cmd->id) {
+                               //*pid = g_cur_cmd_list.foreground;
+                               //*cmd_type = VCD_CLIENT_COMMAND_GROUP_TYPE_FOREGROUND;
+                               //SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Find result pid(%d) type(%d)", *pid, *cmd_type);
+
+                               *result = __command_copy(temp_cmd);
+                               return 0;
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No foreground commands");
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.system_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.system_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       if (result_id == temp_cmd->id) {
+                               //*pid = g_manager.pid;
+                               //*cmd_type = VCD_CLIENT_COMMAND_GROUP_TYPE_SYSTEM;
+                               //SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Find result pid(%d) type(%d)", *pid, *cmd_type);
+
+                               *result = __command_copy(temp_cmd);
+                               return 0;
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No system commands");
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.exclusive_system_cmds)) {
+               iter = g_slist_nth(g_cur_cmd_list.exclusive_system_cmds, 0);
+               while (NULL != iter) {
+                       temp_cmd = iter->data;
+
+                       if (result_id == temp_cmd->id) {
+                               //*pid = g_manager.pid;
+                               //*cmd_type = VCD_CLIENT_COMMAND_GROUP_TYPE_SYSTEM_EXCLUSIVE;
+                               //SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] Find result pid(%d) type(%d)", *pid, *cmd_type);
+
+                               *result = __command_copy(temp_cmd);
+                               return 0;
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No exclusive system commands");
+       }
+
+       if (0 < g_slist_length(g_cur_cmd_list.background_cmds)) {
+               background_command_s* back_cmd_info;
+               iter = g_slist_nth(g_cur_cmd_list.background_cmds, 0);
+
+               while (NULL != iter) {
+                       back_cmd_info = iter->data;
+
+                       GSList* back_iter = NULL;
+                       back_iter = g_slist_nth(back_cmd_info->cmds, 0);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] pid(%d) command count(%d)", back_cmd_info->pid, back_cmd_info->cmd_count);
+
+                       while (NULL != back_iter) {
+                               temp_cmd = back_iter->data;
+
+                               if (result_id == temp_cmd->id) {
+                                       //*pid = back_cmd_info->pid;
+                                       //*cmd_type = VCD_CLIENT_COMMAND_GROUP_TYPE_BACKGROUND;
+
+                                       *result = __command_copy(temp_cmd);
+                                       return 0;
+                               }
+                               back_iter = g_slist_next(back_iter);
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] No background commands");
+       }
+
+       SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Not find matched result");
+
+       return -1;
+}
+
+int vcd_client_set_slience_detection(bool value)
+{
+       g_silence_detection = value;
+       return 0;
+}
+
+bool vcd_client_get_slience_detection()
+{
+       return g_silence_detection;
+}
+
+int __show_client_list()
+{
+       GSList *iter = NULL;
+       vc_client_info_s *data = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCD, "----- client list");
+
+       int count = g_slist_length(g_client_list);
+       int i;
+
+       if (0 == count) {
+               SLOG(LOG_DEBUG, TAG_VCD, "No Client");
+       } else {
+               iter = g_slist_nth(g_client_list, 0);
+               for (i = 0;i < count;i++) {
+                       data = iter->data;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[%dth] pid(%d)", i, data->pid);
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "-----");
+
+       SLOG(LOG_DEBUG, TAG_VCD, "----- widget list");
+
+       widget_info_s *widget_data = NULL;
+
+       count = g_slist_length(g_widget_list);
+
+       if (0 == count) {
+               SLOG(LOG_DEBUG, TAG_VCD, "No widget");
+       } else {
+               iter = g_slist_nth(g_widget_list, 0);
+               for (i = 0;i < count;i++) {
+                       widget_data = iter->data;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[%dth] pid(%d)", i, widget_data->pid);
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "-----");
+
+       return 0;
+}
+
+int __show_command_list(GSList* cmd_group)
+{
+       GSList *iter = NULL;
+       vc_cmd_s *data = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCD, "----- command group");
+
+       int count = g_slist_length(cmd_group);
+       int i;
+
+       if (0 == count) {
+               SLOG(LOG_DEBUG, TAG_VCD, "No command");
+       } else {
+               iter = g_slist_nth(cmd_group, 0);
+               for (i = 0;i < count;i++) {
+                       data = iter->data;
+
+                       if (NULL != data->parameter) {
+                               SLOG(LOG_DEBUG, TAG_VCD, "[%dth] command(%s) parameter(%s) key(%d)", i, data->command, data->parameter, data->key);
+                       } else {
+                               SLOG(LOG_DEBUG, TAG_VCD, "[%dth] command(%s) key(%d)", i, data->command, data->key);
+                       }
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "-----");
+
+       return 0;
+}
+
+GSList* __client_get_item(const int pid)
+{
+       GSList *iter = NULL;
+       vc_client_info_s *data = NULL;
+
+       int count = g_slist_length(g_client_list);
+       int i;
+
+       if (0 < count) {
+               iter = g_slist_nth(g_client_list, 0);
+               for (i = 0;i < count;i++) {
+                       data = iter->data;
+
+                       if (pid == data->pid) 
+                               return iter;
+
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       return NULL;
+}
+
+vc_client_info_s* __client_get_element(int pid)
+{
+       GSList *iter = NULL;
+       vc_client_info_s *data = NULL;
+       
+       int count = g_slist_length(g_client_list);
+       int i;
+
+       if (0 < count) {
+               iter = g_slist_nth(g_client_list, 0);
+               for (i = 0;i < count;i++) {
+                       data = iter->data;
+
+                       if (pid == data->pid) 
+                               return data;
+
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       return NULL;
+}
+
+int vcd_client_add(int pid)
+{
+       /*Check pid is duplicated*/
+       GSList *tmp = NULL;
+       tmp = __client_get_item(pid);
+       
+       if (NULL != tmp) {
+               SLOG(LOG_WARN, TAG_VCD, "[Client Data] Client pid is already registered");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       vc_client_info_s *info = (vc_client_info_s*)calloc(1, sizeof(vc_client_info_s));
+       if (NULL == info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
+               return VCD_ERROR_OUT_OF_MEMORY;
+       }
+
+       info->pid = pid;
+
+       info->fg_cmd = false;
+       info->bg_cmd = false;
+       info->exclusive_cmd = false;
+
+       /* Add item to global list */
+       g_client_list = g_slist_append(g_client_list, info);
+       
+       if (NULL == g_client_list) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to add new client");
+               return -1;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data SUCCESS] Add new client");
+       }
+
+#ifdef CLIENT_DATA_DEBUG
+       __show_client_list();
+#endif 
+       return 0;
+}
+
+int vcd_client_delete(int pid)
+{
+       GSList *tmp = NULL;
+       vc_client_info_s* client_info = NULL;
+
+       /*Get handle*/
+       tmp = __client_get_item(pid);
+       if (NULL == tmp) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /*Free client structure*/
+       client_info = tmp->data;
+       if (NULL != client_info) {
+               free(client_info);
+       }
+
+       /*Remove handle from list*/
+       g_client_list = g_slist_remove_link(g_client_list, tmp);
+
+
+#ifdef CLIENT_DATA_DEBUG
+       __show_client_list();
+#endif 
+
+       return 0;
+}
+
+bool vcd_client_is_available(int pid)
+{
+       vc_client_info_s* client_info = NULL;
+
+       client_info = __client_get_element(pid);
+       if (NULL == client_info) {
+               SLOG(LOG_WARN, TAG_VCD, "[Client Data] pid(%d) is NOT valid", pid);
+               return false;
+       }
+
+       return true;
+}
+
+int vcd_client_get_ref_count()
+{
+       int count = 0;
+       
+       count = g_slist_length(g_client_list) + g_slist_length(g_widget_list);
+       if (0 < g_manager.pid) {
+               count++;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Client Data] client count : %d", count);
+
+       return count;
+}
+
+int vcd_client_get_list(int** pids, int* pid_count)
+{
+       if (NULL == pids || NULL == pid_count)
+               return -1;
+       
+       int count = g_slist_length(g_client_list);
+
+       if (0 == count)
+               return -1;
+
+       int *tmp;
+       tmp = (int*)calloc(count, sizeof(int));
+       if (NULL == tmp) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
+               return VCD_ERROR_OUT_OF_MEMORY;
+       }
+       
+       GSList *iter = NULL;
+       vc_client_info_s *data = NULL;
+       int i = 0;
+
+       iter = g_slist_nth(g_client_list, 0);
+
+       while (NULL != iter) {
+               data = iter->data;
+
+               if (NULL != data) {
+                       tmp[i] = data->pid;
+               }
+
+               iter = g_slist_next(iter);
+               i++;
+       }
+
+       *pids = tmp;
+       *pid_count = count;
+
+       return 0;
+}
+
+//int vcd_client_set_command_type(int pid, vcd_client_command_group_type_e type)
+int vcd_client_set_command_type(int pid, int type)
+{
+       vc_client_info_s* client_info = NULL;
+
+       client_info = __client_get_element(pid);
+       if (NULL == client_info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] vcd_client_get_pid : pid(%d) is not found", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (type) {
+       case VC_COMMAND_TYPE_FOREGROUND:
+               client_info->fg_cmd = true;
+               break;
+       case VC_COMMAND_TYPE_BACKGROUND:
+               client_info->bg_cmd = true;
+               break;
+       default:
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] not supported command type(%d)", type);
+               return -1;
+       }
+
+       return 0;
+}
+
+//int vcd_client_unset_command_type(int pid, vcd_client_command_group_type_e type)
+int vcd_client_unset_command_type(int pid, int type)
+{
+       vc_client_info_s* client_info = NULL;
+
+       client_info = __client_get_element(pid);
+       if (NULL == client_info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] vcd_client_get_pid : pid(%d) is not found", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       switch (type) {
+       case VC_COMMAND_TYPE_FOREGROUND:
+               client_info->fg_cmd = false;
+               break;
+       case VC_COMMAND_TYPE_BACKGROUND:
+               client_info->bg_cmd = false;
+               break;
+       default:
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] not supported command type(%d)", type);
+               return -1;
+       }
+
+       return 0;
+}
+
+int vcd_client_set_exclusive_command(int pid)
+{
+       vc_client_info_s* client_info = NULL;
+
+       client_info = __client_get_element(pid);
+       if (NULL == client_info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] pid(%d) is not found", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       client_info->exclusive_cmd = true;
+
+       return 0;
+}
+
+int vcd_client_unset_exclusive_command(int pid)
+{
+       vc_client_info_s* client_info = NULL;
+
+       client_info = __client_get_element(pid);
+       if (NULL == client_info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] pid(%d) is not found", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       client_info->exclusive_cmd = false;
+
+       return 0;
+}
+
+int vcd_client_save_client_info()
+{
+       if (0 != vc_info_parser_set_client_info(g_client_list)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to save client info");
+               return -1;
+       }
+
+       return 0;
+}
+
+/*
+* Functions for widget
+*/
+GSList* __widget_get_item(int pid)
+{
+       GSList *iter = NULL;
+       widget_info_s *data = NULL;
+
+       int count = g_slist_length(g_widget_list);
+       int i;
+
+       if (0 < count) {
+               iter = g_slist_nth(g_widget_list, 0);
+               for (i = 0;i < count;i++) {
+                       data = iter->data;
+
+                       if (pid == data->pid) 
+                               return iter;
+
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       return NULL;
+}
+
+widget_info_s* __widget_get_element(int pid)
+{
+       GSList *iter = NULL;
+       widget_info_s *data = NULL;
+       
+       int count = g_slist_length(g_widget_list);
+       int i;
+
+       if (0 < count) {
+               iter = g_slist_nth(g_widget_list, 0);
+               for (i = 0;i < count;i++) {
+                       data = iter->data;
+
+                       if (NULL != data) {
+                               if (pid == data->pid)
+                                       return data;
+                       }
+
+                       iter = g_slist_next(iter);
+               }
+       }
+
+       return NULL;
+}
+
+int vcd_client_widget_get_list(int** pids, int* pid_count)
+{
+       if (NULL == pids || NULL == pid_count)
+               return -1;
+
+       int count = g_slist_length(g_widget_list);
+
+       if (0 == count)
+               return -1;
+
+       int *tmp;
+       tmp = (int*)calloc(count, sizeof(int));
+       if (NULL == tmp) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
+               return VCD_ERROR_OUT_OF_MEMORY;
+       }
+
+       GSList *iter = NULL;
+       widget_info_s *data = NULL;
+       int i = 0;
+
+       iter = g_slist_nth(g_widget_list, 0);
+       while (NULL != iter) {
+               data = iter->data;
+
+               if (NULL != data) {
+                       tmp[i] = data->pid;
+               }
+
+               iter = g_slist_next(iter);
+               i++;
+       }
+
+       *pids = tmp;
+       *pid_count = count;
+
+       return 0;
+}
+
+int vcd_client_widget_add(int pid)
+{
+       /*Check pid is duplicated*/
+       GSList *tmp = NULL;
+       tmp = __widget_get_item(pid);
+
+       if (NULL != tmp) {
+               SLOG(LOG_WARN, TAG_VCD, "[Client Data] widget pid is already registered");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       widget_info_s *info = (widget_info_s*)calloc(1, sizeof(widget_info_s));
+       if (NULL == info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
+               return VCD_ERROR_OUT_OF_MEMORY;
+       }
+
+       info->pid = pid;
+       info->widget_cmd = false;
+
+       /* Add item to global list */
+       g_widget_list = g_slist_append(g_widget_list, info);
+
+       if (NULL == g_widget_list) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] Fail to add new widget");
+               return -1;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Client Data SUCCESS] Add new widget");
+       }
+
+#ifdef CLIENT_DATA_DEBUG
+       __show_client_list();
+#endif 
+       return 0;
+}
+
+int vcd_client_widget_delete(int pid)
+{
+       GSList *tmp = NULL;
+       widget_info_s* widget_info = NULL;
+
+       /*Get handle*/
+       tmp = __widget_get_item(pid);
+       if (NULL == tmp) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /*Free client structure*/
+       widget_info = tmp->data;
+       if (NULL != widget_info) {
+               free(widget_info);
+       }
+
+       /*Remove handle from list*/
+       g_widget_list = g_slist_remove_link(g_widget_list, tmp);
+
+
+#ifdef CLIENT_DATA_DEBUG
+       __show_client_list();
+#endif 
+
+       return 0;
+}
+
+int vcd_client_widget_get_foreground_pid()
+{
+       /* 1. Get foreground pid */
+       int fg_pid = 0;
+       if (0 != vcd_config_get_foreground(&fg_pid)) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get foreground pid");
+               /* There is no foreground app for voice control */
+       }
+
+       widget_info_s* widget = NULL;
+
+       widget = __widget_get_element(fg_pid);
+       if (NULL == widget) {
+               SLOG(LOG_WARN, TAG_VCD, "[Client Data] Not found foreground pid of widget");
+               return -1;
+       }
+
+       return widget->pid;
+}
+
+
+bool vcd_client_widget_is_available(int pid)
+{
+       widget_info_s* widget_info = NULL;
+
+       widget_info = __widget_get_element(pid);
+       if (NULL == widget_info) {
+               SLOG(LOG_WARN, TAG_VCD, "[Client Data] pid(%d) is NOT valid", pid);
+               return false;
+       }
+
+       return true;
+}
+
+int vcd_client_widget_set_command(int pid)
+{
+       widget_info_s *info = NULL;
+       info = __widget_get_element(pid);
+       if (NULL == info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       info->widget_cmd = true;
+       
+       return 0;
+}
+
+int vcd_client_widget_unset_command(int pid)
+{
+       widget_info_s *info = NULL;
+       info = __widget_get_element(pid);
+       if (NULL == info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Client Data ERROR] pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       info->widget_cmd = false;
+       
+       return 0;
+}
\ No newline at end of file
diff --git a/server/vcd_client_data.h b/server/vcd_client_data.h
new file mode 100644 (file)
index 0000000..6cfc59c
--- /dev/null
@@ -0,0 +1,156 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VCD_CLIENT_DATA_H_
+#define __VCD_CLIENT_DATA_H_
+
+#include <glib.h>
+#include "vc_command.h"
+#include "vc_info_parser.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+       int     pid;
+       int     cmd_count;
+       
+       GSList* cmds;
+}background_command_s;
+
+typedef struct {
+       int total_cmd_count;
+
+       /* Foreground application */
+       int foreground;
+       GSList* widget_cmds;
+       GSList* foreground_cmds;
+
+       /* Manager application */
+       GSList* system_cmds;
+       GSList* exclusive_system_cmds;
+
+       /* Other applications */
+       int     bg_cmd_count;
+       GSList* background_cmds;
+}current_commands_list_s;
+
+
+typedef struct {
+       int     pid;
+       bool    manager_cmd;
+       bool    exclusive_cmd_option;
+}manager_info_s;
+
+typedef struct {
+       int     pid;
+       bool    widget_cmd;
+}widget_info_s;
+
+
+/*
+* Command API
+*/
+typedef bool (* client_foreach_command_cb)(int id, int type, const char* command, const char* param, int domain, void* user_data);
+
+int vcd_client_command_collect_command();
+
+int vcd_client_get_length();
+
+int vcd_client_foreach_command(client_foreach_command_cb callback, void* user_data);
+
+//int vcd_client_get_client_info_from_result_id(int* result_id, int** pid, int** cmd_type);
+int vcd_client_get_cmd_from_result_id(int result_id, vc_cmd_s** result);
+
+int vcd_client_get_cmd_info_from_result_id(int result_id, int* pid, int* cmd_type, vc_cmd_s** result);
+
+int vcd_client_set_slience_detection(bool value);
+
+bool vcd_client_get_slience_detection();
+
+/*
+* Manager API
+*/
+int vcd_client_manager_set(int pid);
+
+int vcd_client_manager_unset();
+
+bool vcd_client_manager_is_valid(int pid);
+
+int vcd_client_manager_set_command(int pid);
+
+int vcd_client_manager_unset_command(int pid);
+
+int vcd_client_manager_set_demandable_client(int pid, GSList* client_list);
+
+bool vcd_client_manager_check_demandable_client(int pid);
+
+bool vcd_client_manager_get_exclusive();
+
+int vcd_client_manager_set_exclusive(bool value);
+
+int vcd_client_manager_get_pid();
+
+
+/*
+* client API
+*/
+int vcd_client_add(int pid);
+
+int vcd_client_delete(int pid);
+
+bool vcd_client_is_available(int pid);
+
+int vcd_client_get_ref_count();
+
+int vcd_client_get_list(int** pids, int* pid_count);
+
+int vcd_client_set_command_type(int pid, int type);
+
+int vcd_client_unset_command_type(int pid, int type);
+
+int vcd_client_set_exclusive_command(int pid);
+
+int vcd_client_unset_exclusive_command(int pid);
+
+int vcd_client_save_client_info();
+
+/*
+* widget API
+*/
+int vcd_client_widget_get_list(int** pids, int* pid_count);
+
+int vcd_client_widget_add(int pid);
+
+int vcd_client_widget_delete(int pid);
+
+bool vcd_client_widget_is_available(int pid);
+
+int vcd_client_widget_get_foreground_pid();
+
+int vcd_client_widget_set_command(int pid);
+
+int vcd_client_widget_unset_command(int pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VCD_CLIENT_DATA_H_ */
+
diff --git a/server/vcd_config.c b/server/vcd_config.c
new file mode 100644 (file)
index 0000000..522458f
--- /dev/null
@@ -0,0 +1,124 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vc_config_mgr.h"
+#include "vcd_config.h"
+#include "vcd_main.h"
+
+
+static vcd_config_lang_changed_cb g_lang_cb;
+
+static vcd_config_foreground_changed_cb g_fore_cb;
+
+static void* g_user_data;
+
+static vcd_state_e g_state;
+
+
+void __vcd_config_lang_changed_cb(const char* before_lang, const char* current_lang)
+{
+       if (NULL != g_lang_cb)
+               g_lang_cb(current_lang, g_user_data);
+       else
+               SLOG(LOG_ERROR, TAG_VCD, "Language changed callback is NULL");
+}
+
+void __vcd_config_foreground_changed_cb(int previous, int current)
+{
+       if (NULL != g_fore_cb)
+               g_fore_cb(previous, current, g_user_data);
+       else
+               SLOG(LOG_ERROR, TAG_VCD, "Foreground changed callback is NULL");
+}
+
+int vcd_config_initialize(vcd_config_lang_changed_cb lang_cb, vcd_config_foreground_changed_cb fore_cb, void* user_data)
+{
+       if (NULL == lang_cb) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Config] Invalid parameter");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = -1;
+       ret = vc_config_mgr_initialize(getpid());
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Config] Fail to initialize config manager : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       ret = vc_config_mgr_set_lang_cb(getpid(), __vcd_config_lang_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set config changed callback : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       ret = vc_config_mgr_set_foreground_cb(getpid(), __vcd_config_foreground_changed_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to set foreground changed callback : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       g_lang_cb = lang_cb;
+       g_fore_cb = fore_cb;
+       g_user_data = user_data;
+
+       return 0;
+}
+
+int vcd_config_finalize()
+{
+       vc_config_mgr_unset_foreground_cb(getpid());
+       vc_config_mgr_unset_lang_cb(getpid());
+       vc_config_mgr_finalize(getpid());
+       return 0;
+}
+
+int vcd_config_get_default_language(char** language)
+{
+       if (NULL == language)
+               return VCD_ERROR_INVALID_PARAMETER;
+
+       if (0 != vc_config_mgr_get_default_language(language)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Config ERROR] Fail to get language");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return 0;
+}
+
+int vcd_config_set_service_state(vcd_state_e state)
+{
+       g_state = state;
+
+       if (0 != vc_config_mgr_set_service_state((int)state)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Config ERROR] Fail to set service state");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Config] Config is changed : %d", g_state);
+
+       return 0;
+}
+
+vcd_state_e vcd_config_get_service_state()
+{
+       return g_state;
+}
+
+int vcd_config_get_foreground(int* pid)
+{
+       return vc_config_mgr_get_foreground(pid);
+}
\ No newline at end of file
diff --git a/server/vcd_config.h b/server/vcd_config.h
new file mode 100644 (file)
index 0000000..f922706
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VCD_CONFIG_H_
+#define __VCD_CONFIG_H_
+
+#include "vcd_main.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef void (*vcd_config_lang_changed_cb)(const char* language, void* user_data);
+
+typedef void (*vcd_config_foreground_changed_cb)(int previous, int current, void* user_data);
+
+
+int vcd_config_initialize(vcd_config_lang_changed_cb lang_cb, vcd_config_foreground_changed_cb fore_cb, void* user_data);
+
+int vcd_config_finalize();
+
+int vcd_config_get_default_language(char** language);
+
+int vcd_config_set_service_state(vcd_state_e state);
+
+vcd_state_e vcd_config_get_service_state();
+
+int vcd_config_get_foreground(int* pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VCD_CONFIG_H_ */
diff --git a/server/vcd_dbus.c b/server/vcd_dbus.c
new file mode 100644 (file)
index 0000000..9bcc0e3
--- /dev/null
@@ -0,0 +1,635 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+
+#include <dbus/dbus.h>
+#include "vcd_client_data.h"
+#include "vcd_dbus.h"
+#include "vcd_dbus_server.h"
+#include "vcd_main.h"
+
+
+static DBusConnection* g_conn;
+
+static int g_waiting_time = 3000;
+
+
+static DBusMessage* __get_message(int pid, const char* method, vcd_client_type_e type)
+{
+       char service_name[64] = {0,};
+       char object_path[64] = {0,};
+       char target_if_name[128] = {0,};
+
+       if (VCD_CLIENT_TYPE_NORMAL == type) {
+               snprintf(service_name, 64, "%s%d", VC_CLIENT_SERVICE_NAME, pid);
+               snprintf(object_path, 64, "%s", VC_CLIENT_SERVICE_OBJECT_PATH);
+               snprintf(target_if_name, 128, "%s%d", VC_CLIENT_SERVICE_NAME, pid);
+       } else if (VCD_CLIENT_TYPE_WIDGET == type) {
+               snprintf(service_name, 64, "%s%d", VC_WIDGET_SERVICE_NAME, pid);
+               snprintf(object_path, 64, "%s", VC_WIDGET_SERVICE_OBJECT_PATH);
+               snprintf(target_if_name, 128, "%s%d", VC_WIDGET_SERVICE_INTERFACE, pid);
+       } else if (VCD_CLIENT_TYPE_MANAGER == type) {
+               snprintf(service_name, 64, "%s%d", VC_MANAGER_SERVICE_NAME, pid);
+               snprintf(object_path, 64, "%s", VC_MANAGER_SERVICE_OBJECT_PATH);
+               snprintf(target_if_name, 128, "%s%d", VC_MANAGER_SERVICE_INTERFACE, pid);
+       } else {
+               return NULL;
+       }
+
+       return dbus_message_new_method_call(service_name, object_path, target_if_name, method);
+}
+
+int vcdc_send_hello(int pid, vcd_client_type_e type)
+{
+       DBusMessage* msg = NULL;
+
+       if (VCD_CLIENT_TYPE_NORMAL == type) {
+               msg = __get_message(pid, VCD_METHOD_HELLO, VCD_CLIENT_TYPE_NORMAL);
+       } else if (VCD_CLIENT_TYPE_WIDGET == type) {
+               msg = __get_message(pid, VCD_WIDGET_METHOD_HELLO, VCD_CLIENT_TYPE_WIDGET);
+       } else if (VCD_CLIENT_TYPE_MANAGER == type) {
+               msg = __get_message(pid, VCD_WIDGET_METHOD_HELLO, VCD_CLIENT_TYPE_MANAGER);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Client type is NOT valid");
+               return -1;
+       }
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to create message");
+               return -1;
+       }
+
+       dbus_message_append_args(msg, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+       int result = -1;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] %s", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_get_args(result_msg, &err, DBUS_TYPE_INT32, &result, DBUS_TYPE_INVALID);
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus] Get arguments error (%s)", err.message);
+                       dbus_error_free(&err);
+                       result = -1;
+               }
+
+               dbus_message_unref(result_msg);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result message is NULL. Client is not available");
+               result = 0;
+       }
+
+       return result;
+}
+
+int vcdc_send_show_tooltip(int pid, bool show)
+{
+       if (0 > pid) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] widget pid is NOT valid" );
+               return -1;
+       }
+
+       char service_name[64];
+       memset(service_name, 0, 64);
+       snprintf(service_name, 64, "%s%d", VC_WIDGET_SERVICE_NAME, pid);
+
+       char target_if_name[128];
+       snprintf(target_if_name, sizeof(target_if_name), "%s%d", VC_WIDGET_SERVICE_INTERFACE, pid);
+
+       DBusMessage* msg;
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] send widget show tooltip signal : pid(%d) show(%d)", pid, show);
+
+       msg = dbus_message_new_method_call(
+               service_name, 
+               VC_WIDGET_SERVICE_OBJECT_PATH, 
+               target_if_name, 
+               VCD_WIDGET_METHOD_SHOW_TOOLTIP);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to create message");
+               return -1;
+       }
+
+       int temp = (int)show;
+
+       DBusMessageIter args;
+       dbus_message_iter_init_append(msg, &args);
+
+       /* Append pid & type */
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &pid);
+       dbus_message_iter_append_basic(&args, DBUS_TYPE_INT32, &(temp));
+
+       dbus_message_set_no_reply(msg, TRUE);
+       
+       if (1 != dbus_connection_send(g_conn, msg, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send");
+               return -1;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] SUCCESS Send");
+               dbus_connection_flush(g_conn);
+               return 0;
+       }
+
+       /*
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (NULL != result_msg) {
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus] Get arguments error (%s)\n", err.message);
+                       dbus_error_free(&err);
+                       return -1;
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result response");
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result message is NULL. Widget is not available");
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] %s", err.message);
+                       dbus_error_free(&err);
+               }
+               return -1;
+       }
+
+       return 0;
+       */
+}
+
+int vcdc_send_result(int pid, int cmd_type)
+{
+       DBusMessage* msg = NULL;
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result command type(%d)", cmd_type);
+
+       switch (cmd_type) {
+       case VC_COMMAND_TYPE_FOREGROUND:
+               msg = __get_message(pid, VCD_METHOD_RESULT, VCD_CLIENT_TYPE_NORMAL);
+               break;
+       case VC_COMMAND_TYPE_BACKGROUND:
+               msg = __get_message(pid, VCD_METHOD_RESULT, VCD_CLIENT_TYPE_NORMAL);
+               break;
+       case VC_COMMAND_TYPE_WIDGET:
+               msg = __get_message(pid, VCD_WIDGET_METHOD_RESULT, VCD_CLIENT_TYPE_WIDGET);
+               break;
+       case VC_COMMAND_TYPE_SYSTEM:
+       case VC_COMMAND_TYPE_EXCLUSIVE:
+               msg = __get_message(pid, VCD_MANAGER_METHOD_RESULT, VCD_CLIENT_TYPE_MANAGER);
+               break;
+
+       default:
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Command type is NOT valid(%d)", cmd_type);
+               return -1;
+       }
+
+       if (NULL == msg)
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL");
+
+
+       dbus_message_set_no_reply(msg, TRUE);
+       if (1 != dbus_connection_send(g_conn, msg, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send");
+               return -1;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] SUCCESS Send");
+               dbus_connection_flush(g_conn);
+               return 0;
+       }
+
+       /*
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (NULL != result_msg) {
+               dbus_message_unref(result_msg);
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus] Get arguments error (%s)\n", err.message);
+                       dbus_error_free(&err);
+                       return VCD_ERROR_TIMED_OUT;
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result response");
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result message is NULL.");
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] %s", err.message);
+                       dbus_error_free(&err);
+               }
+               return VCD_ERROR_TIMED_OUT;
+       }
+
+       return 0;
+       */
+}
+
+int vcdc_send_result_to_manager(int manger_pid)
+{
+//     int count = 0;
+
+//     DBusMessage* result_msg = NULL;
+       
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* msg = NULL;
+
+       msg = __get_message(manger_pid, VCD_MANAGER_METHOD_ALL_RESULT, VCD_CLIENT_TYPE_MANAGER);
+
+       if (NULL == msg)
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL");
+
+       dbus_message_set_no_reply(msg, TRUE);
+       
+       if (1 != dbus_connection_send(g_conn, msg, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send");
+               return -1;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] SUCCESS Send");
+               dbus_connection_flush(g_conn);
+               return 0;
+       }
+       
+       /*
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (NULL != result_msg) {
+               dbus_message_unref(result_msg);
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus] Get arguments error (%s)\n", err.message);
+                       dbus_error_free(&err);
+                       return -1;
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result response");
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result message is NULL.");
+
+               if (dbus_error_is_set(&err)) { 
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] %s", err.message);
+                       dbus_error_free(&err);
+               }
+               return -1;
+       }
+
+       count++;
+
+       return 0;
+       */
+}
+
+int vcdc_send_speech_detected(int manger_pid)
+{
+//     DBusMessage* result_msg = NULL;
+
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* msg = NULL;
+
+       msg = __get_message(manger_pid, VCD_MANAGER_METHOD_SPEECH_DETECTED, VCD_CLIENT_TYPE_MANAGER);
+
+       if (NULL == msg)
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Message is NULL");
+
+       dbus_message_set_no_reply(msg, TRUE);
+
+       if (1 != dbus_connection_send(g_conn, msg, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send");
+               return -1;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] SUCCESS Send");
+               dbus_connection_flush(g_conn);
+               return 0;
+       }
+
+       /*
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (NULL != result_msg) {
+               dbus_message_unref(result_msg);
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus] Get arguments error (%s)\n", err.message);
+                       dbus_error_free(&err);
+                       return -1;
+               }
+               else {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result response");
+               }
+       }
+       else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result message is NULL.");
+
+               if (dbus_error_is_set(&err)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] %s", err.message);
+                       dbus_error_free(&err);
+               }
+               return -1;
+       }
+
+       return 0;
+       */
+}
+
+int vcdc_send_error_signal(int pid, int reason, char *err_msg)
+{
+       if (NULL == err_msg) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Input parameter is NULL");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       char service_name[64];
+       memset(service_name, 0, 64);
+       snprintf(service_name, 64, "%s%d", VC_CLIENT_SERVICE_NAME, pid);
+
+       char target_if_name[128];
+       snprintf(target_if_name, sizeof(target_if_name), "%s%d", VC_CLIENT_SERVICE_INTERFACE, pid);
+
+       DBusMessage* msg;
+       SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] send error signal : reason(%d), Error Msg(%s)", reason, err_msg);
+
+       msg = dbus_message_new_method_call(
+               service_name, 
+               VC_CLIENT_SERVICE_OBJECT_PATH, 
+               target_if_name, 
+               VCD_METHOD_ERROR);
+
+       if (NULL == msg) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to create message");
+               return -1;
+       }
+
+       dbus_message_append_args(msg, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INT32, &reason, 
+               DBUS_TYPE_STRING, &err_msg,
+               DBUS_TYPE_INVALID);
+
+       dbus_message_set_no_reply(msg, TRUE);
+       
+       if (1 != dbus_connection_send(g_conn, msg, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to Send");
+               return -1;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] SUCCESS Send");
+               dbus_connection_flush(g_conn);
+               return 0;
+       }
+
+       /*
+       DBusError err;
+       dbus_error_init(&err);
+
+       DBusMessage* result_msg;
+
+       result_msg = dbus_connection_send_with_reply_and_block(g_conn, msg, g_waiting_time, &err);
+       dbus_message_unref(msg);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] %s", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL != result_msg) {
+               dbus_message_unref(result_msg);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Dbus] Result message is NULL.");
+       }
+
+       return 0;
+       */
+}
+
+static Eina_Bool listener_event_callback(void* data, Ecore_Fd_Handler *fd_handler)
+{
+       DBusConnection* conn = (DBusConnection*)data;
+       DBusMessage* msg = NULL;
+
+       if (NULL == conn)
+               return ECORE_CALLBACK_RENEW;
+
+       dbus_connection_read_write_dispatch(conn, 50);
+
+       msg = dbus_connection_pop_message(conn);
+
+       /* loop again if we haven't read a message */
+       if (NULL == msg) { 
+               return ECORE_CALLBACK_RENEW;
+       }
+
+       /* Common event */
+       if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_HELLO))
+               vcd_dbus_server_hello(conn, msg);
+
+       /* manager event */
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_INITIALIZE))
+               vcd_dbus_server_mgr_initialize(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_FINALIZE))
+               vcd_dbus_server_mgr_finalize(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_SET_COMMAND))
+               vcd_dbus_server_mgr_set_command(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_UNSET_COMMAND))
+               vcd_dbus_server_mgr_unset_command(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_SET_DEMANDABLE))
+               vcd_dbus_server_mgr_set_demandable_client(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_SET_AUDIO_TYPE))
+               vcd_dbus_server_mgr_set_audio_type(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_GET_AUDIO_TYPE))
+               vcd_dbus_server_mgr_get_audio_type(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_SET_CLIENT_INFO))
+               vcd_dbus_server_mgr_set_client_info(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_START)) 
+               vcd_dbus_server_mgr_start(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_STOP)) 
+               vcd_dbus_server_mgr_stop(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_CANCEL)) 
+               vcd_dbus_server_mgr_cancel(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_MANAGER_METHOD_RESULT_SELECTION)) 
+               vcd_dbus_server_mgr_result_selection(conn, msg);
+
+
+       /* client event */
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_INITIALIZE))
+               vcd_dbus_server_initialize(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_FINALIZE))
+               vcd_dbus_server_finalize(conn, msg);
+#if 0
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_SET_EXCLUSIVE_CMD))
+               vcd_dbus_server_set_exclusive_command(conn, msg);
+#endif
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_SET_COMMAND))
+               vcd_dbus_server_set_command(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_UNSET_COMMAND))
+               vcd_dbus_server_unset_command(conn, msg);
+#if 0
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_REQUEST_START))
+               vcd_dbus_server_start_request(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_REQUEST_STOP))
+               vcd_dbus_server_stop_request(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_METHOD_REQUEST_CANCEL))
+               vcd_dbus_server_cancel_request(conn, msg);
+#endif
+       /* widget event */
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_WIDGET_METHOD_INITIALIZE))
+               vcd_dbus_server_widget_initialize(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_WIDGET_METHOD_FINALIZE))
+               vcd_dbus_server_widget_finalize(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_WIDGET_METHOD_START_RECORDING))
+               vcd_dbus_server_widget_start_recording(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_WIDGET_METHOD_START))
+               vcd_dbus_server_widget_start(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_WIDGET_METHOD_STOP))
+               vcd_dbus_server_widget_stop(conn, msg);
+
+       else if (dbus_message_is_method_call(msg, VC_SERVER_SERVICE_INTERFACE, VC_WIDGET_METHOD_CANCEL))
+               vcd_dbus_server_widget_cancel(conn, msg);
+
+       else 
+               return ECORE_CALLBACK_RENEW;
+
+       /* free the message */
+       dbus_message_unref(msg);
+
+       return ECORE_CALLBACK_RENEW;
+}
+
+int vcd_dbus_open_connection()
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int ret;
+
+       /* connect to the bus and check for errors */
+       g_conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail dbus_bus_get : %s", err.message);
+               dbus_error_free(&err);
+       }
+
+       if (NULL == g_conn) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to get dbus connection" );
+               return -1;
+       }
+
+       /* request our name on the bus and check for errors */
+       ret = dbus_bus_request_name(g_conn, VC_SERVER_SERVICE_NAME, DBUS_NAME_FLAG_REPLACE_EXISTING , &err);
+
+       if (DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER != ret) {
+               printf("Fail to be primary owner in dbus request.");
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to be primary owner");
+               return -1;
+       }
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] dbus_bus_request_name() : %s", err.message);
+               dbus_error_free(&err);
+               return -1;
+       }
+
+       /* add a rule for getting signal */
+       char rule[128];
+       snprintf(rule, 128, "type='signal',interface='%s'", VC_SERVER_SERVICE_INTERFACE);
+
+       /* add a rule for which messages we want to see */
+       dbus_bus_add_match(g_conn, rule, &err);/* see signals from the given interface */
+       dbus_connection_flush(g_conn);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] dbus_bus_add_match() : %s", err.message);
+               dbus_error_free(&err);
+               return -1;
+       }
+
+       int fd = 0;
+       dbus_connection_get_unix_fd(g_conn, &fd);
+
+       if (!ecore_init()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] ecore_init()");
+               return -1;
+       }
+
+       Ecore_Fd_Handler* fd_handler;
+       fd_handler = ecore_main_fd_handler_add(fd, ECORE_FD_READ , (Ecore_Fd_Cb)listener_event_callback, g_conn, NULL, NULL);
+
+       if (NULL == fd_handler) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] Fail to get fd handler");
+               return -1;
+       }
+
+       return 0;
+}
+
+int vcd_dbus_close_connection()
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       dbus_bus_release_name (g_conn, VC_SERVER_SERVICE_NAME, &err);
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Dbus ERROR] dbus_bus_release_name() : %s", err.message);
+               dbus_error_free(&err);
+               return -1;
+       }
+
+       return 0;
+}
\ No newline at end of file
diff --git a/server/vcd_dbus.h b/server/vcd_dbus.h
new file mode 100644 (file)
index 0000000..3b889fe
--- /dev/null
@@ -0,0 +1,55 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VCD_DBUS_h__
+#define __VCD_DBUS_h__
+
+#include "vcd_main.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef enum {
+       VCD_CLIENT_TYPE_NORMAL,
+       VCD_CLIENT_TYPE_WIDGET,
+       VCD_CLIENT_TYPE_MANAGER
+}vcd_client_type_e;
+
+int vcd_dbus_open_connection();
+
+int vcd_dbus_close_connection();
+
+
+int vcdc_send_hello(int pid, vcd_client_type_e type);
+
+int vcdc_send_show_tooltip(int pid, bool show);
+
+int vcdc_send_result(int pid, int cmd_type);
+
+int vcdc_send_result_to_manager(int manger_pid);
+
+int vcdc_send_speech_detected(int manger_pid);
+
+int vcdc_send_error_signal(int pid, int reason, char *err_msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VCD_DBUS_h__ */
diff --git a/server/vcd_dbus_server.c b/server/vcd_dbus_server.c
new file mode 100644 (file)
index 0000000..60e17b1
--- /dev/null
@@ -0,0 +1,1441 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vcd_client_data.h"
+#include "vcd_dbus.h"
+#include "vcd_dbus_server.h"
+#include "vcd_main.h"
+#include "vcd_server.h"
+
+
+int __dbus_error_return(DBusConnection* conn, DBusMessage* msg, int ret)
+{
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, 
+                       DBUS_TYPE_INT32, &ret, 
+                       DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)");
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_hello(DBusConnection* conn, DBusMessage* msg)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Hello");
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+/*
+* Dbus Server functions for manager
+*/
+
+int vcd_dbus_server_mgr_initialize(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err,
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+       
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager Initialize");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr initialize : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr initialize : pid(%d)", pid);
+               ret =  vcd_server_mgr_initialize(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, 
+                       DBUS_TYPE_INT32, &ret, 
+                       DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)");
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_finalize(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager Finalize");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr finalize : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr finalize : pid(%d)", pid);
+               ret =  vcd_server_mgr_finalize(pid);
+       }
+
+       DBusMessage* reply;
+       
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_set_command(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager Set command");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr set command : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr set command : pid(%d)", pid);
+               ret = vcd_server_mgr_set_command(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               if (0 == ret) {
+                       /* Append result and language */
+                       dbus_message_append_args( reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_unset_command(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD manager unset command");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr unset command : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr unset command : pid(%d)", pid);
+               ret = vcd_server_mgr_unset_command(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               if (0 == ret) {
+                       /* Append result and language */
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_set_demandable_client(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager Set demandable client");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr set demandable client : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr set demandable client : pid(%d)", pid);
+               ret = vcd_server_mgr_set_demandable_client(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               if (0 == ret) {
+                       /* Append result and language */
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_set_audio_type(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid = 0;
+       char* audio_type = NULL;
+       
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager set audio type");
+
+       dbus_message_get_args(msg, &err, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_STRING, &audio_type,
+               DBUS_TYPE_INVALID);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr set audio type : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr set audio type : pid(%d), audio type(%s)", pid, audio_type);
+               ret = vcd_server_mgr_set_audio_type(pid, audio_type);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_get_audio_type(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid = 0;
+       char* audio_type = NULL;
+       
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager get audio type");
+
+       dbus_message_get_args(msg, &err, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr set audio type : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr set audio type : pid(%d)", pid);
+               ret = vcd_server_mgr_get_audio_type(pid, &audio_type);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, 
+                       DBUS_TYPE_INT32, &ret, 
+                       DBUS_TYPE_STRING, &audio_type, 
+                       DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d), audio type(%s)", ret, audio_type);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       if (NULL != audio_type) free(audio_type);
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_set_client_info(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid = 0;
+       
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager set client info");
+
+       dbus_message_get_args(msg, &err, 
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr set client info : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr set client info : pid(%d)", pid);
+               ret = vcd_server_mgr_set_client_info(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, 
+                       DBUS_TYPE_INT32, &ret, 
+                       DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_start(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid = 0;
+       int silence = 0;
+       int exclusive = 0;
+       int start_by_client = 0;
+       
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager start");
+
+       dbus_message_get_args(msg, &err, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INT32, &silence,
+               DBUS_TYPE_INT32, &exclusive,
+               DBUS_TYPE_INT32, &start_by_client,
+               DBUS_TYPE_INVALID);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr start : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr start : pid(%d), silence(%d), exclusive(%d), start by client(%d)", pid, silence, exclusive, start_by_client);
+               ret = vcd_server_mgr_start((bool)silence, (bool)exclusive, (bool)start_by_client);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_stop(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager stop");
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr stop : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr stop : pid(%d)", pid);
+               ret = vcd_server_mgr_stop();
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_cancel(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager cancel");
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr cancel : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr cancel : pid(%d)", pid);
+               ret = vcd_server_mgr_cancel();
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_mgr_result_selection(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       //int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Manager result selection");
+
+       if (dbus_error_is_set(&err)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd mgr result selection : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+       //      ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd mgr result selection : pid(%d)", pid);
+               //ret = vcd_server_mgr_result_select();
+               vcd_server_mgr_result_select();
+       }
+       return 0;
+
+       /*
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+       */
+}
+
+/*
+* Dbus Server functions for client
+*/
+int vcd_dbus_server_initialize(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err,
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+       
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Initialize");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd initialize : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd initialize : pid(%d)", pid);
+               ret =  vcd_server_initialize(pid);
+       }
+
+       int mgr_pid = vcd_client_manager_get_pid();
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, 
+                       DBUS_TYPE_INT32, &ret,
+                       DBUS_TYPE_INT32, &mgr_pid,
+                       DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)");
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_finalize(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Finalize");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd finalize : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd finalize : pid(%d)", pid);
+               ret =  vcd_server_finalize(pid);
+       }
+
+       DBusMessage* reply;
+       
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+#if 0
+int vcd_dbus_server_set_exclusive_command(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int value;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INT32, &value, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD set exclusive command");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd unset command : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd unset command : pid(%d) value(%d)", pid, value);
+               ret = vcd_server_set_exclusive_command(pid, (bool)value);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               if (0 == ret) {
+                       /* Append result and language */
+                       dbus_message_append_args( reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+#endif
+
+int vcd_dbus_server_set_command(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int cmd_type;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INT32, &cmd_type, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD set command");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd set command : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd set command : pid(%d), cmd_type(%d)", pid, cmd_type);
+               ret = vcd_server_set_command(pid, (vc_cmd_type_e)cmd_type);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               if (0 == ret) {
+                       /* Append result and language */
+                       dbus_message_append_args( reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_unset_command(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int cmd_type;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INT32, &cmd_type, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD unset command");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd unset command : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd unset command : pid(%d), cmd_type(%d)", pid, cmd_type);
+               ret = vcd_server_unset_command(pid, (vc_cmd_type_e)cmd_type);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               if (0 == ret) {
+                       /* Append result and language */
+                       dbus_message_append_args( reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+#if 0
+int vcd_dbus_server_start_request(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int silence;
+       
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Request Start");
+
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INT32, &silence, DBUS_TYPE_INVALID);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd start : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd request start : pid(%d), silence(%d)", pid, silence);
+               ret = vcd_server_request_start(pid, (bool)silence);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_stop_request(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Request Stop");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd stop : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd request stop : pid(%d)", pid);
+               ret = vcd_server_request_stop(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_cancel_request(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Request Cancel");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd cancel : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd request cancel : pid(%d)", pid);
+               ret = vcd_server_request_cancel(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+#endif
+
+/*
+* Dbus Widget-Daemon Server
+*/ 
+int vcd_dbus_server_widget_initialize(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       dbus_message_get_args(msg, &err,
+               DBUS_TYPE_INT32, &pid,
+               DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Widget Initialize");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd widget initialize : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd widget initialize : pid(%d)", pid);
+               ret =  vcd_server_widget_initialize(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, 
+                       DBUS_TYPE_INT32, &ret, 
+                       DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)");
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_widget_finalize(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD Widget Finalize");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd widget finalize : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd widget finalize : pid(%d)", pid);
+               ret =  vcd_server_widget_finalize(pid);
+       }
+
+       DBusMessage* reply;
+
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_widget_start_recording(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       int widget_command;
+
+       dbus_message_get_args(msg, &err, 
+               DBUS_TYPE_INT32, &pid, 
+               DBUS_TYPE_INT32, &widget_command, 
+               DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD widget start recording");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd widget start recording : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd widget start recording : pid(%d)", pid);
+               ret = vcd_server_widget_start_recording(pid, widget_command);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               if (0 == ret) {
+                       /* Append result and language */
+                       dbus_message_append_args( reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_widget_start(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int silence;
+       
+       int ret = VCD_ERROR_OPERATION_FAILED;
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD widget start");
+
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INT32, &silence, DBUS_TYPE_INVALID);
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd start : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd widget start : pid(%d), silence(%d)", pid, silence);
+               ret = vcd_server_widget_start(pid, (bool)silence);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_widget_stop(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD widget stop");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd widget stop : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd widget stop : pid(%d)", pid);
+               ret = vcd_server_widget_stop(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+int vcd_dbus_server_widget_cancel(DBusConnection* conn, DBusMessage* msg)
+{
+       DBusError err;
+       dbus_error_init(&err);
+
+       int pid;
+       int ret = VCD_ERROR_OPERATION_FAILED;
+       dbus_message_get_args(msg, &err, DBUS_TYPE_INT32, &pid, DBUS_TYPE_INVALID);
+
+       SLOG(LOG_DEBUG, TAG_VCD, ">>>>> VCD widget cancel");
+
+       if (dbus_error_is_set(&err)) { 
+               SLOG(LOG_ERROR, TAG_VCD, "[IN ERROR] vcd widget cancel : get arguments error (%s)", err.message);
+               dbus_error_free(&err);
+               ret = VCD_ERROR_OPERATION_FAILED;
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[IN] vcd widget cancel : pid(%d)", pid);
+               ret = vcd_server_widget_cancel(pid);
+       }
+
+       DBusMessage* reply;
+       reply = dbus_message_new_method_return(msg);
+
+       if (NULL != reply) {
+               dbus_message_append_args(reply, DBUS_TYPE_INT32, &ret, DBUS_TYPE_INVALID);
+
+               if (0 == ret) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[OUT SUCCESS] Result(%d)", ret);
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Result(%d)", ret);
+               }
+
+               if (!dbus_connection_send(conn, reply, NULL)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Out Of Memory!");
+               }
+
+               dbus_connection_flush(conn);
+               dbus_message_unref(reply);
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[OUT ERROR] Fail to create reply message!!");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "<<<<<");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
diff --git a/server/vcd_dbus_server.h b/server/vcd_dbus_server.h
new file mode 100644 (file)
index 0000000..40f58dc
--- /dev/null
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VCD_DBUS_SERVER_h__
+#define __VCD_DBUS_SERVER_h__
+
+#include <dbus/dbus.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int vcd_dbus_server_hello(DBusConnection* conn, DBusMessage* msg);
+
+/*
+* Dbus Server functions for manager
+*/
+
+int vcd_dbus_server_mgr_initialize(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_finalize(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_set_command(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_unset_command(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_set_demandable_client(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_set_audio_type(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_get_audio_type(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_set_client_info(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_start(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_stop(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_cancel(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_mgr_result_selection(DBusConnection* conn, DBusMessage* msg);
+
+/*
+* Dbus Server functions for client
+*/
+
+int vcd_dbus_server_initialize(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_finalize(DBusConnection* conn, DBusMessage* msg);
+
+#if 0
+int vcd_dbus_server_set_exclusive_command(DBusConnection* conn, DBusMessage* msg);
+#endif
+
+int vcd_dbus_server_set_command(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_unset_command(DBusConnection* conn, DBusMessage* msg);
+
+#if 0
+int vcd_dbus_server_start_request(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_stop_request(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_cancel_request(DBusConnection* conn, DBusMessage* msg);
+#endif
+
+/*
+* Dbus Server functions for widget
+*/ 
+int vcd_dbus_server_widget_initialize(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_widget_finalize(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_widget_start_recording(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_widget_start(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_widget_stop(DBusConnection* conn, DBusMessage* msg);
+
+int vcd_dbus_server_widget_cancel(DBusConnection* conn, DBusMessage* msg);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* __VCD_DBUS_SERVER_h__ */
diff --git a/server/vcd_engine_agent.c b/server/vcd_engine_agent.c
new file mode 100644 (file)
index 0000000..c4c2681
--- /dev/null
@@ -0,0 +1,916 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include <dlfcn.h>
+#include <dirent.h>
+
+#include "vcd_client_data.h"
+#include "vcd_config.h"
+#include "vcd_engine_agent.h"
+#include "vcd_main.h"
+#include "vcd_recorder.h"
+
+/*
+* Internal data structure
+*/
+typedef struct {
+       /* engine info */
+       char*   engine_uuid;
+       char*   engine_name;
+       char*   engine_path;
+
+       /* engine load info */
+       bool    is_set;
+       bool    is_loaded;      
+       bool    is_command_ready;
+       void    *handle;
+
+       vcpe_funcs_s*   pefuncs;
+       vcpd_funcs_s*   pdfuncs;
+
+       int (*vcp_load_engine)(vcpd_funcs_s* pdfuncs, vcpe_funcs_s* pefuncs);
+       int (*vcp_unload_engine)();
+} vcengine_s;
+
+typedef struct _vcengine_info {
+       char*   engine_uuid;
+       char*   engine_path;
+       char*   engine_name;
+} vcengine_info_s;
+
+
+/*
+* static data
+*/
+
+/** vc engine agent init */
+static bool g_agent_init;
+
+/** vc engine list */
+static GList *g_engine_list;           
+
+/** current engine information */
+static vcengine_s g_dynamic_engine;
+
+static char* g_default_lang;
+
+/** callback functions */
+static result_callback g_result_cb;
+
+bool __supported_language_cb(const char* language, void* user_data);
+
+void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* engine_setting, bool use_network, void* user_data);
+
+bool __engine_setting_cb(const char* key, const char* value, void* user_data);
+
+/** Free voice list */
+void __free_language_list(GList* lang_list);
+
+
+/*
+* Internal Interfaces 
+*/
+
+/** check engine id */
+int __internal_check_engine_id(const char* engine_uuid);
+
+/** update engine list */
+int __internal_update_engine_list();
+
+/** get engine info */
+int __internal_get_engine_info(const char* filepath, vcengine_info_s** info);
+
+int __log_enginelist();
+
+/*
+* VCS Engine Agent Interfaces
+*/
+int vcd_engine_agent_init(result_callback result_cb)
+{
+       if (NULL == result_cb) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* init dynamic engine */
+       g_dynamic_engine.engine_uuid = NULL;
+       g_dynamic_engine.engine_name = NULL;
+       g_dynamic_engine.engine_path = NULL;
+
+       g_dynamic_engine.is_set = false;
+       g_dynamic_engine.is_loaded = false;
+       g_dynamic_engine.handle = NULL;
+       g_dynamic_engine.is_command_ready = false;
+       g_dynamic_engine.pefuncs = (vcpe_funcs_s*)calloc(1, sizeof(vcpe_funcs_s));
+       g_dynamic_engine.pdfuncs = (vcpd_funcs_s*)calloc(1, sizeof(vcpd_funcs_s));
+
+       g_agent_init = true;
+
+       g_result_cb = result_cb;
+
+       if (0 != vcd_config_get_default_language(&g_default_lang)) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] There is No default voice in config");
+               /* Set default voice */
+               g_default_lang = strdup(VC_BASE_LANGUAGE);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent Initialize");
+
+       return 0;
+}
+
+int vcd_engine_agent_release()
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* unload current engine */
+       vcd_engine_agent_unload_current_engine();
+
+       /* release engine list */
+       GList *iter = NULL;
+       vcengine_s *data = NULL;
+
+       if (g_list_length(g_engine_list) > 0) {
+               /* Get a first item */
+               iter = g_list_first(g_engine_list);
+
+               while (NULL != iter) {
+                       /* Get handle data from list */
+                       data = iter->data;
+                       iter = g_list_remove(iter, data);
+               }
+       }
+
+       g_list_free(iter);
+       
+       /* release current engine data */
+       if (NULL != g_dynamic_engine.pefuncs)   free(g_dynamic_engine.pefuncs);
+       if (NULL != g_dynamic_engine.pdfuncs)   free(g_dynamic_engine.pdfuncs);
+
+       g_agent_init = false;
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine Agent release");
+
+       return 0;
+}
+
+bool vcd_engine_is_available_engine()
+{
+       if (true == g_dynamic_engine.is_loaded) 
+               return true;
+       
+       return false;
+}
+
+int vcd_engine_agent_initialize_current_engine()
+{
+       /* check agent init */
+       if (false == g_agent_init ) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* update engine list */
+       if (0 != __internal_update_engine_list()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[engine agent] vcd_engine_agent_init : __internal_update_engine_list : no engine error");
+               return VCD_ERROR_ENGINE_NOT_FOUND;
+       }
+
+       /* check whether engine id is valid or not.*/
+       GList *iter = NULL;
+       vcengine_info_s *dynamic_engine = NULL;
+
+       if (g_list_length(g_engine_list) > 0) {
+               /*Get a first item*/
+               iter = g_list_first(g_engine_list);
+
+               while (NULL != iter) {
+                       /*Get handle data from list*/
+                       dynamic_engine = iter->data;
+                       if (NULL != dynamic_engine) {
+                               break;
+                       }
+
+                       /*Get next item*/
+                       iter = g_list_next(iter);
+               }
+       } else {
+               return VCD_ERROR_ENGINE_NOT_FOUND;
+       }
+
+       if (NULL == dynamic_engine) {
+               return VCD_ERROR_ENGINE_NOT_FOUND;
+       } else {
+               if (NULL != g_dynamic_engine.engine_uuid) {
+                       /* set data from g_engine_list */
+                       if (g_dynamic_engine.engine_uuid != NULL)       free(g_dynamic_engine.engine_uuid);
+                       if (g_dynamic_engine.engine_name != NULL)       free(g_dynamic_engine.engine_name);
+                       if (g_dynamic_engine.engine_path != NULL)       free(g_dynamic_engine.engine_path);
+               }
+
+               g_dynamic_engine.engine_uuid = g_strdup(dynamic_engine->engine_uuid);
+               g_dynamic_engine.engine_name = g_strdup(dynamic_engine->engine_name);
+               g_dynamic_engine.engine_path = g_strdup(dynamic_engine->engine_path);
+
+               g_dynamic_engine.handle = NULL;
+               g_dynamic_engine.is_loaded = false;
+               g_dynamic_engine.is_set = true;
+
+               SLOG(LOG_DEBUG, TAG_VCD, "-----");
+               SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine uuid : %s", g_dynamic_engine.engine_uuid);
+               SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine name : %s", g_dynamic_engine.engine_name);
+               SLOG(LOG_DEBUG, TAG_VCD, " Dynamic engine path : %s", g_dynamic_engine.engine_path);
+               SLOG(LOG_DEBUG, TAG_VCD, "-----");
+               
+       }
+
+       return 0;
+}
+
+int __internal_check_engine_id(const char* engine_uuid)
+{
+       if (NULL == engine_uuid) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       GList *iter = NULL;
+       vcengine_s *data = NULL;
+
+       if (0 < g_list_length(g_engine_list)) {
+               /*Get a first item*/
+               iter = g_list_first(g_engine_list);
+
+               while (NULL != iter) {
+                       data = iter->data;
+                       
+                       if (0 == strncmp(engine_uuid, data->engine_uuid, strlen(data->engine_uuid))) {
+                               return 0;
+                       }
+
+                       iter = g_list_next(iter);
+               }
+       }
+
+       return -1;
+}
+
+void __engine_info_cb(const char* engine_uuid, const char* engine_name, const char* engine_setting, bool use_network, void* user_data)
+{
+       vcengine_info_s* temp = (vcengine_info_s*)user_data;
+
+       temp->engine_uuid = g_strdup(engine_uuid);
+       temp->engine_name = g_strdup(engine_name);
+}
+
+
+int __internal_get_engine_info(const char* filepath, vcengine_info_s** info)
+{
+       if (NULL == filepath || NULL == info) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* load engine */
+       char *error;
+       void* handle;
+
+       handle = dlopen(filepath, RTLD_LAZY);
+
+       if (!handle) {
+               SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine : %s", filepath);
+               return -1;
+       }
+
+       /* link engine to daemon */
+       dlsym(handle, "vcp_load_engine");
+       if ((error = dlerror()) != NULL) {
+               SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine. Fail to open vcp_load_engine : %s", filepath);
+               dlclose(handle);
+               return -1;
+       }
+
+       dlsym(handle, "vcp_unload_engine");
+       if ((error = dlerror()) != NULL) {
+               SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Invalid engine. Fail to open vcp_unload_engine : %s", filepath);
+               dlclose(handle);
+               return -1;
+       }
+
+       int (*get_engine_info)(vcpe_engine_info_cb callback, void* user_data);
+
+       get_engine_info = (int (*)(vcpe_engine_info_cb, void*))dlsym(handle, "vcp_get_engine_info");
+       if ((error = dlerror()) != NULL) {
+               SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] Invalid engine. Fail to open vcp_get_engine_info : %s", filepath);
+               dlclose(handle);
+               return -1;
+       }
+
+       vcengine_info_s* temp;
+       temp = (vcengine_info_s*)calloc(1, sizeof(vcengine_info_s));
+       if (NULL == temp) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to allocate memory");
+               dlclose(handle);
+               return VCD_ERROR_OUT_OF_MEMORY;
+       }
+
+       /* get engine info */
+       if (0 != get_engine_info(__engine_info_cb, (void*)temp)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine info from engine");
+               dlclose(handle);
+               free(temp);
+               return -1;
+       }
+
+       /* close engine */
+       dlclose(handle);
+
+       temp->engine_path = g_strdup(filepath);
+
+       SLOG(LOG_DEBUG, TAG_VCD, "----- Valid Engine");
+       SLOG(LOG_DEBUG, TAG_VCD, "Engine uuid : %s", temp->engine_uuid);
+       SLOG(LOG_DEBUG, TAG_VCD, "Engine name : %s", temp->engine_name);
+       SLOG(LOG_DEBUG, TAG_VCD, "Engine path : %s", temp->engine_path);
+       SLOG(LOG_DEBUG, TAG_VCD, "-----");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       *info = temp;
+
+       return 0;
+}
+
+int __internal_update_engine_list()
+{
+       /* relsease engine list */
+       GList *iter = NULL;
+       vcengine_info_s *data = NULL;
+
+       if (0 < g_list_length(g_engine_list)) {
+               /* Get a first item */
+               iter = g_list_first(g_engine_list);
+
+               while (NULL != iter) {
+                       /* Get handle data from list */
+                       data = iter->data;
+
+                       if (NULL != data) {
+                               if (NULL != data->engine_uuid)          free(data->engine_uuid);
+                               if (NULL != data->engine_path)          free(data->engine_path);
+                               if (NULL != data->engine_name)          free(data->engine_name);
+                               
+                               free(data);
+                       }
+
+                       g_engine_list = g_list_remove_link(g_engine_list, iter);
+                       iter = g_list_first(g_engine_list);
+               }
+       }
+
+       /* Get file name from default engine directory */
+       DIR *dp = NULL;
+       int ret = -1;
+       struct dirent entry;
+       struct dirent *dirp = NULL;
+
+       dp  = opendir(ENGINE_DIRECTORY_DEFAULT);
+       if (NULL != dp) {
+               do {
+                       ret = readdir_r(dp, &entry, &dirp);
+                       if (0 != ret) {
+                               SLOG(LOG_ERROR, TAG_VCD, "[File ERROR] Fail to read directory");
+                               break;
+                       }
+
+                       if (NULL != dirp) {
+                               vcengine_info_s* info = NULL;
+                               char* filepath = NULL;
+                               int filesize = 0;
+
+                               filesize = strlen(ENGINE_DIRECTORY_DEFAULT) + strlen(dirp->d_name) + 5;
+                               filepath = (char*)calloc(filesize, sizeof(char));
+
+                               if (NULL != filepath) {
+                                       snprintf(filepath, filesize, "%s/%s", ENGINE_DIRECTORY_DEFAULT, dirp->d_name);
+                               } else {
+                                       SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Memory not enough!!");
+                                       continue;
+                               }
+
+                               /* get its info and update engine list */
+                               if (0 == __internal_get_engine_info(filepath, &info)) {
+                                       /* add engine info to g_engine_list */
+                                       g_engine_list = g_list_append(g_engine_list, info);
+                               }
+
+                               if (NULL != filepath) {
+                                       free(filepath);
+                                       filepath = NULL;
+                               }
+                       }
+               } while (NULL != dirp);
+
+               closedir(dp);
+       } else {
+               SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] Fail to open default directory");
+       }
+       
+       if (0 >= g_list_length(g_engine_list)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] No Engine");
+               return VCD_ERROR_ENGINE_NOT_FOUND;      
+       }
+
+       __log_enginelist();
+       
+       return 0;
+}
+
+
+int __foreach_command(vcp_cmd_h vc_command, vcpd_foreach_command_cb callback, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request foreach command from engine");
+       return vcd_client_foreach_command((client_foreach_command_cb)callback, user_data);
+}
+
+int __command_get_length(vcp_cmd_h vc_command)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request command length from engine");
+       return vcd_client_get_length();
+}
+
+int __get_audio_type(char** audio_type)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Request audio type");
+
+       return vcd_recorder_get(audio_type);
+}
+
+void __result_cb(vcp_result_event_e event, int* result_id, int count, const char* all_result, const char* non_fixed, const char* msg, void *user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine agent] Event(%d), Count(%d) Text(%s) Nonfixed(%s) Msg(%s)", event, count, all_result, non_fixed, msg);
+
+       if (NULL != g_result_cb) {
+               g_result_cb(event, result_id, count, all_result, non_fixed, msg, user_data);
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent ERROR] Result callback function is NOT valid");
+       }
+
+       return;
+}
+
+int __load_engine(vcengine_s* engine)
+{
+       /* check whether current engine is loaded or not */
+       if (true == engine->is_loaded) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine has already been loaded ");
+               return 0;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Current engine path : %s", engine->engine_path);
+
+       /* open engine */
+       char *error;
+       engine->handle = dlopen(engine->engine_path, RTLD_LAZY);
+
+       if ((error = dlerror()) != NULL || !engine->handle) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to get engine handle");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       engine->vcp_unload_engine = (int (*)())dlsym(engine->handle, "vcp_unload_engine");
+       if ((error = dlerror()) != NULL) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to link daemon to vcp_unload_engine()");
+               dlclose(engine->handle);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       engine->vcp_load_engine = (int (*)(vcpd_funcs_s*, vcpe_funcs_s*) )dlsym(engine->handle, "vcp_load_engine");
+       if ((error = dlerror()) != NULL) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to link daemon to vcp_load_engine()");
+               dlclose(engine->handle);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* load engine */
+       engine->pdfuncs->version = 1;
+       engine->pdfuncs->size = sizeof(vcpd_funcs_s);
+
+       engine->pdfuncs->foreach_command = __foreach_command;
+       engine->pdfuncs->get_command_count = __command_get_length;
+       engine->pdfuncs->get_audio_type = __get_audio_type;
+
+       if (0 != engine->vcp_load_engine(engine->pdfuncs, engine->pefuncs)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail vcp_load_engine()");
+               dlclose(engine->handle);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] engine info : version(%d), size(%d)",engine->pefuncs->version, engine->pefuncs->size);
+
+       /* engine error check */
+       if (engine->pefuncs->size != sizeof(vcpe_funcs_s)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not valid");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* Check all engine functions */
+       if (NULL == engine->pefuncs->initialize ||
+               NULL == engine->pefuncs->deinitialize ||
+               NULL == engine->pefuncs->foreach_langs ||
+               NULL == engine->pefuncs->is_lang_supported ||
+               NULL == engine->pefuncs->set_result_cb ||
+               NULL == engine->pefuncs->set_language ||
+               NULL == engine->pefuncs->set_recording ||
+               NULL == engine->pefuncs->stop ||
+               NULL == engine->pefuncs->cancel) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The current engine is NOT valid");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* initalize engine */
+       if (0 != engine->pefuncs->initialize()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to initialize vc-engine");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+       
+       if (0 != engine->pefuncs->set_result_cb(__result_cb, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set result callback of vc-engine");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* load engine */
+       if (true == engine->pefuncs->is_lang_supported(g_default_lang)) {
+               if (0 != engine->pefuncs->set_language(g_default_lang)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to load current engine");
+                       return VCD_ERROR_OPERATION_FAILED;
+               }
+               SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] The %s has been loaded !!!", engine->engine_name);
+               engine->is_loaded = true;
+       } else {
+               SLOG(LOG_WARN, TAG_VCD, "[Engine Agent WARNING] This engine do not support default language : lang(%s)", g_default_lang);
+               engine->is_loaded = false;
+       }
+
+       return 0;
+}
+
+int vcd_engine_agent_load_current_engine()
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       if (true == g_dynamic_engine.is_set) {
+               if (0 != __load_engine(&g_dynamic_engine)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to load dynamic engine");
+
+                       /* need to initialize dynamic engine data */
+                       g_dynamic_engine.is_loaded = false;
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Load dynamic engine");
+               }
+       }
+       
+       return 0;
+}
+
+int vcd_engine_agent_unload_current_engine()
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized ");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       if (true == g_dynamic_engine.is_set) {
+               /* unload dynamic engine */
+               if (true == g_dynamic_engine.is_loaded) {
+                       /* shutdown engine */
+                       g_dynamic_engine.pefuncs->deinitialize();
+                       g_dynamic_engine.vcp_unload_engine();
+                       dlclose(g_dynamic_engine.handle);
+                       g_dynamic_engine.handle = NULL;
+                       g_dynamic_engine.is_loaded = false;
+               }
+       }
+       return 0;
+}
+
+
+/*
+* VCS Engine Interfaces for client
+*/
+
+int vcd_engine_set_commands()
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       int ret = -1;
+
+       if (true == g_dynamic_engine.is_loaded) {
+               /* Set dynamic command */
+               ret = g_dynamic_engine.pefuncs->set_commands((vcp_cmd_h)0);
+               if (0 != ret) {
+                       SLOG(LOG_WARN, TAG_VCD, "[Engine Agent ERROR] Fail to set command of dynamic engine : error(%d)", ret);
+                       g_dynamic_engine.is_command_ready = false;
+               } else {
+                       g_dynamic_engine.is_command_ready = true;
+               }
+
+               SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] set command");
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Dynamic engine is not available");
+       }
+
+       return 0;
+}
+
+int vcd_engine_recognize_start(bool silence)
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       int ret = -1;
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] silence is %s", silence ? "true" : "false");
+       
+       if (true == g_dynamic_engine.is_loaded && true == g_dynamic_engine.is_command_ready) {
+               ret = g_dynamic_engine.pefuncs->start(silence);
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent] Fail to start engine error(%d)", ret);
+                       return VCD_ERROR_OPERATION_FAILED;
+               }
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Engine is not available (Cannot start)");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent SUCCESS] Engine start");
+       return 0;
+}
+
+int vcd_engine_recognize_audio(const void* data, unsigned int length, vcp_speech_detect_e* speech_detected)
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       if (NULL == data) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = -1;
+
+       if (true == g_dynamic_engine.is_loaded) {
+               ret = g_dynamic_engine.pefuncs->set_recording(data, length, speech_detected);
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to set recording dynamic engine error(%d)", ret);
+                       return VCD_ERROR_OPERATION_FAILED;
+               }
+       }
+
+       return 0;
+}
+
+int vcd_engine_recognize_stop()
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       if (true == g_dynamic_engine.is_loaded) {
+               int ret = -1;
+               ret = g_dynamic_engine.pefuncs->stop();
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to stop dynamic engine error(%d)", ret);
+                       return VCD_ERROR_OPERATION_FAILED;
+               }
+       } else {
+               SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Dynamic engine is not recording state");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return 0;
+}
+
+int vcd_engine_recognize_cancel()
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       int ret = -1;
+       if (true == g_dynamic_engine.is_loaded) {
+               ret = g_dynamic_engine.pefuncs->cancel();
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Fail to cancel dynamic engine error(%d)", ret);
+               }
+       } 
+
+       return 0;
+}
+
+
+/*
+* VCS Engine Interfaces for client and setting
+*/
+
+int vcd_engine_get_audio_format(const char* audio_id, vcp_audio_type_e* types, int* rate, int* channels)
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       if (true != g_dynamic_engine.is_loaded) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
+       }
+
+       if (NULL == g_dynamic_engine.pefuncs->get_recording_format) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The function of engine is NULL!!");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       int ret = g_dynamic_engine.pefuncs->get_recording_format(audio_id, types, rate, channels);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get recording format(%d)", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return 0;
+}
+
+bool __supported_language_cb(const char* language, void* user_data)
+{
+       GList** lang_list = (GList**)user_data;
+
+       if (NULL == language || NULL == lang_list) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Input parameter is NULL in callback!!!!");
+               return false;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "-- Language(%s)", language);
+
+       char* temp_lang = g_strdup(language);
+
+       *lang_list = g_list_append(*lang_list, temp_lang);
+
+       return true;
+}
+
+int vcd_engine_supported_langs(GList** lang_list)
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       if (true != g_dynamic_engine.is_loaded) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Engine is not loaded");
+       }
+
+       if (NULL == g_dynamic_engine.pefuncs->foreach_langs) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] The function of engine is NULL!!");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       int ret = g_dynamic_engine.pefuncs->foreach_langs(__supported_language_cb, (void*)lang_list);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] get language list error(%d)", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+       
+       return 0;
+}
+
+
+int vcd_engine_get_current_language(char** lang)
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       if (NULL == lang) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* get default language */
+       *lang = g_strdup(g_default_lang);
+
+       return 0;
+}
+
+int vcd_engine_set_current_language(const char* language)
+{
+       if (false == g_agent_init) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Not Initialized");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       if (NULL == language) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Engine Agent ERROR] Invalid Parameter");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret;
+
+       if (true == g_dynamic_engine.is_loaded) {
+               g_dynamic_engine.is_command_ready = false;
+
+               ret = g_dynamic_engine.pefuncs->set_language(language);
+               if (0 != ret) {
+                       SLOG(LOG_WARN, TAG_VCD, "[Engine Agent] Fail to set language of dynamic engine error(%d, %s)", ret, language);
+               } 
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Engine Agent] Dynamic engine is not available (Cannot start)");
+       }
+
+       return 0;
+}
+
+void __free_language_list(GList* lang_list)
+{
+       GList *iter = NULL;
+       char* data = NULL;
+
+       /* if list have item */
+       if (g_list_length(lang_list) > 0) {
+               /* Get a first item */
+               iter = g_list_first(lang_list);
+
+               while (NULL != iter) {
+                       data = iter->data;
+
+                       if (NULL != data)
+                               free(data);
+                       
+                       lang_list = g_list_remove_link(lang_list, iter);
+
+                       iter = g_list_first(lang_list);
+               }
+       }
+}
+
+int __log_enginelist()
+{
+       GList *iter = NULL;
+       vcengine_info_s *data = NULL;
+
+       if (0 < g_list_length(g_engine_list)) {
+
+               /* Get a first item */
+               iter = g_list_first(g_engine_list);
+
+               SLOG(LOG_DEBUG, TAG_VCD, "--------------- engine list -------------------");
+
+               int i = 1;      
+               while (NULL != iter) {
+                       /* Get handle data from list */
+                       data = iter->data;
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[%dth]", i);
+                       SLOG(LOG_DEBUG, TAG_VCD, "  engine uuid : %s", data->engine_uuid);
+                       SLOG(LOG_DEBUG, TAG_VCD, "  engine name : %s", data->engine_name);
+                       SLOG(LOG_DEBUG, TAG_VCD, "  engine path : %s", data->engine_path);
+                       iter = g_list_next(iter);
+                       i++;
+               }
+               SLOG(LOG_DEBUG, TAG_VCD, "----------------------------------------------");
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "-------------- engine list -------------------");
+               SLOG(LOG_DEBUG, TAG_VCD, "  No Engine in engine directory");
+               SLOG(LOG_DEBUG, TAG_VCD, "----------------------------------------------");
+       }
+
+       return 0;
+}
+
+
+
+
diff --git a/server/vcd_engine_agent.h b/server/vcd_engine_agent.h
new file mode 100644 (file)
index 0000000..462f1fb
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VCD_ENGINE_AGENT_H_
+#define __VCD_ENGINE_AGENT_H_
+
+#include "vcd_main.h"
+#include "voice_control_plugin_engine.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+* Constants & Structures       
+*/
+
+#define        ENGINE_PATH_SIZE 256
+
+typedef void (*result_callback)(vcp_result_event_e event, int* result_id, int count, 
+                               const char* all_result, const char* non_fixed_result, const char* msg, void *user_data);
+
+typedef void (*silence_dectection_callback)(void *user_data);
+
+
+
+/** Init engine agent */
+int vcd_engine_agent_init(result_callback result_cb);
+
+/** Release engine agent */
+int vcd_engine_agent_release();
+
+bool vcd_engine_is_available_engine();
+
+/** Set current engine */
+int vcd_engine_agent_initialize_current_engine();
+
+/** load current engine */
+int vcd_engine_agent_load_current_engine();
+
+/** Unload current engine */
+int vcd_engine_agent_unload_current_engine();
+
+/** test for language list */
+int vcd_print_enginelist();
+
+
+int vcd_engine_get_audio_format(const char* audio_id, vcp_audio_type_e* types, int* rate, int* channels);
+
+int vcd_engine_supported_langs(GList** lang_list);
+
+int vcd_engine_get_current_language(char** lang);
+
+int vcd_engine_set_current_language(const char* language);
+
+int vcd_engine_set_commands();
+
+/* normal recognition */
+int vcd_engine_recognize_start(bool silence);
+
+int vcd_engine_recognize_audio(const void* data, unsigned int length, vcp_speech_detect_e* speech_detected);
+
+int vcd_engine_recognize_stop();
+
+int vcd_engine_recognize_cancel();
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VCD_ENGINE_AGENT_H_ */
+
+
diff --git a/server/vcd_main.c b/server/vcd_main.c
new file mode 100644 (file)
index 0000000..4de03e8
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include "vcd_dbus.h"
+#include "vcd_main.h"
+#include "vcd_server.h"
+
+#include <privilege-control.h>
+
+#define CLIENT_CLEAN_UP_TIME 500
+
+static Ecore_Timer* g_check_client_timer = NULL;
+
+int main(int argc, char** argv)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+       SLOG(LOG_DEBUG, TAG_VCD, "===== VC Daemon Initialize");
+
+       if (!ecore_init()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail ecore_init()");
+               return -1;
+       }
+
+       if (0 == setuid(0)) {
+               /* daemon has root previlege */
+               perm_app_set_privilege("voice-control", NULL, NULL);
+       }
+
+       if (0 != vcd_dbus_open_connection()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to open connection");
+               return EXIT_FAILURE;
+       }
+
+       if (0 != vcd_initialize()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[ERROR] Fail to initialize vc-daemon");
+               return EXIT_FAILURE;
+       }
+
+       g_check_client_timer = ecore_timer_add(CLIENT_CLEAN_UP_TIME, vcd_cleanup_client, NULL);
+       if (NULL == g_check_client_timer) {
+               SLOG(LOG_WARN, TAG_VCD, "[Main Warning] Fail to create timer of client check");
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Main] vc-daemon start...");
+
+       SLOG(LOG_DEBUG, TAG_VCD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       ecore_main_loop_begin();
+
+       SLOG(LOG_DEBUG, TAG_VCD, "===== VC Daemon Finalize");
+
+       if (NULL != g_check_client_timer) {
+               ecore_timer_del(g_check_client_timer);
+       }
+
+       vcd_dbus_close_connection();
+
+       vcd_finalize();
+
+       ecore_shutdown();
+
+       SLOG(LOG_DEBUG, TAG_VCD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return 0;
+}
+
+
diff --git a/server/vcd_main.h b/server/vcd_main.h
new file mode 100644 (file)
index 0000000..2e72e7c
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VCD_MAIN_H_
+#define __VCD_MAIN_H_
+
+#include <Ecore.h>
+#include <dlog.h>
+#include <errno.h>
+#include <glib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <stdlib.h>
+#include <string.h>
+#include <tizen.h>
+#include <unistd.h>
+
+#include "vc_defs.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+* Daemon Define
+*/
+
+#define TAG_VCD "vcd"
+
+#define BASE_DIRECTORY_DEFAULT                 "/usr/lib/voice/vc/1.0"
+#define ENGINE_DIRECTORY_DEFAULT               "/usr/lib/voice/vc/1.0/engine"
+#define ENGINE_DIRECTORY_DEFAULT_SETTING       "/usr/lib/voice/vc/setting"
+
+#define CONFIG_DIRECTORY                       "/opt/home/app/.voice"
+
+#define ENGINE_DIRECTORY_DOWNLOAD              "/opt/usr/voice/vc/engine"
+#define ENGINE_DIRECTORY_DOWNLOAD_SETTING      "/opt/usr/voice/vc/setting"
+
+/* for debug message */
+// #define RECORDER_DEBUG
+#define CLIENT_DATA_DEBUG
+// #define COMMAND_DATA_DEBUG
+
+typedef enum {
+       VCD_ERROR_NONE                  = TIZEN_ERROR_NONE,                     /**< Successful */
+       VCD_ERROR_OUT_OF_MEMORY         = TIZEN_ERROR_OUT_OF_MEMORY,            /**< Out of Memory */
+       VCD_ERROR_IO_ERROR              = TIZEN_ERROR_IO_ERROR,                 /**< I/O error */
+       VCD_ERROR_INVALID_PARAMETER     = TIZEN_ERROR_INVALID_PARAMETER,        /**< Invalid parameter */
+       VCD_ERROR_TIMED_OUT             = TIZEN_ERROR_TIMED_OUT,                /**< No answer from service */
+       VCD_ERROR_RECORDER_BUSY         = TIZEN_ERROR_RESOURCE_BUSY,            /**< Busy recorder */
+       VCD_ERROR_PERMISSION_DENIED     = TIZEN_ERROR_PERMISSION_DENIED,        /**< Permission denied */
+       VCD_ERROR_NOT_SUPPORTED         = TIZEN_ERROR_NOT_SUPPORTED,            /**< VC NOT supported */
+       VCD_ERROR_INVALID_STATE         = TIZEN_ERROR_VOICE_CONTROL | 0x011,    /**< Invalid state */
+       VCD_ERROR_INVALID_LANGUAGE      = TIZEN_ERROR_VOICE_CONTROL | 0x012,    /**< Invalid language */
+       VCD_ERROR_ENGINE_NOT_FOUND      = TIZEN_ERROR_VOICE_CONTROL | 0x013,    /**< No available engine */
+       VCD_ERROR_OPERATION_FAILED      = TIZEN_ERROR_VOICE_CONTROL | 0x014,    /**< Operation failed */
+       VCD_ERROR_OPERATION_REJECTED    = TIZEN_ERROR_VOICE_CONTROL | 0x015     /**< Operation rejected */
+}vcd_error_e;
+
+typedef enum {
+       VCD_STATE_NONE = 0,
+       VCD_STATE_READY = 1,
+       VCD_STATE_RECORDING = 2,
+       VCD_STATE_PROCESSING = 3
+}vcd_state_e;
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VCD_MAIN_H_ */
diff --git a/server/vcd_recorder.c b/server/vcd_recorder.c
new file mode 100644 (file)
index 0000000..77b522f
--- /dev/null
@@ -0,0 +1,650 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#include <audio_io.h>
+#include <bluetooth.h>
+#include <math.h>
+#include <sound_manager.h>
+
+#include "vcd_recorder.h"
+#include "vcd_main.h"
+#include "voice_control_plugin_engine.h"
+
+/* Multi session enable */
+//#define AUDIO_MULTI_SESSION
+
+/* TV BT enable */
+//#define TV_BT_MODE
+
+#define FRAME_LENGTH 160
+#define BUFFER_LENGTH FRAME_LENGTH * 2
+
+#define VCP_AUDIO_ID_NONE              "VC_AUDIO_ID_NONE"              /**< None audio id */
+
+static vcd_recorder_state_e    g_recorder_state = VCD_RECORDER_STATE_READY;
+
+static vcd_recoder_audio_cb    g_audio_cb = NULL;
+
+static vcd_recorder_interrupt_cb       g_interrupt_cb = NULL;
+
+static audio_in_h      g_audio_h;
+
+static vcp_audio_type_e g_audio_type;
+
+static int             g_audio_rate;
+
+static int             g_audio_channel;
+
+static FILE*   g_pFile_vol;
+
+static char    g_normal_buffer[BUFFER_LENGTH + 10];
+
+static bool    g_is_valid_audio_in = false;
+
+static bool    g_is_valid_bt_in = false;
+
+static char*   g_current_audio_type = NULL;
+
+#ifdef AUDIO_MULTI_SESSION
+static sound_multi_session_h   g_session = NULL;
+#endif
+
+static int     g_buffer_count;
+
+/* Sound buf save */
+/*
+#define BUF_SAVE_MODE
+*/
+
+#ifdef BUF_SAVE_MODE
+static FILE* g_normal_file;
+
+static int g_count = 1;
+#endif
+
+static float get_volume_decibel(char* data, int size);
+
+#ifdef TV_BT_MODE
+static int g_bt_extend_count;
+
+#define SMART_CONTROL_EXTEND_CMD       0x03
+#define SMART_CONTROL_START_CMD                0x04
+
+static void _bt_cb_hid_state_changed(int result, bool connected, const char *remote_address, void *user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth Event [%d] Received address [%s]", result, remote_address);
+       return;
+}
+
+static void _bt_hid_audio_data_receive_cb(bt_hid_voice_data_s *voice_data, void *user_data)
+{
+       if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
+               /*SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");*/
+               return;
+       }
+
+       if (NULL != g_audio_cb) {
+               if (0 != g_audio_cb((void*)voice_data->audio_buf, (unsigned int)voice_data->length)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio");
+                       vcd_recorder_stop();
+               }
+
+               float vol_db = get_volume_decibel((char*)voice_data->audio_buf, (int)voice_data->length);
+
+               rewind(g_pFile_vol);
+
+               fwrite((void*)(&vol_db), sizeof(vol_db), 1, g_pFile_vol);
+       }
+
+       if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
+               SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, voice_data->length);
+               
+               if (0 == g_bt_extend_count % 5) {
+                       const unsigned char input_data[2] = {SMART_CONTROL_EXTEND_CMD, 0x00 };
+                       if (BT_ERROR_NONE != bt_hid_send_rc_command(NULL, input_data, sizeof(input_data))) {
+                               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command(NULL, %s, %d)", input_data, sizeof(input_data));
+                       }
+                       else {
+                               SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Extend bt audio recorder");
+                       }
+               }
+               g_bt_extend_count++;
+
+               if (100000 == g_buffer_count) {
+                       g_buffer_count = 0;
+               }
+       }
+
+       g_buffer_count++;
+
+#ifdef BUF_SAVE_MODE
+       /* write pcm buffer */
+       fwrite(voice_data->audio_buf, 1, voice_data->length, g_normal_file);
+#endif
+       return;
+}
+
+#endif
+
+#ifdef AUDIO_MULTI_SESSION
+void __vcd_recorder_sound_interrupted_cb(sound_interrupted_code_e code, void *user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Get the interrupt code from sound mgr : %d", code);
+
+       if (SOUND_INTERRUPTED_BY_CALL == code) {
+               if (NULL != g_interrupt_cb) {
+                       g_interrupt_cb();
+               }
+       }
+
+       return;
+}
+#endif
+
+int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb)
+{
+       if (NULL == audio_cb || NULL == interrupt_cb) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input param is NOT valid");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = 0;
+#ifdef AUDIO_MULTI_SESSION
+       g_session = NULL;
+       ret = sound_manager_multi_session_create(SOUND_MULTI_SESSION_TYPE_VOICE_RECOGNITION, &g_session);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create multi session : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       ret = sound_manager_set_interrupted_cb(__vcd_recorder_sound_interrupted_cb, NULL);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set interrupt callback : %d", ret);
+               sound_manager_multi_session_destroy(g_session);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       ret = sound_manager_multi_session_set_mode(g_session, SOUND_MULTI_SESSION_MODE_VR_NORMAL);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set mode : %d", ret);
+               sound_manager_unset_interrupted_cb();
+               sound_manager_multi_session_destroy(g_session);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+#endif
+       /* set init value */
+       g_is_valid_audio_in = false;
+       g_is_valid_bt_in = false;
+       g_current_audio_type = NULL;
+
+       g_audio_type = VCP_AUDIO_TYPE_PCM_S16_LE;
+       g_audio_rate = 16000;
+       g_audio_channel = 1;
+       
+       audio_channel_e audio_ch;
+       audio_sample_type_e audio_type;
+
+       switch (g_audio_channel) {
+       case 1: audio_ch = AUDIO_CHANNEL_MONO;          break;
+       case 2: audio_ch = AUDIO_CHANNEL_STEREO;        break;
+       default:
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
+               return VCD_ERROR_OPERATION_FAILED;
+               break;
+       }
+
+       switch (g_audio_type) {
+       case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE;  break;
+       case VCP_AUDIO_TYPE_PCM_U8:     audio_type = AUDIO_SAMPLE_TYPE_U8;      break;
+       default:
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
+               return VCD_ERROR_OPERATION_FAILED;
+               break;
+       }
+
+       /*
+       ret = audio_in_create_ex(sample_rate, audio_ch, audio_type, &g_audio_h, AUDIO_IO_SOURCE_TYPE_VOICECONTROL);
+       */
+       ret = audio_in_create(g_audio_rate, audio_ch, audio_type, &g_audio_h);
+       if (AUDIO_IO_ERROR_NONE == ret) {
+               g_is_valid_audio_in = true;
+               /*
+               ret = audio_in_ignore_session(g_audio_h);
+               if (AUDIO_IO_ERROR_NONE != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to ignore session : %d", ret);
+               }
+               */
+       } else {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
+               g_is_valid_audio_in = false;
+       }
+
+       g_audio_cb = audio_cb;
+       g_interrupt_cb = interrupt_cb;
+       g_recorder_state = VCD_RECORDER_STATE_READY;
+
+#ifdef TV_BT_MODE
+
+       bool is_bt_failed = false;
+
+       if (false == is_bt_failed && BT_ERROR_NONE != bt_initialize()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to init bt");
+               is_bt_failed = true;
+       }
+
+       if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_host_initialize(_bt_cb_hid_state_changed, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_host_initialize()");
+               is_bt_failed = true;
+       }
+
+       if (false == is_bt_failed && BT_ERROR_NONE != bt_hid_set_audio_data_receive_cb(_bt_hid_audio_data_receive_cb, NULL)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_set_audio_data_receive_cb()");
+               is_bt_failed = true;
+       }
+
+
+       if (false == is_bt_failed) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Bluetooth is available");
+               g_is_valid_bt_in = true;
+       }
+#endif
+       /* Select default audio type */
+       if (true == g_is_valid_bt_in) {
+               g_current_audio_type = strdup(VCP_AUDIO_ID_BLUETOOTH);
+       } else {
+               g_current_audio_type = strdup(VCP_AUDIO_ID_NONE);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Audio type : %s", g_current_audio_type);
+
+       return 0;
+}
+
+int vcd_recorder_destroy()
+{
+       if (VCD_RECORDER_STATE_RECORDING == g_recorder_state) {
+               if (0 != strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
+                       audio_in_unprepare(g_audio_h);
+               } else {
+#ifdef TV_BT_MODE
+                       bt_hid_unset_audio_data_receive_cb();
+#endif
+               }
+               g_recorder_state = VCD_RECORDER_STATE_READY;
+       }
+
+       audio_in_destroy(g_audio_h);
+
+#ifdef AUDIO_MULTI_SESSION
+       sound_manager_unset_interrupted_cb();
+       sound_manager_multi_session_destroy(g_session);
+#endif
+
+#ifdef TV_BT_MODE
+       bt_hid_unset_audio_data_receive_cb();
+
+       bt_hid_host_deinitialize ();
+
+       bt_deinitialize();
+#endif
+
+       g_audio_cb = NULL;
+
+       if (0 == access(VC_RUNTIME_INFO_AUDIO_VOLUME, R_OK)) {
+               if (0 != remove(VC_RUNTIME_INFO_AUDIO_VOLUME)) {
+                       SLOG(LOG_WARN, TAG_VCD, "[Recorder WARN] Fail to remove volume file");
+               }
+       }
+
+       if (NULL != g_current_audio_type) {
+               free(g_current_audio_type);
+               g_current_audio_type = NULL;
+       }
+
+       return 0;
+}
+
+int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, int channel)
+{
+       if (NULL == audio_type) {
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL != g_current_audio_type) {
+               if (0 == strncmp(g_current_audio_type, audio_type, strlen(g_current_audio_type))) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Current audio type is already set : %s", audio_type);
+                       return 0;
+               }
+       }
+
+       if (VCD_RECORDER_STATE_READY != g_recorder_state) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Recorder is NOT ready");
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       int ret = -1;
+       /* Check BT audio */
+       if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
+               if (false == g_is_valid_bt_in) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder] BT audio is NOT valid");
+                       return VCD_ERROR_OPERATION_REJECTED;
+               }
+
+               if (NULL != g_current_audio_type) {
+                       free(g_current_audio_type);
+                       g_current_audio_type = NULL;
+               }
+
+               g_current_audio_type = strdup(audio_type);
+       } else {
+               if (false == g_is_valid_audio_in) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio-in is NOT valid");
+                       return VCD_ERROR_OPERATION_REJECTED;
+               }
+
+               if (g_audio_type != type || g_audio_rate != rate || g_audio_channel != channel) {
+                       audio_in_destroy(g_audio_h);
+
+                       audio_channel_e audio_ch;
+                       audio_sample_type_e audio_type;
+
+                       switch (channel) {
+                       case 1: audio_ch = AUDIO_CHANNEL_MONO;          break;
+                       case 2: audio_ch = AUDIO_CHANNEL_STEREO;        break;
+                       default:
+                               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Input channel is not supported");
+                               return VCD_ERROR_OPERATION_FAILED;
+                               break;
+                       }
+
+                       switch (type) {
+                       case VCP_AUDIO_TYPE_PCM_S16_LE: audio_type = AUDIO_SAMPLE_TYPE_S16_LE;  break;
+                       case VCP_AUDIO_TYPE_PCM_U8:     audio_type = AUDIO_SAMPLE_TYPE_U8;      break;
+                       default:
+                               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Invalid Audio Type");
+                               return VCD_ERROR_OPERATION_FAILED;
+                               break;
+                       }
+
+                       ret = audio_in_create(rate, audio_ch, audio_type, &g_audio_h);
+                       if (AUDIO_IO_ERROR_NONE != ret) {
+                               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create audio handle : %d", ret);
+                               g_is_valid_audio_in = false;
+                               return VCD_ERROR_OPERATION_FAILED;
+                       }
+
+                       g_audio_type = type;
+                       g_audio_rate = rate;
+                       g_audio_channel = channel;
+               }
+
+#ifdef TV_BT_MODE
+               char* temp_type = NULL;
+               temp_type = strdup(audio_type);
+
+               ret = audio_in_set_device(g_audio_h, temp_type);
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder] Audio type is NOT valid :%s", temp_type);
+                       if (NULL != temp_type)
+                               free(temp_type);
+                       return VCD_ERROR_OPERATION_REJECTED;
+               }
+
+               if (NULL != temp_type)
+                       free(temp_type);
+
+               if (NULL != g_current_audio_type) {
+                       free(g_current_audio_type);
+                       g_current_audio_type = NULL;
+               }
+
+               g_current_audio_type = strdup(audio_type);
+#endif
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Current audio type is changed : %s", g_current_audio_type);
+
+       return 0;
+}
+
+int vcd_recorder_get(char** audio_type)
+{
+       if (NULL == audio_type) {
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       if (NULL != g_current_audio_type) {
+               *audio_type = strdup(g_current_audio_type);
+       } else {
+               SLOG(LOG_WARN, TAG_VCD, "[Recorder] Current audio type is NOT ready", audio_type);
+               *audio_type = NULL;
+       }
+
+       return 0;
+}
+
+static float get_volume_decibel(char* data, int size)
+{
+       #define MAX_AMPLITUDE_MEAN_16 32768
+
+       int i, depthByte;
+       int count = 0;
+       
+       float db = 0.0;
+       float rms = 0.0;
+       unsigned long long square_sum = 0;
+
+       depthByte = 2;
+
+       for (i = 0;i < size;i += (depthByte<<1)) {
+               short pcm16 = 0;
+               memcpy(&pcm16, data + i, sizeof(short));
+               square_sum += pcm16 * pcm16;
+               count++;
+       }
+
+       if (0 == count)
+               rms = 0.0;
+       else
+               rms = sqrt(square_sum/count);
+
+       db = 20 * log10(rms/MAX_AMPLITUDE_MEAN_16);
+
+       return db;
+}
+
+Eina_Bool __read_normal_func(void *data)
+{
+       int ret = -1;
+
+       if (VCD_RECORDER_STATE_RECORDING != g_recorder_state) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Exit audio reading normal func");
+               return EINA_FALSE;
+       }
+
+       memset(g_normal_buffer, '\0', BUFFER_LENGTH + 10);
+
+       ret = audio_in_read(g_audio_h, g_normal_buffer, BUFFER_LENGTH);
+       if (0 > ret) {
+               SLOG(LOG_WARN, TAG_VCD, "[Recorder WARNING] Fail to read audio : %d", ret);
+               g_recorder_state = VCD_RECORDER_STATE_READY;
+               return EINA_FALSE;
+       } 
+
+       if (NULL != g_audio_cb) {
+               if (0 != g_audio_cb(g_normal_buffer, BUFFER_LENGTH)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to read audio : %d", ret);
+                       vcd_recorder_stop();
+                       return EINA_FALSE;
+               }
+       }
+
+       if (0 == g_buffer_count || 0 == g_buffer_count % 50) {
+               SLOG(LOG_WARN, TAG_VCD, "[Recorder][%d] Recording... : read_size(%d)", g_buffer_count, ret);
+               
+               if (100000 == g_buffer_count) {
+                       g_buffer_count = 0;
+               }
+       }
+
+       g_buffer_count++;
+
+       float vol_db = get_volume_decibel(g_normal_buffer, BUFFER_LENGTH);
+
+       rewind(g_pFile_vol);
+
+       fwrite((void*)(&vol_db), sizeof(vol_db), 1, g_pFile_vol);
+
+#ifdef BUF_SAVE_MODE
+       SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] read normal buffer : size(%d)", ret);
+
+       /* write pcm buffer */
+       fwrite(g_normal_buffer, 1, BUFFER_LENGTH, g_normal_file);
+#endif
+
+       return EINA_TRUE;
+}
+
+int vcd_recorder_start()
+{
+       int ret = -1;
+       g_buffer_count = 0;
+
+       if (VCD_RECORDER_STATE_RECORDING == g_recorder_state)   return 0;
+
+#ifdef AUDIO_MULTI_SESSION
+       ret = sound_manager_multi_session_set_option(g_session, SOUND_MULTI_SESSION_OPT_MIX_WITH_OTHERS);
+       if (0 != ret) {
+               if (SOUND_MANAGER_ERROR_POLICY_BLOCKED_BY_CALL == ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] blocked to set option by call");
+               } else {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set option : %d", ret);
+               }
+               return VCD_ERROR_RECORDER_BUSY;
+       }
+#endif
+       bool started = false;
+       if (NULL != g_current_audio_type) {
+               if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
+#ifdef TV_BT_MODE
+                       const unsigned char input_data[2] = {SMART_CONTROL_START_CMD, 0x00 };
+                       if (BT_ERROR_NONE != bt_hid_send_rc_command(NULL, input_data, sizeof(input_data))) {
+                               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_send_rc_command(NULL, %s, %d)", input_data, sizeof(input_data));
+                       } else {
+                               SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start bt audio recorder");
+                       }
+
+                       started = true;
+
+                       g_bt_extend_count = 0;
+#endif
+               }
+       }
+
+       if (false == started) {
+               ret = audio_in_prepare(g_audio_h);
+               if (AUDIO_IO_ERROR_NONE != ret) {
+                       if (AUDIO_IO_ERROR_SOUND_POLICY == ret) {
+#ifdef AUDIO_MULTI_SESSION
+                               sound_manager_multi_session_set_option(g_session, SOUND_MULTI_SESSION_OPT_RESUME_OTHERS);
+#endif
+                               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Audio is busy.");
+                               return VCD_ERROR_RECORDER_BUSY;
+                       } else {
+                               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to start audio : %d", ret);
+                       }
+                       return VCD_ERROR_OPERATION_FAILED;
+               }
+
+               /* Add ecore timer to read audio data */
+               ecore_timer_add(0, __read_normal_func, NULL);
+               SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] Start audio in recorder");
+       }
+
+       g_pFile_vol = fopen(VC_RUNTIME_INFO_AUDIO_VOLUME, "wb+");
+       if (!g_pFile_vol) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to create Volume File");
+       }
+
+       g_recorder_state = VCD_RECORDER_STATE_RECORDING;
+
+#ifdef BUF_SAVE_MODE
+       char normal_file_name[128] = {'\0',};
+       g_count++;
+
+       snprintf(normal_file_name, sizeof(normal_file_name), "/tmp/vc_normal_%d_%d", getpid(), g_count);
+       SLOG(LOG_DEBUG, TAG_VCD, "[Recorder] File normal name : %s", normal_file_name);
+
+       /* open test file */
+       g_normal_file = fopen(normal_file_name, "wb+");
+       if (!g_normal_file) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] File not found!");
+       }       
+#endif
+       return 0;
+}
+
+int vcd_recorder_stop()
+{
+       int ret = -1;
+
+       if (VCD_RECORDER_STATE_READY == g_recorder_state)
+               return 0;
+
+       g_recorder_state = VCD_RECORDER_STATE_READY;
+
+       fclose(g_pFile_vol);
+
+#ifdef BUF_SAVE_MODE
+       fclose(g_normal_file);
+#endif
+
+       bool stoped = false;
+
+       if (NULL != g_current_audio_type) {
+               if (0 == strncmp(VCP_AUDIO_ID_BLUETOOTH, g_current_audio_type, strlen(VCP_AUDIO_ID_BLUETOOTH))) {
+#ifdef TV_BT_MODE
+                       if (BT_ERROR_NONE != bt_hid_rc_stop_sending_voice(NULL)) {
+                               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail bt_hid_rc_stop_sending_voice()");
+                       }
+                       stoped = true;
+#endif
+               }
+       }
+
+       if (false == stoped) {
+               ret = audio_in_unprepare(g_audio_h);
+               if (AUDIO_IO_ERROR_NONE != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to stop audio : %d", ret);
+                       return VCD_ERROR_OPERATION_FAILED;
+               }
+       }
+
+#ifdef AUDIO_MULTI_SESSION
+       ret = sound_manager_multi_session_set_option(g_session, SOUND_MULTI_SESSION_OPT_RESUME_OTHERS);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Recorder ERROR] Fail to set option : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+#endif
+       return 0;
+}
+
+int vcd_recorder_get_state()
+{
+       return g_recorder_state;
+}
\ No newline at end of file
diff --git a/server/vcd_recorder.h b/server/vcd_recorder.h
new file mode 100644 (file)
index 0000000..93b9b36
--- /dev/null
@@ -0,0 +1,61 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VCD_RECORDER_H__
+#define __VCD_RECORDER_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "voice_control_plugin_engine.h"
+
+typedef enum {
+       VCD_RECORDER_STATE_READY,       /**< Recorder is ready to start */
+       VCD_RECORDER_STATE_RECORDING,   /**< In the middle of recording */
+}vcd_recorder_state_e;
+
+
+typedef int (*vcd_recoder_audio_cb)(const void* data, const unsigned int length);
+
+typedef void (*vcd_recorder_interrupt_cb)();
+
+
+int vcd_recorder_create(vcd_recoder_audio_cb audio_cb, vcd_recorder_interrupt_cb interrupt_cb);
+
+int vcd_recorder_destroy();
+
+int vcd_recorder_set(const char* audio_type, vcp_audio_type_e type, int rate, int channel);
+
+int vcd_recorder_get(char** audio_type);
+
+int vcd_recorder_start();
+
+int vcd_recorder_read();
+
+int vcd_recorder_stop();
+
+int vcd_recorder_get_state();
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VCD_RECORDER_H__ */
+
diff --git a/server/vcd_server.c b/server/vcd_server.c
new file mode 100644 (file)
index 0000000..5f4adca
--- /dev/null
@@ -0,0 +1,1256 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+#include <dirent.h>
+#include <sound_manager.h>
+
+#include "vc_info_parser.h"
+#include "vcd_main.h"
+#include "vcd_server.h"
+#include "vcd_client_data.h"
+
+#include "vcd_engine_agent.h"
+#include "vcd_config.h"
+#include "vcd_recorder.h"
+#include "vcd_dbus.h"
+
+#include "voice_control_command_expand.h"
+
+/*
+* VC Server static variable
+*/
+static bool    g_is_engine;
+
+/*
+* VC Server Internal Functions
+*/
+static Eina_Bool __stop_by_silence(void *data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "===== Silence Detected ");
+
+       vcd_server_mgr_stop();
+
+       SLOG(LOG_DEBUG, TAG_VCD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+       return EINA_FALSE;
+}
+
+static Eina_Bool __cancel_by_interrupt(void *data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "===== Cancel by interrupt");
+
+       vcd_server_mgr_cancel();
+
+       SLOG(LOG_DEBUG, TAG_VCD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+       return EINA_FALSE;
+}
+
+static int __server_recorder_callback(const void* data, const unsigned int length)
+{
+       vcd_state_e state = vcd_config_get_service_state();
+       if (VCD_STATE_RECORDING != state) {
+               return 0;
+       }
+
+       vcp_speech_detect_e speech_detected = VCP_SPEECH_DETECT_NONE;
+       int ret;
+
+       ret = vcd_engine_recognize_audio(data, length, &speech_detected);
+
+       if (0 > ret) {
+               /* Error */
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set recording data to engine(%d)", ret);
+               ecore_timer_add(0, __cancel_by_interrupt, NULL);
+               return 0;
+       }
+
+       if (VCP_SPEECH_DETECT_BEGIN == speech_detected) {
+               if (-1 != vcd_client_manager_get_pid()) {
+                       /* Manager client is available */
+                       if (0 != vcdc_send_speech_detected(vcd_client_manager_get_pid())) {
+                               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send speech detected");
+                       }
+               }
+       } else if (VCP_SPEECH_DETECT_END == speech_detected && vcd_client_get_slience_detection()) {
+               /* silence detected */
+               ecore_timer_add(0, __stop_by_silence, NULL);
+       }
+
+       return 0;
+}
+
+void __server_recorder_interrupt_callback()
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "===== Cancel by sound interrupt");
+
+       ecore_timer_add(0, __cancel_by_interrupt, NULL);
+
+       SLOG(LOG_DEBUG, TAG_VCD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+}
+
+static void __config_lang_changed_cb(const char* current_lang, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "===== Change language ");
+
+       /* Current state is recording */
+       vcd_state_e state = vcd_config_get_service_state();
+       if (VCD_STATE_RECORDING == state || VCD_STATE_PROCESSING == state) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is 'Recording'. Cancel recognition");
+               vcd_server_mgr_cancel();
+       }
+
+       int ret;
+       ret = vcd_engine_set_current_language(current_lang);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set language of engine : %d", ret);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return;
+}
+
+static void __config_foreground_changed_cb(int previous, int current, void* user_data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "===== Change foreground");
+
+       SLOG(LOG_DEBUG, TAG_VCD, "Foreground pid(%d)", current);
+       
+       if (VC_NO_FOREGROUND_PID != current) {
+               /* Foreground app is changed */
+               vcd_state_e state = vcd_config_get_service_state();
+               if (VCD_STATE_RECORDING == state) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Foreground pid(%d) is changed. Cancel recognition", current);
+                       ecore_timer_add(0, __cancel_by_interrupt, NULL);
+               }
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "=====");
+       SLOG(LOG_DEBUG, TAG_VCD, "  ");
+
+       return;
+}
+
+static Eina_Bool __vcd_send_selected_result(void *data)
+{
+       GSList* pid_list = NULL;
+       if (0 != vc_info_parser_get_result_pid_list(&pid_list)) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to get pid list. No result");
+       }
+       else {
+               if (0 < g_slist_length(pid_list)){
+                       GSList* iter = NULL;
+                       vc_cmd_s* temp_cmd = NULL;
+                       int ret = 0;
+                       int count = 0;
+
+                       iter = g_slist_nth(pid_list, 0);
+                       while (NULL != iter) {
+                               temp_cmd = iter->data;
+
+                               if (NULL != temp_cmd) {
+                                       count = 0;
+                                       do {
+                                               /* send result noti */
+                                               ret = vcdc_send_result(temp_cmd->pid, temp_cmd->type);
+                                               if (0 != ret) {
+                                                       SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
+                                                       if (VCD_ERROR_TIMED_OUT != ret) {
+                                                               break;
+                                                       }
+                                               } else {
+                                                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Send result : pid(%d) type(%d)", temp_cmd->pid, temp_cmd->type);
+                                               }
+                                               count++;
+
+                                               if (100 == count)       break;
+                                               /* While is retry code */
+                                       } while (0 != ret);
+                                       free(temp_cmd);
+                               }
+
+                               pid_list = g_slist_remove_link(pid_list, iter);
+                               iter = g_slist_nth(pid_list, 0);
+                       }
+               }
+       }
+
+       vcd_config_set_service_state(VCD_STATE_READY);
+
+       return EINA_FALSE;
+}
+
+static void __vcd_server_result_cb(vcp_result_event_e event, int* result_id, int count, 
+                                  const char* all_result, const char* non_fixed_result, const char* msg, void *user_data)
+{
+       if (VCD_STATE_PROCESSING != vcd_config_get_service_state()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not 'Processing'");
+               return;
+       }
+
+       vc_info_parser_unset_result(vcd_client_manager_get_exclusive());
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Event(%d), Text(%s) Nonfixed(%s) Msg(%s) Result count(%d)", event, all_result, non_fixed_result, msg, count);
+
+       /* No result */
+       if (NULL == result_id) {
+               /* No result */
+               if (NULL != all_result) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Engine result is no command : %s", all_result);
+                       bool temp = vcd_client_manager_get_exclusive();
+                       vc_info_parser_set_result(all_result, event, msg, NULL, temp);
+               }
+
+               int pid = vcd_client_widget_get_foreground_pid();
+               if (-1 != pid) {
+                       if (NULL != all_result) {
+                               /* Send result text to widget */
+                               vcdc_send_result(pid, VC_COMMAND_TYPE_WIDGET);
+                       }
+
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
+                       /* Send to hide tooltip */
+                       vcdc_send_show_tooltip(pid, false);
+               }
+
+               if (-1 != vcd_client_manager_get_pid()) {
+                       /* Manager client is available */
+                       if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid())) {
+                               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
+                       }
+               }
+
+               vcd_client_manager_set_exclusive(false);
+
+               return;
+       }
+
+       /* Normal result */
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server] === Get engine result ===");
+
+       int ret = -1;
+       vc_cmd_s* temp_cmd = NULL;
+       vc_cmd_list_h vc_cmd_list = NULL;
+
+       if (0 != vc_cmd_list_create(&vc_cmd_list)) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to create command list");
+               vcd_client_manager_set_exclusive(false);
+               vcd_config_set_service_state(VCD_STATE_READY);
+               return;
+       }
+
+       int i = 0;
+       for (i = 0;i < count;i++) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server]   [%d] Result ID(%d)", i, result_id[i]);
+
+               if (result_id[i] < 0) {
+                       SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Result ID(%d) is NOT valid", result_id[i]);
+                       continue;
+               }
+
+               ret = vcd_client_get_cmd_from_result_id(result_id[i], &temp_cmd);
+               if (0 == ret && NULL != temp_cmd) {
+                       switch (temp_cmd->format) {
+                       case VC_CMD_FORMAT_FIXED:
+                               /* Nonfixed result is NOT valid */
+                               break;
+                       case VC_CMD_FORMAT_FIXED_AND_EXTRA:
+                               if (NULL == temp_cmd->parameter) {
+                                       if (NULL != non_fixed_result) {
+                                               temp_cmd->parameter = strdup(non_fixed_result);
+                                       }
+                               } else {
+                                       SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT vaild. Parameter (%s)", temp_cmd->parameter);
+                               }
+                               break;
+                       case VC_CMD_FORMAT_EXTRA_AND_FIXED:
+                               if (NULL == temp_cmd->command) {
+                                       if (NULL != non_fixed_result) {
+                                               temp_cmd->command = strdup(non_fixed_result);
+                                       }
+                               } else {
+                                       SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Command type is NOT vaild. Command (%s)", temp_cmd->command);
+                               }
+
+                               break;
+                       default:
+                               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Unknown command type : %d", temp_cmd->type);
+                       }
+
+                       temp_cmd->id = i;
+                       if (0 != vc_cmd_list_add(vc_cmd_list, (vc_cmd_h)temp_cmd)) {
+                               SLOG(LOG_DEBUG, TAG_VCD, "Fail to add command to list");
+                               vc_cmd_destroy((vc_cmd_h)temp_cmd);
+                       }
+               } else {
+                       SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] NOT found matached result(%d)", result_id[i]);
+               }
+       }
+
+       vc_cmd_print_list(vc_cmd_list);
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server] =========================");
+
+       int result_count = 0;
+       vc_cmd_list_get_count(vc_cmd_list, &result_count);
+
+       if (false == vcd_client_manager_get_exclusive()) {
+               int pid = vcd_client_widget_get_foreground_pid();
+               if (-1 != pid) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
+                       vcdc_send_show_tooltip(pid, false);
+               }
+
+               vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, false);
+
+               if (-1 != vcd_client_manager_get_pid()) {
+                       /* Manager client is available */
+                       if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid())) {
+                               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
+                       }
+               } else {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Manager is NOT available. Send result to client directly");
+                       /* Send result to client */
+                       ecore_timer_add(0, __vcd_send_selected_result, NULL);
+               }
+       } else {
+               /* exclusive command */
+               vc_info_parser_set_result(all_result, event, msg, vc_cmd_list, true);
+
+               if (-1 != vcd_client_manager_get_pid()) {
+                       /* Manager client is available */
+                       if (0 != vcdc_send_result_to_manager(vcd_client_manager_get_pid())) {
+                               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to send result");
+                       }
+               } else {
+                       SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Manager is NOT available");
+               }
+
+               vcd_client_manager_set_exclusive(false);
+       }
+
+       vc_cmd_list_destroy(vc_cmd_list, true);
+
+       return;
+}
+
+/*
+* vcd server Interfaces
+*/
+static void __vcd_file_clean_up()
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "== Old file clean up == ");
+
+       DIR *dp = NULL;
+       int ret = -1;
+       struct dirent entry;
+       struct dirent *dirp = NULL;
+
+       dp = opendir(VC_RUNTIME_INFO_ROOT);
+       if (dp == NULL) {
+               SLOG(LOG_ERROR, TAG_VCD, "[File message WARN] Fail to open path : %s", VC_RUNTIME_INFO_ROOT);
+               return;
+       }
+
+       char remove_path[256] = {0, };
+       do {
+               ret = readdir_r(dp, &entry, &dirp);
+               if (0 != ret) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[File ERROR] Fail to read directory");
+                       break;
+               }
+
+               if (NULL != dirp) {
+                       if (!strncmp("vc_", dirp->d_name, strlen("vc_"))) {
+                               memset(remove_path, 0, 256);
+                               snprintf(remove_path, 256, "%s/%s", VC_RUNTIME_INFO_ROOT, dirp->d_name);
+
+                               /* Clean up code */
+                               if (0 != remove(remove_path)) {
+                                       SLOG(LOG_WARN, TAG_VCD, "[File message WARN] Fail to remove file : %s", remove_path);
+                               } else {
+                                       SLOG(LOG_DEBUG, TAG_VCD, "[File message] Remove file : %s", remove_path);
+                               }
+                       }
+               }
+       } while (NULL != dirp);
+
+       closedir(dp);
+
+       return;
+}
+
+int vcd_initialize()
+{
+       int ret = 0;
+
+       /* Remove old file */
+       __vcd_file_clean_up();
+
+       /* initialize modules */
+       ret = vcd_config_initialize(__config_lang_changed_cb, __config_foreground_changed_cb, NULL);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server WARNING] Fail to initialize config.");
+       }
+
+       vcd_config_set_service_state(VCD_STATE_NONE);
+
+       ret = vcd_engine_agent_init(__vcd_server_result_cb);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to engine agent initialize : result(%d)", ret);
+               return ret;
+       }
+
+       if (0 != vcd_recorder_create(__server_recorder_callback, __server_recorder_interrupt_callback)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to create recorder");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* Find engine */
+       ret = vcd_engine_agent_initialize_current_engine();
+       if (0 != ret) {
+               if (VCD_ERROR_ENGINE_NOT_FOUND == ret)
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] There is No Voice control engine");
+               else
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to init engine");
+
+               g_is_engine = false;
+       } else {
+               g_is_engine = true;
+       }
+
+       /* Load engine */
+       if (0 != vcd_engine_agent_load_current_engine()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to load current engine");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* Initialize manager info */
+       vcd_client_manager_unset();
+
+       vcd_config_set_service_state(VCD_STATE_READY);
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server SUCCESS] initialize");
+
+       return 0;
+}
+
+void vcd_finalize()
+{
+       vcd_state_e state = vcd_config_get_service_state();
+       if (VCD_STATE_READY != state) {
+               if (VCD_STATE_RECORDING == state) {
+                       vcd_recorder_stop();
+               }
+               vcd_engine_recognize_cancel();
+       }
+       if (0 != vcd_recorder_destroy()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to destroy recorder");
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] destroy recorder");
+       }
+
+       if (0 != vcd_engine_agent_release()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to release engine");
+       } else {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] release engine");
+       }
+
+       vcd_config_set_service_state(VCD_STATE_NONE);
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server] mode finalize");
+
+       return;
+}
+
+static Eina_Bool __finalize_quit_ecore_loop(void *data)
+{
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server] quit ecore main loop");
+       ecore_main_loop_quit();
+       return EINA_FALSE;
+}
+
+Eina_Bool vcd_cleanup_client(void *data)
+{
+       int* client_list = NULL;
+       int client_count = 0;
+       int result;
+       int i = 0;
+
+       if (0 == vcd_client_get_list(&client_list, &client_count)) {
+               SLOG(LOG_DEBUG, TAG_VCD, "===== Clean up client ");
+               if (NULL != client_list && client_count > 0) {
+                       for (i = 0;i < client_count;i++) {
+                               result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_NORMAL);
+
+                               if (0 == result) {
+                                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] pid(%d) should be removed.", client_list[i]);
+                                       vcd_server_finalize(client_list[i]);
+                               } else if (-1 == result) {
+                                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
+                               }
+                       }
+               }
+               SLOG(LOG_DEBUG, TAG_VCD, "=====");
+               SLOG(LOG_DEBUG, TAG_VCD, "  ");
+       }
+       if (NULL != client_list) {
+               free(client_list);
+               client_list = NULL;
+       }
+
+       if (0 == vcd_client_widget_get_list(&client_list, &client_count)) {
+               SLOG(LOG_DEBUG, TAG_VCD, "===== Clean up widget");
+               if (NULL != client_list && client_count > 0) {
+                       for (i = 0;i < client_count;i++) {
+                               result = vcdc_send_hello(client_list[i], VCD_CLIENT_TYPE_WIDGET);
+
+                               if (0 == result) {
+                                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget pid(%d) should be removed.", client_list[i]);
+                                       vcd_server_widget_finalize(client_list[i]);
+                               } else if (-1 == result) {
+                                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Hello result has error");
+                               }
+                       }
+               }
+               SLOG(LOG_DEBUG, TAG_VCD, "=====");
+               SLOG(LOG_DEBUG, TAG_VCD, "  ");
+       }
+       if (NULL != client_list) {
+               free(client_list);
+               client_list = NULL;
+       }
+
+       /* manager */
+
+       return EINA_TRUE;
+}
+
+/*
+* API for manager
+*/
+int vcd_server_mgr_initialize(int pid)
+{
+       if (false == g_is_engine) {
+               if (0 != vcd_engine_agent_initialize_current_engine()) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
+                       g_is_engine = false;
+                       return VCD_ERROR_ENGINE_NOT_FOUND;
+               } else {
+                       g_is_engine = true;
+               }
+       }
+
+       /* check if pid is valid */
+       if (false == vcd_client_manager_is_valid(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid(%d) is already exist", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* Add client information to client manager */
+       if (0 != vcd_client_manager_set(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add manager");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Manager initialize : pid(%d)", pid);
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_finalize(int pid)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_manager_is_valid(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* Remove manager information */
+       if (0 != vcd_client_manager_unset()) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
+       }
+
+       if (0 == vcd_client_get_ref_count()) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Connected client list is empty");
+               ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Manager Finalize : pid(%d)", pid);
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_set_command(int pid)
+{
+       if (0 != vcd_client_manager_set_command(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_unset_command(int pid)
+{
+       if (0 != vcd_client_manager_unset_command(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_set_demandable_client(int pid)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_manager_is_valid(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       GSList* client_list = NULL;
+       if (0 != vc_info_parser_get_demandable_clients(&client_list)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get demandable client");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* Save client list */
+       if (0 != vcd_client_manager_set_demandable_client(pid, client_list)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set demandable client list");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_set_audio_type(int pid, const char* audio_type)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_manager_is_valid(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+       
+       int ret = 0;
+       vcp_audio_type_e type = VCP_AUDIO_TYPE_PCM_S16_LE;
+       int rate = 16000;
+       int channel = 1;
+
+       ret = vcd_engine_get_audio_format(audio_type, &type, &rate, &channel);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio format : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       ret = vcd_recorder_set(audio_type, type, rate, channel);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set audio in type : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_get_audio_type(int pid, char** audio_type)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_manager_is_valid(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+       
+       int ret = vcd_recorder_get(audio_type);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get audio in type : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_set_client_info(int pid)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_manager_is_valid(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The manager pid(%d) is NOT valid", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret = vcd_client_save_client_info();
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to save client info : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return VCD_ERROR_NONE;
+}
+
+static int __start_internal_recognition()
+{
+       int ret;
+
+       /* 2. Get commands */
+       ret = vcd_client_command_collect_command();
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to collect command : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       ret = vcd_client_get_length();
+       if (0 == ret) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNIING] No current command : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       /* 3. Set command to engine */
+       ret = vcd_engine_set_commands();
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to collect command : %d", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Set command");
+
+       /* 4. start recognition */
+       ret = vcd_engine_recognize_start(true);
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recognition : result(%d)", ret);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start engine");
+
+       /* 5. recorder start */
+       ret = vcd_recorder_start();
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recorder : result(%d)", ret);
+               vcd_engine_recognize_cancel();
+               return ret;
+       }
+
+       vcd_config_set_service_state(VCD_STATE_RECORDING);
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Start recognition");
+
+       return 0;
+}
+
+static Eina_Bool __vcd_request_show_tooltip(void *data)
+{
+       int pid = vcd_client_widget_get_foreground_pid();
+       if (-1 != pid) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip show and widget command");
+               vcdc_send_show_tooltip(pid, (bool)data);
+       }
+
+       return EINA_FALSE;
+}
+
+int vcd_server_mgr_start(bool stop_by_silence, bool exclusive_cmd, bool start_by_client)
+{
+       /* 1. check current state */
+       vcd_state_e state = vcd_config_get_service_state();
+       
+       if (VCD_STATE_READY != state) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not ready");
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       vcd_client_set_slience_detection(stop_by_silence);
+
+       if (false == exclusive_cmd) {
+               /* Notify show tooltip */
+               int pid = vcd_client_widget_get_foreground_pid();
+               if (-1 != pid) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip show and widget command");
+                       ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
+                       return 0;
+               }
+       } else {
+               vcd_client_manager_set_exclusive(exclusive_cmd);
+       }
+
+       int fg_pid = -1;
+       if (true == start_by_client) {
+               /* Get foreground pid */
+               if (0 != vcd_config_get_foreground(&fg_pid)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to get foreground");
+               }
+               
+               /* Set client exclusive option */
+               if (0 != vcd_client_set_exclusive_command(fg_pid)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command");
+               }
+       }
+
+       int ret = __start_internal_recognition();
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recongition : %d", ret);
+               return ret;
+       }
+
+       if (true == start_by_client) {
+               vcd_client_unset_exclusive_command(fg_pid);
+       }
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_stop()
+{
+       /* 1. Check current state is recording */
+       if (VCD_STATE_RECORDING != vcd_config_get_service_state()) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Current state is not recording");
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       /* 2. Stop recorder */
+       vcd_recorder_stop();
+
+       /* 3. Stop engine recognition */
+       int ret = vcd_engine_recognize_stop();
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to stop recognition : %d", ret);
+       }
+
+       /* 4. Set original mode */
+       vcd_config_set_service_state(VCD_STATE_PROCESSING);
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_mgr_cancel()
+{
+       /* 1. Check current state */
+       vcd_state_e state = vcd_config_get_service_state();
+       if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server ERROR] Current state is not recording or processing");
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       /* 2. Stop recorder */
+       vcd_recorder_stop();
+       /* 3. Cancel engine */
+       int ret = vcd_engine_recognize_cancel();
+       if (0 != ret) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to cancel : %d", ret);
+       }
+
+       if (false == vcd_client_manager_get_exclusive()) {
+               int pid = vcd_client_widget_get_foreground_pid();
+               if (-1 != pid) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Request tooltip hide");
+                       ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
+               }
+       } else {
+               vcd_client_manager_set_exclusive(false);
+       }
+
+       /* 4. Set state */
+       vcd_config_set_service_state(VCD_STATE_READY);
+
+       return VCD_ERROR_NONE;
+}
+
+
+int vcd_server_mgr_result_select()
+{
+       ecore_timer_add(0.01, __vcd_send_selected_result, NULL);
+
+       return VCD_ERROR_NONE;
+}
+
+/*
+* VC Server Functions for Client
+*/
+int vcd_server_initialize(int pid)
+{
+       if (false == g_is_engine) {
+               if (0 != vcd_engine_agent_initialize_current_engine()) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
+                       g_is_engine = false;
+                       return VCD_ERROR_ENGINE_NOT_FOUND;
+               } else {
+                       g_is_engine = true;
+               }
+       }
+
+       if (false == vcd_engine_is_available_engine()) {
+               if (0 != vcd_engine_agent_initialize_current_engine()) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
+                       return VCD_ERROR_ENGINE_NOT_FOUND;
+               }
+       }
+
+       /* check if pid is valid */
+       if (true == vcd_client_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid is already exist");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* Add client information to client manager */
+       if (0 != vcd_client_add(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Initialize : pid(%d)", pid);
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_finalize(int pid)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* Remove client information */
+       if (0 != vcd_client_delete(pid)) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
+       }
+
+       if (0 == vcd_client_get_ref_count()) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Connected client list is empty");
+               ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Client Finalize : pid(%d)", pid);
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_set_command(int pid, vc_cmd_type_e cmd_type)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       if (0 != vcd_client_set_command_type(pid, cmd_type)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set command type : pid(%d), cmd_type(%d)", pid, cmd_type);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return 0;
+}
+
+int vcd_server_unset_command(int pid, vc_cmd_type_e cmd_type)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       if (0 != vcd_client_unset_command_type(pid, cmd_type)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset command type : pid(%d), cmd_type(%d)", pid, cmd_type);
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+       
+       return 0;
+}
+
+#if 0
+int vcd_server_set_exclusive_command(int pid, bool value)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       if (true == value) {
+               if (0 != vcd_client_set_exclusive_command(pid)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to set exclusive command : pid(%d)", pid);
+                       return VCD_ERROR_OPERATION_FAILED;
+               }
+       } else {
+               if (0 != vcd_client_unset_exclusive_command(pid)) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to unset exclusive command : pid(%d)", pid);
+                       return VCD_ERROR_OPERATION_FAILED;
+               }
+       }
+       
+       return 0;
+}
+
+int vcd_server_request_start(int pid, bool stop_by_silence)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid(%d) is NOT forground client", pid);
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret;
+       /* Check current state */
+       vcd_state_e state = vcd_config_get_service_state();
+
+       /* Service state should be ready */
+       if (VCD_STATE_READY != state) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       if (-1 != vcd_client_manager_get_pid()) {
+               /* Check current pid is valid */
+               if (false == vcd_client_manager_check_demandable_client(pid)) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
+                       return VCD_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       ret = vcd_server_mgr_start(stop_by_silence, false);
+       if (0 != ret) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       return 0;
+}
+
+int vcd_server_request_stop(int pid)
+{
+       int ret;
+       /* Check current state */
+       vcd_state_e state = vcd_config_get_service_state();
+
+       /* Service state should be ready */
+       if (VCD_STATE_RECORDING != state) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording : pid(%d)", pid);
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       if (-1 != vcd_client_manager_get_pid()) {
+               /* Check current pid is valid */
+               if (false == vcd_client_manager_check_demandable_client(pid)) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
+                       return VCD_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       ret = vcd_server_mgr_stop();
+       if (0 != ret) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_request_cancel(int pid)
+{
+       int ret;
+       /* Check current state */
+       vcd_state_e state = vcd_config_get_service_state();
+
+       /* Service state should be recording or processing */
+       if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       if (-1 != vcd_client_manager_get_pid()) {
+               /* Check current pid is valid */
+               if (false == vcd_client_manager_check_demandable_client(pid)) {
+                       SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current client is NOT available : pid(%d)", pid);
+                       return VCD_ERROR_INVALID_PARAMETER;
+               }
+       }
+
+       ret = vcd_server_mgr_cancel();
+       if (0 != ret) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return VCD_ERROR_NONE;
+}
+#endif
+
+/*
+* VC Server Functions for Widget lib
+*/
+int vcd_server_widget_initialize(int pid)
+{
+       if (false == g_is_engine) {
+               if (0 != vcd_engine_agent_initialize_current_engine()) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
+                       g_is_engine = false;
+                       return VCD_ERROR_ENGINE_NOT_FOUND;
+               } else {
+                       g_is_engine = true;
+               }
+       }
+
+       if (false == vcd_engine_is_available_engine()) {
+               if (0 != vcd_engine_agent_initialize_current_engine()) {
+                       SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] No Engine");
+                       return VCD_ERROR_ENGINE_NOT_FOUND;
+               }
+       }
+
+       /* check if pid is valid */
+       if (true == vcd_client_widget_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] The pid is already exist");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* Add client information to client manager */
+       if (0 != vcd_client_widget_add(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to add client info");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       SLOG(LOG_DEBUG, TAG_VCD, "[Server Success] Initialize widget : pid(%d)", pid);
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_widget_finalize(int pid)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_widget_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* Remove client information */
+       if (0 != vcd_client_widget_delete(pid)) {
+               SLOG(LOG_WARN, TAG_VCD, "[Server WARNING] Fail to delete client");
+       }
+
+       if (0 == vcd_client_get_ref_count()) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] connected client list is empty");
+               ecore_timer_add(0, __finalize_quit_ecore_loop, NULL);
+       }
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_widget_start_recording(int pid, bool widget_command)
+{
+       /* check if pid is valid */
+       if (false == vcd_client_widget_is_available(pid)) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] pid is NOT valid ");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       if (true == widget_command) {
+               vcd_client_widget_set_command(pid);
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is available");
+       } else {
+               vcd_client_widget_unset_command(pid);
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] widget command is NOT available");
+       }
+
+       int ret = __start_internal_recognition();
+       if (0 != ret) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server ERROR] Fail to start recongition : %d", ret);
+               ecore_timer_add(0, __vcd_request_show_tooltip, (void*)false);
+       }
+
+       return 0;
+}
+
+int vcd_server_widget_start(int pid, bool stop_by_silence)
+{
+       /* check if pid is valid */
+       int fore_pid = vcd_client_widget_get_foreground_pid();
+       if (pid != fore_pid) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       /* Check current state */
+       vcd_state_e state = vcd_config_get_service_state();
+
+       /* Service state should be ready */
+       if (VCD_STATE_READY != state) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Ready : pid(%d)", pid);
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       vcd_client_set_slience_detection(stop_by_silence);
+
+       /* Notify show tooltip */
+       ecore_timer_add(0, __vcd_request_show_tooltip, (void*)true);
+
+       return 0;
+}
+
+int vcd_server_widget_stop(int pid)
+{
+       /* check if pid is valid */
+       int fore_pid = vcd_client_widget_get_foreground_pid();
+       if (pid != fore_pid) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret;
+       /* Check current state */
+       vcd_state_e state = vcd_config_get_service_state();
+
+       /* Service state should be recording */
+       if (VCD_STATE_RECORDING != state) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current service state is not Recording : pid(%d)", pid);
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       ret = vcd_server_mgr_stop();
+       if (0 != ret) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return VCD_ERROR_NONE;
+}
+
+int vcd_server_widget_cancel(int pid)
+{
+       /* check if pid is valid */
+       int fore_pid = vcd_client_widget_get_foreground_pid();
+       if (pid != fore_pid) {
+               SLOG(LOG_ERROR, TAG_VCD, "[Server] pid is NOT foreground");
+               return VCD_ERROR_INVALID_PARAMETER;
+       }
+
+       int ret;
+       /* Check current state */
+       vcd_state_e state = vcd_config_get_service_state();
+
+       /* Service state should be recording or processing */
+       if (VCD_STATE_RECORDING != state && VCD_STATE_PROCESSING != state) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Current state is not Recording or Processing : pid(%d)", pid);
+               return VCD_ERROR_INVALID_STATE;
+       }
+
+       ret = vcd_server_mgr_cancel();
+       if (0 != ret) {
+               SLOG(LOG_DEBUG, TAG_VCD, "[Server] Fail to start recognition");
+               return VCD_ERROR_OPERATION_FAILED;
+       }
+
+       return VCD_ERROR_NONE;
+}
+
diff --git a/server/vcd_server.h b/server/vcd_server.h
new file mode 100644 (file)
index 0000000..27c2dbb
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+* Copyright (c) 2011-2015 Samsung Electronics Co., Ltd All Rights Reserved
+*
+* Licensed under the Apache License, Version 2.0 (the License);
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an AS IS BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+
+
+#ifndef __VCD_SERVER_H_
+#define __VCD_SERVER_H_
+
+#include "vcd_main.h"
+#include "vcd_client_data.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+* Daemon functions
+*/
+int vcd_initialize();
+
+void vcd_finalize();
+
+Eina_Bool vcd_cleanup_client(void *data);
+
+
+/*
+* For manager
+*/
+int vcd_server_mgr_initialize(int pid);
+
+int vcd_server_mgr_finalize(int pid);
+
+int vcd_server_mgr_set_command(int pid);
+
+int vcd_server_mgr_unset_command(int pid);
+
+int vcd_server_mgr_set_demandable_client(int pid);
+
+int vcd_server_mgr_set_audio_type(int pid, const char* audio_type);
+
+int vcd_server_mgr_get_audio_type(int pid, char** audio_type);
+
+int vcd_server_mgr_set_client_info(int pid);
+
+int vcd_server_mgr_start(bool stop_by_silence, bool exclusive_cmd, bool start_by_client);
+
+int vcd_server_mgr_stop();
+
+int vcd_server_mgr_cancel();
+
+int vcd_server_mgr_result_select();
+
+/*
+* For client
+*/
+int vcd_server_initialize(int pid);
+
+int vcd_server_finalize(int pid);
+
+int vcd_server_set_command(int pid, vc_cmd_type_e cmd_type);
+
+int vcd_server_unset_command(int pid, vc_cmd_type_e cmd_type);
+
+int vcd_server_set_exclusive_command(int pid, bool value);
+
+#if 0
+int vcd_server_request_start(int pid, bool stop_by_silence);
+
+int vcd_server_request_stop(int pid);
+
+int vcd_server_request_cancel(int pid);
+#endif
+
+/*
+* For widget
+*/
+int vcd_server_widget_initialize(int pid);
+
+int vcd_server_widget_finalize(int pid);
+
+int vcd_server_widget_start_recording(int pid, bool widget_command);
+
+int vcd_server_widget_start(int pid, bool stop_by_silence);
+
+int vcd_server_widget_stop(int pid);
+
+int vcd_server_widget_cancel(int pid);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __VCD_SERVER_H_ */
diff --git a/vc-config.xml b/vc-config.xml
new file mode 100644 (file)
index 0000000..5e222e8
--- /dev/null
@@ -0,0 +1,7 @@
+<?xml version="1.0"?>
+<voice-control-config>
+        <engine>C7AEDE1D-90F7-41ea-9AB4-FD99966D2654</engine>
+        <auto>on</auto>
+        <language>en_US</language>
+        <enabled>off</enabled>
+</voice-control-config>