Default VPN CAPI Initial Code (without Connman Library) 36/57636/1
authortaesub.kim <taesub.kim@samsung.com>
Thu, 21 Jan 2016 07:54:44 +0000 (16:54 +0900)
committertaesub.kim <taesub.kim@samsung.com>
Thu, 21 Jan 2016 07:54:50 +0000 (16:54 +0900)
Change-Id: I59aa5bcfcb35184cd099b04cfa9fed0ee5e7469d
Signed-off-by: Taesub Kim <taesub.kim@samsung.com>
25 files changed:
AUTHORS [new file with mode: 0644]
CMakeLists.txt [new file with mode: 0644]
ChangeLog [new file with mode: 0644]
LICENSE.APLv2 [new file with mode: 0644]
NOTICE [new file with mode: 0644]
capi-network-vpn.pc.in [new file with mode: 0644]
dvpnlib/include/debug.h [new file with mode: 0644]
dvpnlib/include/dvpnlib-common.h [new file with mode: 0644]
dvpnlib/include/dvpnlib-internal.h [new file with mode: 0644]
dvpnlib/include/dvpnlib-vpn-connection.h [new file with mode: 0644]
dvpnlib/include/dvpnlib-vpn-manager.h [new file with mode: 0644]
dvpnlib/include/dvpnlib-vpn.h [new file with mode: 0644]
dvpnlib/src/dvpnlib-vpn-connnection.c [new file with mode: 0644]
dvpnlib/src/dvpnlib-vpn-manager.c [new file with mode: 0644]
dvpnlib/src/dvpnlib-vpn.c [new file with mode: 0644]
dvpnlib/src/dvpnlib.c [new file with mode: 0644]
include/vpn.h [new file with mode: 0644]
packaging/capi-network-vpn.manifest [new file with mode: 0644]
packaging/capi-network-vpn.spec [new file with mode: 0644]
src/include/common.h [new file with mode: 0644]
src/include/vpn-internal.h [new file with mode: 0644]
src/vpn-internal.c [new file with mode: 0644]
src/vpn.c [new file with mode: 0644]
test/CMakeLists.txt [new file with mode: 0644]
test/vpn_test.c [new file with mode: 0644]

diff --git a/AUTHORS b/AUTHORS
new file mode 100644 (file)
index 0000000..8e0097f
--- /dev/null
+++ b/AUTHORS
@@ -0,0 +1,2 @@
+Sushil Kumar Yadav <sushil.ky@samsung.com>
+Sushil <sushil.iitk@gmail.com>
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..a98ed96
--- /dev/null
@@ -0,0 +1,98 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_name "capi-network-vpn")
+
+PROJECT(${fw_name})
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(INC_DIR include dvpnlib/include/)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/${INC_DIR}/)
+INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/src/include/)
+
+
+SET(dependents "dlog vconf capi-base-common glib-2.0 gio-2.0")
+SET(pc_dependents "capi-base-common")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_name} REQUIRED ${dependents})
+FOREACH(flag ${${fw_name}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -fPIC -Wall -Werror -fvisibility=hidden")
+SET(CMAKE_C_FLAGS_DEBUG "-O0 -g")
+
+IF("${ARCH}" STREQUAL "arm")
+    ADD_DEFINITIONS("-DTARGET")
+ENDIF("${ARCH}" STREQUAL "arm")
+
+ADD_DEFINITIONS("-DPREFIX=\"${CMAKE_INSTALL_PREFIX}\"")
+ADD_DEFINITIONS("-DTIZEN_DEBUG")
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIB_INSTALL_DIR}")
+
+aux_source_directory(src SOURCES)
+aux_source_directory(dvpnlib/src DVPNLIB_SOURCES)
+ADD_LIBRARY(${fw_name} SHARED ${SOURCES} ${DVPNLIB_SOURCES})
+
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${fw_name}
+     PROPERTIES
+     VERSION ${FULLVER}
+     SOVERSION ${MAJORVER}
+     CLEAN_DIRECT_OUTPUT 1
+)
+
+INSTALL(TARGETS ${fw_name} DESTINATION ${LIB_INSTALL_DIR})
+INSTALL(
+        DIRECTORY ${INC_DIR}/ DESTINATION include/network
+        FILES_MATCHING
+        PATTERN "*_private.h" EXCLUDE
+        PATTERN "${INC_DIR}/*.h"
+        )
+
+SET(PC_NAME ${fw_name})
+SET(PC_REQUIRED ${pc_dependents})
+SET(PC_LDFLAGS -l${fw_name})
+
+CONFIGURE_FILE(
+    ${fw_name}.pc.in
+    ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc
+    @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
+
+ADD_SUBDIRECTORY(test)
+
+IF(UNIX)
+
+ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
+ADD_CUSTOM_COMMAND(
+        DEPENDS clean
+        COMMENT "distribution clean"
+        COMMAND find
+        ARGS    .
+        -not -name config.cmake -and \(
+        -name tester.c -or
+        -name Testing -or
+        -name CMakeFiles -or
+        -name cmake.depends -or
+        -name cmake.check_depends -or
+        -name CMakeCache.txt -or
+        -name cmake.check_cache -or
+        -name *.cmake -or
+        -name Makefile -or
+        -name core -or
+        -name core.* -or
+        -name gmon.out -or
+        -name install_manifest.txt -or
+        -name *.pc -or
+        -name *~ \)
+        | grep -v TC | xargs rm -rf
+        TARGET  distclean
+        VERBATIM
+)
+
+ENDIF(UNIX)
diff --git a/ChangeLog b/ChangeLog
new file mode 100644 (file)
index 0000000..30df408
--- /dev/null
+++ b/ChangeLog
@@ -0,0 +1,3 @@
+Ver 0.1:
+       Added Default VPN CAPI Code
+
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..d645695
--- /dev/null
@@ -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..0e0f016
--- /dev/null
+++ b/NOTICE
@@ -0,0 +1,3 @@
+Copyright (c) Samsung Electronics Co., Ltd. All rights reserved.
+Except as noted, this software is licensed under Apache License, Version 2.
+Please, see the LICENSE.APLv2 file for Apache License terms and conditions.
diff --git a/capi-network-vpn.pc.in b/capi-network-vpn.pc.in
new file mode 100644 (file)
index 0000000..ee6db75
--- /dev/null
@@ -0,0 +1,13 @@
+# Package Information for pkg-config
+
+prefix=@PREFIX@
+exec_prefix=/usr
+libdir=/usr/lib
+includedir=/usr/include/network
+
+Name: @PC_NAME@
+Description: @PACKAGE_DESCRIPTION@
+Version: @VERSION@
+Requires: @PC_REQUIRED@
+Libs: -L${libdir} @PC_LDFLAGS@
+Cflags: -I${includedir}
diff --git a/dvpnlib/include/debug.h b/dvpnlib/include/debug.h
new file mode 100644 (file)
index 0000000..c4c1a24
--- /dev/null
@@ -0,0 +1,27 @@
+#ifndef __DEBUG_H__
+#define __DEBUG_H__
+
+#include <stdio.h>
+
+#ifndef RELEASE
+
+#include <dlog.h>
+
+#undef LOG_TAG
+#define LOG_TAG "DVPN_LIB"
+
+#define DBG(fmt, arg...) SLOGD(fmt, ##arg)
+
+#define WARN(fmt, arg...) SLOGI(fmt, ##arg)
+
+#define ERROR(fmt, arg...) SLOGE(fmt, ##arg)
+
+#else
+
+#define DBG(fmt, arg...)
+#define WARN(fmt, arg...)
+#define ERROR(fmt, arg...)
+
+#endif
+
+#endif
diff --git a/dvpnlib/include/dvpnlib-common.h b/dvpnlib/include/dvpnlib-common.h
new file mode 100644 (file)
index 0000000..f2af6da
--- /dev/null
@@ -0,0 +1,54 @@
+#ifndef __COMMON_LIB_H__
+#define __COMMON_LIB_H__
+
+#include <stdbool.h>
+#include <glib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+enum dvpnlib_err {
+       /* Successful */
+       DVPNLIB_ERR_NONE = 0,
+       /* General error */
+       DVPNLIB_ERR_FAILED,
+       /* Specific error */
+       DVPNLIB_ERR_OPERATION_FAILED,
+       DVPNLIB_ERR_INVALID_PARAMETER,
+       DVPNLIB_ERR_PERMISSION_DENIED,
+       DVPNLIB_ERR_PASSPHRASE_REQUIRED,
+       DVPNLIB_ERR_NOT_REGISTERED,
+       DVPNLIB_ERR_NOT_UNIQUE,
+       DVPNLIB_ERR_NOT_SUPPORTED,
+       DVPNLIB_ERR_NOT_IMPLEMENTED,
+       DVPNLIB_ERR_NOT_FOUND,
+       DVPNLIB_ERR_NOT_CARRIER,
+       DVPNLIB_ERR_IN_PROGRESS,
+       DVPNLIB_ERR_ALREADY_EXISTS,
+       DVPNLIB_ERR_ALREADY_ENABLED,
+       DVPNLIB_ERR_ALREADY_DISABLED,
+       DVPNLIB_ERR_ALREADY_CONNECTED,
+       DVPNLIB_ERR_NOT_CONNECTED,
+       DVPNLIB_ERR_OPERATION_ABORTED,
+       DVPNLIB_ERR_OPERATION_TIMEOUT,
+       DVPNLIB_ERR_INVALID_SERVICE,
+       DVPNLIB_ERR_INVALID_PROPERTY,
+       /* D-Bus error */
+       DVPNLIB_ERR_TIMEOUT,
+       DVPNLIB_ERR_UNKNOWN_PROPERTY,
+       DVPNLIB_ERR_PROPERTY_READONLY,
+       DVPNLIB_ERR_UNKNOWN_METHOD,
+};
+
+/*
+ * Common
+ */
+typedef void(*dvpnlib_reply_cb)(enum dvpnlib_err result,
+                                                       void *user_data);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/dvpnlib/include/dvpnlib-internal.h b/dvpnlib/include/dvpnlib-internal.h
new file mode 100644 (file)
index 0000000..1d0ef75
--- /dev/null
@@ -0,0 +1,75 @@
+#ifndef __DVPNLIB_INTERNAL_H__
+#define __DVPNLIB_INTERNAL_H__
+
+#include <gio/gio.h>
+#include <assert.h>
+
+#include "debug.h"
+#include "dvpnlib-common.h"
+
+struct vpn_manager;
+struct vpn_connection;
+
+extern struct vpn_manager *vpn_manager;
+
+#define VPN_NAME "net.connman.vpn"
+#define VPN_MANAGER_INTERFACE "net.connman.vpn.Manager"
+#define VPN_CONNECTION_INTERFACE "net.connman.vpn.Connection"
+#define VPN_MANAGER_PATH "/"
+
+struct common_reply_data {
+       void *cb;
+       void *data;
+       void *user;
+       bool flag;              /*TODO: */
+};
+
+struct error_map_t {
+       const gchar *error_key_str;
+       enum dvpnlib_err type;
+};
+
+/*
+ * D-Bus
+ */
+enum dvpnlib_err common_set_property(GDBusProxy *dbus_proxy,
+                                        const char *property,
+                                        GVariant *value);
+GVariant *common_get_call_method_result(GDBusProxy *dbus_proxy,
+                                         const char *method);
+enum dvpnlib_err common_set_interface_call_method_sync(
+                                               GDBusProxy *dbus_proxy,
+                                               const char *method,
+                                               GVariant **parameters);
+enum dvpnlib_err common_set_interface_call_method(GDBusProxy *dbus_proxy,
+                                               const char *method,
+                                               GVariant **parameters,
+                                               GAsyncReadyCallback callback,
+                                               gpointer user_data);
+
+/*
+ * VPN Manager
+ */
+struct vpn_manager *create_vpn_manager(void);
+void free_vpn_manager(struct vpn_manager *manager);
+GDBusProxy *get_vpn_manager_dbus_proxy(void);
+
+/*
+ * VPN Connection
+ */
+void sync_vpn_connections(void);
+void destroy_vpn_connections(void);
+struct vpn_connection *get_connection_by_path(const gchar *path);
+gboolean add_vpn_connection(GVariant **parameters,
+                           struct vpn_connection **connection);
+void remove_vpn_connection(struct vpn_connection *connection);
+
+struct common_reply_data *common_reply_data_new(void *cb,
+                                               void *data,
+                                               void *user, bool flag);
+/*
+ * Error
+ */
+enum dvpnlib_err get_error_type(GError *error);
+
+#endif
diff --git a/dvpnlib/include/dvpnlib-vpn-connection.h b/dvpnlib/include/dvpnlib-vpn-connection.h
new file mode 100644 (file)
index 0000000..20682ea
--- /dev/null
@@ -0,0 +1,149 @@
+#ifndef __VPN_CONNECTION_H__
+#define __VPN_CONNECTION_H__
+
+#include "dvpnlib-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct vpn_connection;
+
+enum vpn_connection_state {
+       VPN_CONN_STATE_IDLE,
+       VPN_CONN_STATE_READY,
+       VPN_CONN_STATE_CONFIGURATION,
+       VPN_CONN_STATE_DISCONNECT,
+       VPN_CONN_STATE_FAILURE,
+       VPN_CONN_STATE_UNKNOWN,
+};
+
+enum vpn_connection_property_type {
+       VPN_CONN_PROP_NONE,
+
+       /*string State [readonly]*/
+       VPN_CONN_PROP_STATE,
+       /*string Name [readonly]*/
+       VPN_CONN_PROP_NAME,
+       /*boolean Immutable [readonly]*/
+       VPN_CONN_PROP_IMMUTABLE,
+
+       /*string Domain [readonly]*/
+       VPN_CONN_PROP_DOMAIN,
+       /*string Host [readonly]*/
+       VPN_CONN_PROP_HOST,
+       /*string Type [readonly]*/
+       VPN_CONN_PROP_TYPE,
+       /*int Index [readonly]*/
+       VPN_CONN_PROP_INDEX,
+       /*dict IPv4 [readonly]*/
+       VPN_CONN_PROP_IPV4,
+       /*dict IPv6 [readonly]*/
+       VPN_CONN_PROP_IPV6,
+       /*array{string} Nameservers [readonly]*/
+       VPN_CONN_PROP_NAMESERVERS,
+       /* array{dict} UserRoutes [readwrite] */
+       VPN_CONN_PROP_USERROUTES,
+       /* array{dict} ServerRoutes [readonly] */
+       VPN_CONN_PROP_SERVERROUTES,
+};
+
+/*
+ * Connection Property Structures
+ */
+struct vpn_connection_ipv4 {
+       gchar *address;
+       gchar *netmask;
+       gchar *gateway;
+       gchar *peer;
+};
+
+struct vpn_connection_ipv6 {
+       gchar *address;
+       gchar *prefix_length;
+       gchar *gateway;
+       gchar *peer;
+};
+
+struct vpn_connection_route {
+       int protocol_family;
+       gchar *network;
+       gchar *netmask;
+       gchar *gateway;
+};
+
+/*
+ * Callback prototype
+ */
+typedef void (*vpn_connection_property_changed_cb)(
+                               struct vpn_connection *connection,
+                               void *user_data);
+
+/*
+* Methods
+*/
+/* experimental */
+GList *vpn_get_connections(void);
+struct vpn_connection *vpn_get_connection(
+                               const char *host, const char *domain);
+enum dvpnlib_err vpn_connection_clear_property(
+                               struct vpn_connection *connection);
+enum dvpnlib_err vpn_connection_connect(struct vpn_connection *connection,
+                               dvpnlib_reply_cb callback,
+                               void *user_data);
+enum dvpnlib_err
+vpn_connection_disconnect(struct vpn_connection *connection);
+
+/*
+ * Properties
+ */
+/* Set */
+enum dvpnlib_err
+vpn_connection_set_user_routes(struct vpn_connection *connection,
+                       struct vpn_connection_route **user_routes);
+
+/* Get */
+const char *vpn_connection_get_type(
+                               struct vpn_connection *connection);
+const char *vpn_connection_get_name(
+                               struct vpn_connection *connection);
+const char *vpn_connection_get_path(
+                               struct vpn_connection *connection);
+const char *vpn_connection_get_domain(
+                               struct vpn_connection *connection);
+const char *vpn_connection_get_host(
+                               struct vpn_connection *connection);
+bool vpn_connection_get_immutable(
+                               struct vpn_connection *connection);
+int vpn_connection_get_index(
+                               struct vpn_connection *connection);
+
+enum vpn_connection_state vpn_connection_get_state(
+                               struct vpn_connection *connection);
+const struct vpn_connection_ipv4 *vpn_connection_get_ipv4(
+                               struct vpn_connection *connection);
+const struct vpn_connection_ipv6 *vpn_connection_get_ipv6(
+                               struct vpn_connection *connection);
+char **vpn_connection_get_nameservers(
+                               struct vpn_connection *connection);
+GSList *vpn_connection_get_user_routes(
+                               struct vpn_connection *connection);
+GSList *vpn_connection_get_server_routes(
+                               struct vpn_connection *connection);
+/*
+ * Signals
+ */
+enum dvpnlib_err vpn_connection_set_property_changed_cb(
+                               struct vpn_connection *connection,
+                               enum vpn_connection_property_type type,
+                               vpn_connection_property_changed_cb cb,
+                               void *user_data);
+enum dvpnlib_err vpn_connection_unset_property_changed_cb(
+                               struct vpn_connection *connection,
+                               enum vpn_connection_property_type type);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/dvpnlib/include/dvpnlib-vpn-manager.h b/dvpnlib/include/dvpnlib-vpn-manager.h
new file mode 100644 (file)
index 0000000..2af716e
--- /dev/null
@@ -0,0 +1,55 @@
+#ifndef __VPN_MANAGER_H__
+#define __VPN_MANAGER_H__
+
+#include "dvpnlib-common.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct vpn_manager;
+struct vpn_connection;
+
+struct vpn_setting_entry {
+       gchar *key;
+       gchar *value;
+};
+
+/*
+ * Callback prototype
+ */
+typedef void (*vpn_connection_added_cb)(
+                               struct vpn_connection *connection,
+                               void *user_data);
+typedef void (*vpn_connection_removed_cb)(
+                               struct vpn_connection *connection,
+                               void *user_data);
+/*
+* Methods
+*/
+GList *vpn_get_connections(void);
+enum dvpnlib_err dvpnlib_vpn_manager_create(GHashTable *settings,
+                               dvpnlib_reply_cb callback,
+                               void *user_data);
+enum dvpnlib_err dvpnlib_vpn_manager_remove(const char *path,
+                               dvpnlib_reply_cb callback,
+                               void *user_data);
+enum dvpnlib_err dvpnlib_vpn_manager_register_agent(const char *path);
+enum dvpnlib_err dvpnlib_vpn_manager_unregister_agent(const char *path);
+
+/*
+ * Signals
+ */
+void dvpnlib_vpn_manager_set_connection_added_cb(
+                               vpn_connection_added_cb cb,
+                               void *user_data);
+void dvpnlib_vpn_manager_unset_connection_added_cb();
+void dvpnlib_vpn_manager_set_connection_removed_cb(
+                               vpn_connection_removed_cb cb,
+                               void *user_data);
+void dvpnlib_vpn_manager_unset_connection_removed_cb();
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/dvpnlib/include/dvpnlib-vpn.h b/dvpnlib/include/dvpnlib-vpn.h
new file mode 100644 (file)
index 0000000..a8aede8
--- /dev/null
@@ -0,0 +1,15 @@
+#ifndef __VPN_LIB_H__
+#define __VPN_LIB_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int dvpnlib_vpn_init(void);
+void dvpnlib_vpn_deinit(void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/dvpnlib/src/dvpnlib-vpn-connnection.c b/dvpnlib/src/dvpnlib-vpn-connnection.c
new file mode 100644 (file)
index 0000000..88e93bb
--- /dev/null
@@ -0,0 +1,1039 @@
+#include "dvpnlib-internal.h"
+#include "dvpnlib-vpn-connection.h"
+
+static GList *vpn_connection_list;
+static GHashTable *vpn_connection_hash;
+
+struct connection_property_changed_cb {
+       vpn_connection_property_changed_cb property_changed_cb;
+       void *user_data;
+};
+
+struct vpn_connection {
+       GDBusProxy *dbus_proxy;
+       gchar *type;
+       gchar *path;
+       gchar *name;
+       gchar *domain;
+       gchar *host;
+       gboolean immutable;
+       gint index;
+       enum vpn_connection_state state;
+       struct vpn_connection_ipv4 *ipv4;
+       struct vpn_connection_ipv6 *ipv6;
+       gchar **nameservers;
+       GSList *user_routes; /*struct vpn_connection_route */
+       GSList *server_routes; /* struct vpn_connection_route */
+       GHashTable *property_changed_cb_hash;
+};
+
+static void free_vpn_connection_ipv4(struct vpn_connection_ipv4 *ipv4_info);
+static void free_vpn_connection_ipv6(struct vpn_connection_ipv6 *ipv6_info);
+static void free_vpn_connection_route(gpointer data);
+
+enum dvpnlib_err
+vpn_connection_set_user_routes(struct vpn_connection *connection,
+                           struct vpn_connection_route **user_routes)
+{
+       if (!connection || !user_routes)
+               return DVPNLIB_ERR_INVALID_PARAMETER;
+
+       GVariantBuilder user_routes_b;
+       GVariant *user_routes_v;
+
+       g_variant_builder_init(&user_routes_b, G_VARIANT_TYPE("a(a{sv})"));
+
+       while (*user_routes != NULL) {
+
+               g_variant_builder_open(&user_routes_b,
+                               G_VARIANT_TYPE("(a{sv})"));
+               g_variant_builder_open(&user_routes_b,
+                               G_VARIANT_TYPE("a{sv}"));
+
+               if ((*user_routes)->protocol_family) {
+                       g_variant_builder_add(&user_routes_b, "{sv}",
+                               "ProtocolFamily",
+                               g_variant_new_int32(
+                                       (*user_routes)->protocol_family));
+               }
+
+               if ((*user_routes)->network) {
+                       g_variant_builder_add(&user_routes_b, "{sv}",
+                               "Network",
+                               g_variant_new_string((*user_routes)->network));
+               }
+
+               if ((*user_routes)->netmask) {
+                       g_variant_builder_add(&user_routes_b, "{sv}",
+                               "Netmask",
+                               g_variant_new_string((*user_routes)->netmask));
+               }
+
+               if ((*user_routes)->gateway) {
+                       g_variant_builder_add(&user_routes_b, "{sv}",
+                               "Gateway",
+                               g_variant_new_string((*user_routes)->gateway));
+               }
+
+               g_variant_builder_close(&user_routes_b);
+               g_variant_builder_close(&user_routes_b);
+
+               user_routes++;
+       }
+
+       user_routes_v = g_variant_builder_end(&user_routes_b);
+
+       return common_set_property(connection->dbus_proxy, "UserRoutes",
+                       user_routes_v);
+
+}
+
+static struct connection_property_changed_cb
+               *get_connection_property_changed_cb(
+                       struct vpn_connection *connection,
+                       enum vpn_connection_property_type type)
+{
+       return g_hash_table_lookup(connection->property_changed_cb_hash,
+                                       GINT_TO_POINTER(type));
+}
+
+static void parse_connection_property_ipv4(
+                               struct vpn_connection *connection,
+                               GVariant *ipv4)
+{
+       DBG("");
+
+       GVariantIter *iter;
+       gchar *key;
+       GVariant *value;
+
+       g_variant_get(ipv4, "a{sv}", &iter);
+       if (g_variant_iter_n_children(iter) == 0) {
+               g_variant_iter_free(iter);
+               return;
+       }
+
+       if (connection->ipv4)
+               free_vpn_connection_ipv4(connection->ipv4);
+
+       connection->ipv4 = g_try_new0(struct vpn_connection_ipv4, 1);
+       if (connection->ipv4 == NULL) {
+               ERROR("no memory");
+               g_variant_iter_free(iter);
+               return;
+       }
+
+       while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+               if (!g_strcmp0(key, "Address")) {
+                       const char *property_value =
+                               g_variant_get_string(value, NULL);
+                       DBG("Address is %s", property_value);
+                       connection->ipv4->address = g_strdup(property_value);
+               } else if (!g_strcmp0(key, "Netmask")) {
+                       const char *property_value =
+                               g_variant_get_string(value, NULL);
+                       DBG("Netmask is %s", property_value);
+                       connection->ipv4->netmask = g_strdup(property_value);
+               } else if (!g_strcmp0(key, "Gateway")) {
+                       const char *property_value =
+                               g_variant_get_string(value, NULL);
+                       DBG("Gateway is %s", property_value);
+                       connection->ipv4->gateway = g_strdup(property_value);
+               } else if (!g_strcmp0(key, "Peer")) {
+                       const char *property_value =
+                               g_variant_get_string(value, NULL);
+                       DBG("Peer is %s", property_value);
+                       connection->ipv4->peer = g_strdup(property_value);
+               }
+       }
+
+       g_variant_iter_free(iter);
+}
+
+static void parse_connection_property_ipv6(
+                               struct vpn_connection *connection,
+                               GVariant *ipv6)
+{
+       DBG("");
+
+       GVariantIter *iter;
+       gchar *key;
+       GVariant *value;
+
+       g_variant_get(ipv6, "a{sv}", &iter);
+       if (g_variant_iter_n_children(iter) == 0) {
+               g_variant_iter_free(iter);
+               return;
+       }
+
+       if (connection->ipv6)
+               free_vpn_connection_ipv6(connection->ipv6);
+
+       connection->ipv6 = g_try_new0(struct vpn_connection_ipv6, 1);
+       if (connection->ipv6 == NULL) {
+               ERROR("no memory");
+               g_variant_iter_free(iter);
+               return;
+       }
+
+       while (g_variant_iter_loop(iter, "{sv}", &key, &value)) {
+               if (!g_strcmp0(key, "Address")) {
+                       const char *property_value =
+                               g_variant_get_string(value, NULL);
+                       DBG("Address is %s", property_value);
+                       connection->ipv6->address = g_strdup(property_value);
+               } else if (!g_strcmp0(key, "PrefixLength")) {
+                       const char *property_value =
+                               g_variant_get_string(value, NULL);
+                       DBG("PrefixLength is %s", property_value);
+                       connection->ipv6->prefix_length =
+                               g_strdup(property_value);
+               } else if (!g_strcmp0(key, "Gateway")) {
+                       const char *property_value =
+                               g_variant_get_string(value, NULL);
+                       DBG("Gateway is %s", property_value);
+                       connection->ipv6->gateway = g_strdup(property_value);
+               } else if (!g_strcmp0(key, "Peer")) {
+                       const char *property_value =
+                               g_variant_get_string(value, NULL);
+                       DBG("Peer is %s", property_value);
+                       connection->ipv6->peer = g_strdup(property_value);
+               }
+       }
+
+       g_variant_iter_free(iter);
+}
+
+static void parse_connection_property_nameservers(
+                               struct vpn_connection *connection,
+                               GVariant *nameservers)
+{
+       DBG("");
+
+       GVariantIter *iter;
+       gchar *value;
+       int i = 0, n;
+
+       g_variant_get(nameservers, "as", &iter);
+       if (g_variant_iter_n_children(iter) == 0) {
+               g_variant_iter_free(iter);
+               return;
+       }
+
+       g_strfreev(connection->nameservers);
+       n = g_variant_iter_n_children(iter);
+       connection->nameservers = g_try_new0(char *, n+1);
+       if (connection->nameservers == NULL) {
+               ERROR("no memory");
+               g_variant_iter_free(iter);
+               return;
+       }
+
+       while (g_variant_iter_loop(iter, "s", &value) && i < n) {
+               DBG("Nameserver Entry is %s", value);
+               connection->nameservers[i] = g_strdup(value);
+               i++;
+       }
+       connection->nameservers[n] = NULL;
+
+       g_variant_iter_free(iter);
+}
+
+static void print_variant(const gchar *s, GVariant *v)
+{
+       gchar *temp = g_variant_print(v, true);
+       DBG("%s => %s", s, temp);
+       g_free(temp);
+}
+
+static void parse_connection_property_user_routes(
+                               struct vpn_connection *connection,
+                               GVariant *user_routes)
+{
+       DBG("");
+
+       GVariantIter outer;
+       GVariantIter *route_entry;
+
+       print_variant("Incoming : ", user_routes);
+
+       g_variant_iter_init(&outer, user_routes);
+       if (g_variant_iter_n_children(&outer) == 0)
+               return;
+
+       if (connection->user_routes)
+               g_slist_free_full(connection->user_routes,
+                               free_vpn_connection_route);
+
+       while (g_variant_iter_loop(&outer, "(a{sv})", &route_entry)) {
+               gchar *key;
+               GVariant *value;
+
+               if (g_variant_iter_n_children(route_entry) == 0)
+                       continue;
+
+               struct vpn_connection_route *route =
+                       g_try_new0(struct vpn_connection_route, 1);
+               if (route == NULL) {
+                       ERROR("no memory");
+                       return;
+               }
+
+               while (g_variant_iter_loop(route_entry, "{sv}", &key, &value)) {
+                       if (!g_strcmp0(key, "ProtocolFamily")) {
+                               int property_value = g_variant_get_int32(value);
+                               DBG("ProtocolFamily is %d", property_value);
+                               route->protocol_family = property_value;
+                       } else if (!g_strcmp0(key, "Network")) {
+                               const char *property_value =
+                                       g_variant_get_string(value, NULL);
+                               DBG("Network is %s", property_value);
+                               route->network = g_strdup(property_value);
+                       } else if (!g_strcmp0(key, "Netmask")) {
+                               const char *property_value =
+                                       g_variant_get_string(value, NULL);
+                               DBG("Netmask is %s", property_value);
+                               route->netmask = g_strdup(property_value);
+                       } else if (!g_strcmp0(key, "Gateway")) {
+                               const char *property_value =
+                                       g_variant_get_string(value, NULL);
+                               DBG("Gateway is %s", property_value);
+                               route->gateway = g_strdup(property_value);
+                       }
+               }
+
+               /*TODO: See if g_slist_prepend works better*/
+               connection->user_routes =
+                       g_slist_append(connection->user_routes, route);
+
+       }
+}
+
+static void parse_connection_property_server_routes(
+                               struct vpn_connection *connection,
+                               GVariant *server_routes)
+{
+       DBG("");
+
+       GVariantIter outer;
+       GVariantIter *route_entry;
+
+       g_variant_iter_init(&outer, server_routes);
+       if (g_variant_iter_n_children(&outer) == 0) {
+               return;
+       }
+
+       if (connection->server_routes)
+               g_slist_free_full(connection->server_routes,
+                               free_vpn_connection_route);
+
+       while (g_variant_iter_loop(&outer, "(a{sv})", &route_entry)) {
+               gchar *key;
+               GVariant *value;
+
+               if (g_variant_iter_n_children(route_entry) == 0)
+                       continue;
+
+               struct vpn_connection_route *route =
+                       g_try_new0(struct vpn_connection_route, 1);
+               if (route == NULL) {
+                       ERROR("no memory");
+                       return;
+               }
+
+               while (g_variant_iter_loop(route_entry, "{sv}", &key, &value)) {
+                       if (!g_strcmp0(key, "ProtocolFamily")) {
+                               int property_value = g_variant_get_int32(value);
+                               DBG("ProtocolFamily is %d", property_value);
+                               route->protocol_family = property_value;
+                       } else if (!g_strcmp0(key, "Network")) {
+                               const char *property_value =
+                                       g_variant_get_string(value, NULL);
+                               DBG("Network is %s", property_value);
+                               route->network = g_strdup(property_value);
+                       } else if (!g_strcmp0(key, "Netmask")) {
+                               const char *property_value =
+                                       g_variant_get_string(value, NULL);
+                               DBG("Netmask is %s", property_value);
+                               route->netmask = g_strdup(property_value);
+                       } else if (!g_strcmp0(key, "Gateway")) {
+                               const char *property_value =
+                                       g_variant_get_string(value, NULL);
+                               DBG("Gateway is %s", property_value);
+                               route->gateway = g_strdup(property_value);
+                       }
+               }
+
+               /*TODO: See if g_slist_prepend works better*/
+               connection->server_routes =
+                       g_slist_append(connection->server_routes, route);
+       }
+}
+
+static enum vpn_connection_property_type parse_connection_property(
+                                       struct vpn_connection *connection,
+                                       gchar *key, GVariant *value)
+{
+       assert(connection != NULL);
+       enum vpn_connection_property_type property_type = VPN_CONN_PROP_NONE;
+
+       if (!g_strcmp0(key, "State")) {
+               const gchar *property_value;
+               property_value = g_variant_get_string(value, NULL);
+               DBG("connection state is %s", property_value);
+               if (!g_strcmp0(property_value, "idle"))
+                       connection->state = VPN_CONN_STATE_IDLE;
+               else if (!g_strcmp0(property_value, "failure"))
+                       connection->state = VPN_CONN_STATE_FAILURE;
+               else if (!g_strcmp0(property_value, "configuration"))
+                       connection->state = VPN_CONN_STATE_CONFIGURATION;
+               else if (!g_strcmp0(property_value, "ready"))
+                       connection->state = VPN_CONN_STATE_READY;
+               else if (!g_strcmp0(property_value, "disconnect"))
+                       connection->state = VPN_CONN_STATE_DISCONNECT;
+               property_type = VPN_CONN_PROP_STATE;
+       } else if (!g_strcmp0(key, "Type")) {
+               const gchar *property_value;
+               property_value = g_variant_get_string(value, NULL);
+               DBG("connection type is %s", property_value);
+               g_free(connection->type);
+               connection->type = g_strdup(property_value);
+               property_type = VPN_CONN_PROP_TYPE;
+       } else if (!g_strcmp0(key, "Name")) {
+               const gchar *property_value;
+               property_value = g_variant_get_string(value, NULL);
+               g_free(connection->name);
+               connection->name = g_strdup(property_value);
+               property_type = VPN_CONN_PROP_NAME;
+       } else if (!g_strcmp0(key, "Domain")) {
+               const gchar *property_value;
+               property_value = g_variant_get_string(value, NULL);
+               g_free(connection->domain);
+               connection->domain = g_strdup(property_value);
+               property_type = VPN_CONN_PROP_DOMAIN;
+       } else if (!g_strcmp0(key, "Host")) {
+               const gchar *property_value;
+               property_value = g_variant_get_string(value, NULL);
+               g_free(connection->host);
+               connection->host = g_strdup(property_value);
+               property_type = VPN_CONN_PROP_HOST;
+       } else if (!g_strcmp0(key, "Immutable")) {
+               connection->immutable = g_variant_get_boolean(value);
+               property_type = VPN_CONN_PROP_IMMUTABLE;
+       } else if (!g_strcmp0(key, "Index")) {
+               connection->index = g_variant_get_int32(value);
+               property_type = VPN_CONN_PROP_INDEX;
+       }
+       /* TODO:
+        * Add IPv4/IPV6/Nameservers
+        * UserRoutes/ServerRoutes
+        * Parsing code */
+
+       else if (!g_strcmp0(key, "IPv4")) {
+               parse_connection_property_ipv4(connection, value);
+               property_type = VPN_CONN_PROP_IPV4;
+       } else if (!g_strcmp0(key, "IPv6")) {
+               parse_connection_property_ipv6(connection, value);
+               property_type = VPN_CONN_PROP_IPV6;
+       } else if (!g_strcmp0(key, "Nameservers")) {
+               parse_connection_property_nameservers(connection, value);
+               property_type = VPN_CONN_PROP_USERROUTES;
+       } else if (!g_strcmp0(key, "UserRoutes")) {
+               parse_connection_property_user_routes(connection, value);
+               property_type = VPN_CONN_PROP_USERROUTES;
+       } else if (!g_strcmp0(key, "ServerRoutes")) {
+               parse_connection_property_server_routes(connection, value);
+               property_type = VPN_CONN_PROP_SERVERROUTES;
+       }
+
+       return property_type;
+}
+
+static void parse_connection_properties(
+                               struct vpn_connection *connection,
+                               GVariantIter *properties)
+{
+       gchar *key;
+       GVariant *value;
+
+       while (g_variant_iter_next(properties, "{sv}", &key, &value)) {
+               parse_connection_property(connection, key, value);
+
+               g_free(key);
+               g_variant_unref(value);
+       }
+}
+
+static void connection_property_changed(
+                               struct vpn_connection *connection,
+                               GVariant *parameters)
+{
+       gchar *key;
+       GVariant *value;
+       enum vpn_connection_property_type property_type;
+
+       DBG("");
+
+       g_variant_get(parameters, "(sv)", &key, &value);
+       property_type = parse_connection_property(connection, key, value);
+
+       if (property_type != VPN_CONN_PROP_NONE) {
+               DBG("Now check property changed callback");
+
+               struct connection_property_changed_cb *property_changed_cb_t;
+
+               property_changed_cb_t = get_connection_property_changed_cb(
+                                                       connection,
+                                                       property_type);
+               if (property_changed_cb_t != NULL) {
+                       DBG("property changed callback has been set");
+                       property_changed_cb_t->property_changed_cb(connection,
+                                       property_changed_cb_t->user_data);
+               }
+       }
+
+       g_free(key);
+       g_variant_unref(value);
+}
+
+static void connection_signal_handler(GDBusProxy *proxy,
+                                          gchar *sender_name,
+                                          gchar *signal_name,
+                                          GVariant *parameters,
+                                          gpointer user_data)
+{
+       DBG("signal_name: %s", signal_name);
+
+       struct vpn_connection *connection = user_data;
+
+       if (!g_strcmp0(signal_name, "PropertyChanged"))
+               connection_property_changed(connection, parameters);
+}
+
+static void free_connection_property_changed_cb(gpointer data)
+{
+       DBG("");
+       struct connection_property_changed_cb *property_changed_cb = data;
+
+       g_free(property_changed_cb);
+}
+
+void destroy_vpn_connections(void)
+{
+       if (vpn_connection_list != NULL) {
+               g_list_free(vpn_connection_list);
+               vpn_connection_list = NULL;
+       }
+       if (vpn_connection_hash != NULL) {
+               g_hash_table_destroy(vpn_connection_hash);
+               vpn_connection_hash = NULL;
+       }
+}
+
+static struct vpn_connection *create_vpn_connection(
+                                               gchar *object_path,
+                                               GVariantIter *properties)
+{
+       GDBusProxy *connection_proxy;
+       struct vpn_connection *connection;
+       GError *error = NULL;
+
+       DBG("");
+
+       connection_proxy = g_dbus_proxy_new_for_bus_sync(G_BUS_TYPE_SYSTEM,
+                                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                                       VPN_NAME, object_path,
+                                       VPN_CONNECTION_INTERFACE, NULL, &error);
+       if (connection_proxy == NULL) {
+               ERROR("error info: %s", error->message);
+               g_error_free(error);
+               return NULL;
+       }
+
+       connection = g_try_new0(struct vpn_connection, 1);
+       if (connection == NULL) {
+               ERROR("no memory");
+               g_object_unref(connection_proxy);
+               return NULL;
+       }
+
+       connection->dbus_proxy = connection_proxy;
+       connection->path = g_strdup(object_path);
+
+       parse_connection_properties(connection, properties);
+
+       g_hash_table_insert(vpn_connection_hash,
+                               (gpointer)connection->path,
+                               (gpointer)connection);
+
+       vpn_connection_list = g_list_append(vpn_connection_list,
+                                               connection);
+
+       connection->property_changed_cb_hash = g_hash_table_new_full(
+                                       g_direct_hash, g_direct_equal, NULL,
+                                       free_connection_property_changed_cb);
+
+       g_signal_connect(connection->dbus_proxy, "g-signal",
+                       G_CALLBACK(connection_signal_handler), connection);
+
+       return connection;
+}
+
+static void free_vpn_connection_ipv4(struct vpn_connection_ipv4 *ipv4_info)
+{
+       DBG("");
+
+       g_free(ipv4_info->address);
+       g_free(ipv4_info->netmask);
+       g_free(ipv4_info->gateway);
+       g_free(ipv4_info->peer);
+       g_free(ipv4_info);
+}
+
+static void free_vpn_connection_ipv6(struct vpn_connection_ipv6 *ipv6_info)
+{
+       DBG("");
+
+       g_free(ipv6_info->address);
+       g_free(ipv6_info->prefix_length);
+       g_free(ipv6_info->gateway);
+       g_free(ipv6_info->peer);
+       g_free(ipv6_info);
+}
+
+static void free_vpn_connection_route(gpointer data)
+{
+       DBG("");
+
+       struct vpn_connection_route *route = data;
+
+       if (route == NULL) {
+               DBG("Nothing to Delete!");
+               return;
+       }
+
+       g_free(route->network);
+       g_free(route->netmask);
+       g_free(route->gateway);
+
+       g_free(route);
+}
+
+static void free_vpn_connection(gpointer data)
+{
+       DBG("");
+
+       struct vpn_connection *connection = data;
+
+       if (connection == NULL)
+               return;
+
+       if (connection->dbus_proxy != NULL)
+               g_object_unref(connection->dbus_proxy);
+
+       if (connection->property_changed_cb_hash != NULL)
+               g_hash_table_destroy(connection->property_changed_cb_hash);
+
+       g_free(connection->path);
+       g_free(connection->name);
+       g_free(connection->domain);
+       g_free(connection->host);
+
+       if (connection->ipv4)
+               free_vpn_connection_ipv4(connection->ipv4);
+
+       if (connection->ipv6)
+               free_vpn_connection_ipv6(connection->ipv6);
+
+       g_strfreev(connection->nameservers);
+
+       if (connection->user_routes)
+               g_slist_free_full(connection->user_routes,
+                               free_vpn_connection_route);
+
+       if (connection->server_routes)
+               g_slist_free_full(connection->server_routes,
+                               free_vpn_connection_route);
+
+       g_free(connection);
+}
+
+static void create_vpn_connections(GVariant *connections)
+{
+       GVariantIter *iter;
+       gchar *path;
+       GVariantIter *properties;
+
+       g_variant_get(connections, "(a(oa{sv}))", &iter);
+       if (g_variant_iter_n_children(iter) == 0) {
+               g_variant_iter_free(iter);
+               return;
+       }
+
+       while (g_variant_iter_loop(iter, "(oa{sv})", &path, &properties))
+               create_vpn_connection(path, properties);
+
+       g_variant_iter_free(iter);
+}
+
+struct vpn_connection *get_connection_by_path(const gchar *path)
+{
+       DBG("path: %s", path);
+
+       return g_hash_table_lookup(vpn_connection_hash, (gpointer)path);
+}
+
+gboolean add_vpn_connection(GVariant **parameters,
+                               struct vpn_connection **connection)
+{
+       gchar *print_str;
+       gchar *connection_path;
+       GVariantIter *properties;
+       gboolean ret;
+
+       g_variant_get(*parameters, "(oa{sv})", &connection_path, &properties);
+
+       print_str = g_variant_print(*parameters, TRUE);
+       DBG("connection path: %s, parameters: %s", connection_path, print_str);
+       g_free(print_str);
+
+       /*
+        * Lookup if it has existed in the hash table
+        */
+       *connection = g_hash_table_lookup(vpn_connection_hash,
+                                               (gpointer) connection_path);
+       if (*connection != NULL) {
+               DBG("Repetitive connection %s", (*connection)->name);
+
+               ret = FALSE;
+       } else {
+               *connection = create_vpn_connection(connection_path,
+                                                               properties);
+               if (*connection != NULL)
+                       ret = TRUE;
+               else
+                       ret = FALSE;
+       }
+
+       g_variant_iter_free(properties);
+       return ret;
+}
+
+void remove_vpn_connection(struct vpn_connection *connection)
+{
+       DBG("");
+
+       assert(connection != NULL);
+
+       vpn_connection_list = g_list_remove(vpn_connection_list,
+                                               (gpointer)connection);
+
+       g_hash_table_remove(vpn_connection_hash,
+                       (gconstpointer)connection->path);
+}
+
+void sync_vpn_connections(void)
+{
+       DBG("");
+
+       gchar *print_str;
+       GVariant *connections;
+       GError *error = NULL;
+
+       connections = g_dbus_proxy_call_sync(get_vpn_manager_dbus_proxy(),
+                                               "GetConnections", NULL,
+                                               G_DBUS_CALL_FLAGS_NONE,
+                                               -1, NULL, &error);
+       if (connections == NULL) {
+               ERROR("error info: %s", error->message);
+               g_error_free(error);
+               return;
+       }
+
+       print_str = g_variant_print(connections, TRUE);
+       DBG("connections: %s", print_str);
+       g_free(print_str);
+
+       if (!vpn_connection_hash)
+               vpn_connection_hash = g_hash_table_new_full(
+                                       g_str_hash, g_str_equal,
+                                       NULL, free_vpn_connection);
+       DBG("hash: %p", vpn_connection_hash);
+
+       create_vpn_connections(connections);
+
+       g_variant_unref(connections);
+}
+
+/**
+ * VPN Connection Methods
+ */
+GList *vpn_get_connections(void)
+{
+       DBG("");
+
+       return vpn_connection_list;
+}
+
+struct vpn_connection *vpn_get_connection(
+                                       const char *host, const char *domain)
+{
+       if (!host || !domain)
+               return NULL;
+
+       GList *iter;
+
+       for (iter = vpn_connection_list; iter != NULL;
+            iter = iter->next) {
+               struct vpn_connection *connection =
+                   (struct vpn_connection *)(iter->data);
+
+               if (g_str_equal(connection->host, host) &&
+                               g_str_equal(connection->domain, domain))
+                       return connection;
+       }
+
+       return NULL;
+}
+
+enum dvpnlib_err vpn_connection_clear_property(
+                               struct vpn_connection *connection)
+{
+       GVariant *value;
+
+       assert(connection != NULL);
+
+       /**
+        * Only supported the "UserRoutes" item now;
+        */
+       value = g_variant_new("(s)", "UserRoutes");
+
+       return common_set_interface_call_method_sync(connection->dbus_proxy,
+                                               "ClearProperty", &value);
+}
+
+/**
+ * Asynchronous connect callback
+ */
+static void connect_callback(GObject *source_object,
+                            GAsyncResult *res, gpointer user_data)
+{
+       GError *error = NULL;
+       enum dvpnlib_err error_type = DVPNLIB_ERR_NONE;
+       GVariant *ret;
+       struct common_reply_data *reply_data;
+       struct vpn_connection *connection;
+
+       reply_data = user_data;
+       if (!reply_data)
+               return;
+
+       connection = reply_data->user;
+       if (!connection)
+               goto done;
+
+       if (!connection->dbus_proxy)
+               goto done;
+
+       ret = g_dbus_proxy_call_finish(connection->dbus_proxy, res, &error);
+       if (!ret) {
+               DBG("%s", error->message);
+               error_type = get_error_type(error);
+
+               g_error_free(error);
+       } else
+               g_variant_unref(ret);
+
+       if (reply_data->cb) {
+               dvpnlib_reply_cb callback = reply_data->cb;
+               callback(error_type, reply_data->data);
+       }
+
+done:
+       g_free(reply_data);
+}
+
+enum dvpnlib_err vpn_connection_connect(struct vpn_connection *connection,
+                                dvpnlib_reply_cb callback,
+                                void *user_data)
+{
+       DBG("");
+
+       struct common_reply_data *reply_data;
+
+       assert(connection != NULL);
+
+       reply_data =
+           common_reply_data_new(callback, user_data, connection, TRUE);
+
+       return common_set_interface_call_method(connection->dbus_proxy,
+                                        "Connect", NULL,
+                                        (GAsyncReadyCallback)
+                                        connect_callback, reply_data);
+}
+
+enum dvpnlib_err
+vpn_connection_disconnect(struct vpn_connection *connection)
+{
+       DBG("");
+
+       assert(connection != NULL);
+
+       return common_set_interface_call_method_sync(connection->dbus_proxy,
+                                        "Disconnect", NULL);
+
+}
+
+const char *vpn_connection_get_type(
+                                       struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->type;
+}
+
+const char *vpn_connection_get_name(
+                                       struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->name;
+}
+
+const char *vpn_connection_get_path(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->path;
+}
+
+const char *vpn_connection_get_domain(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->domain;
+}
+
+const char *vpn_connection_get_host(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->host;
+}
+
+bool vpn_connection_get_immutable(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->immutable;
+}
+
+int vpn_connection_get_index(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->index;
+}
+
+enum vpn_connection_state vpn_connection_get_state(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->state;
+}
+
+const struct vpn_connection_ipv4 *vpn_connection_get_ipv4(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->ipv4;
+}
+
+const struct vpn_connection_ipv6 *vpn_connection_get_ipv6(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->ipv6;
+}
+
+char **vpn_connection_get_nameservers(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->nameservers;
+}
+
+GSList *vpn_connection_get_user_routes(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->user_routes;
+}
+
+GSList *vpn_connection_get_server_routes(
+                               struct vpn_connection *connection)
+{
+       assert(connection != NULL);
+
+       return connection->server_routes;
+}
+
+enum dvpnlib_err vpn_connection_set_property_changed_cb(
+                               struct vpn_connection *connection,
+                               enum vpn_connection_property_type type,
+                               vpn_connection_property_changed_cb cb,
+                               void *user_data)
+{
+       DBG("");
+
+       if (connection == NULL)
+               return DVPNLIB_ERR_INVALID_PARAMETER;
+
+       struct connection_property_changed_cb *property_changed_cb_t =
+                       g_try_new0(struct connection_property_changed_cb, 1);
+       if (property_changed_cb_t == NULL) {
+               ERROR("no memory");
+               return DVPNLIB_ERR_FAILED;
+       }
+       property_changed_cb_t->property_changed_cb = cb;
+       property_changed_cb_t->user_data = user_data;
+
+       g_hash_table_insert(connection->property_changed_cb_hash,
+                               GINT_TO_POINTER(type),
+                               (gpointer)property_changed_cb_t);
+
+       return DVPNLIB_ERR_NONE;
+}
+
+enum dvpnlib_err vpn_connection_unset_property_changed_cb(
+                               struct vpn_connection *connection,
+                               enum vpn_connection_property_type type)
+{
+       DBG("");
+
+       if (connection == NULL)
+               return DVPNLIB_ERR_INVALID_PARAMETER;
+
+       struct connection_property_changed_cb *property_changed_cb_t =
+                       get_connection_property_changed_cb(connection, type);
+
+       if (property_changed_cb_t == NULL) {
+               DBG("Can't find connection property changed callback");
+               return DVPNLIB_ERR_FAILED;
+       }
+
+       g_hash_table_remove(connection->property_changed_cb_hash,
+                               GINT_TO_POINTER(type));
+
+       return DVPNLIB_ERR_NONE;
+}
diff --git a/dvpnlib/src/dvpnlib-vpn-manager.c b/dvpnlib/src/dvpnlib-vpn-manager.c
new file mode 100644 (file)
index 0000000..dd5fb13
--- /dev/null
@@ -0,0 +1,321 @@
+#include "dvpnlib-internal.h"
+#include "dvpnlib-vpn-manager.h"
+
+struct vpn_manager {
+       GDBusProxy *dbus_proxy;
+       void *connection_added_cb_data;
+       void *connection_removed_cb_data;
+       vpn_connection_added_cb connection_added_cb;
+       vpn_connection_removed_cb connection_removed_cb;
+};
+
+static void connection_added(GVariant *parameters)
+{
+       struct vpn_connection *connection;
+
+       DBG("");
+
+       if (add_vpn_connection(&parameters, &connection)) {
+               if (vpn_manager->connection_added_cb) {
+                       vpn_manager->connection_added_cb(connection,
+                               vpn_manager->connection_added_cb_data);
+               }
+       }
+}
+
+static void connection_removed(GVariant *parameters)
+{
+       DBG("");
+
+       const gchar *connection_path;
+       struct vpn_connection *connection;
+
+       g_variant_get(parameters, "(o)", &connection_path);
+
+       connection = get_connection_by_path(connection_path);
+       if (connection == NULL)
+               return;
+
+       if (vpn_manager->connection_removed_cb) {
+               void *user_data = vpn_manager->connection_removed_cb_data;
+               vpn_manager->connection_removed_cb(connection, user_data);
+       }
+
+       remove_vpn_connection(connection);
+}
+
+static void manager_signal_handler(GDBusProxy *proxy, gchar *sender_name,
+                               gchar *signal_name, GVariant *parameters,
+                               gpointer user_data)
+{
+       DBG("signal_name: %s", signal_name);
+
+       if (!g_strcmp0(signal_name, "ConnectionAdded"))
+               connection_added(parameters);
+       else if (!g_strcmp0(signal_name, "ConnectionRemoved"))
+               connection_removed(parameters);
+}
+
+void free_vpn_manager(struct vpn_manager *manager)
+{
+       DBG("");
+
+       if (manager == NULL)
+               return;
+
+       if (manager->dbus_proxy != NULL)
+               g_object_unref(manager->dbus_proxy);
+
+       g_free(manager);
+}
+
+struct vpn_manager *create_vpn_manager(void)
+{
+       GError *error = NULL;
+       struct vpn_manager *manager;
+
+       DBG("");
+       manager = g_try_new0(struct vpn_manager, 1);
+       if (manager == NULL) {
+               ERROR("no memory");
+               return NULL;
+       }
+
+       manager->dbus_proxy = g_dbus_proxy_new_for_bus_sync(
+                                       G_BUS_TYPE_SYSTEM,
+                                       G_DBUS_PROXY_FLAGS_NONE, NULL,
+                                       VPN_NAME, VPN_MANAGER_PATH,
+                                       VPN_MANAGER_INTERFACE, NULL, &error);
+
+       if (manager->dbus_proxy == NULL) {
+               ERROR("error info: %s", error->message);
+               g_error_free(error);
+               free_vpn_manager(manager);
+               return NULL;
+       }
+
+       g_signal_connect(manager->dbus_proxy, "g-signal",
+                       G_CALLBACK(manager_signal_handler), NULL);
+
+       return manager;
+}
+
+GDBusProxy *get_vpn_manager_dbus_proxy(void)
+{
+       return vpn_manager->dbus_proxy;
+}
+
+/**
+ * Asynchronous Methods Create/Remove callback
+ */
+static void create_remove_callback(GObject *source_object,
+                            GAsyncResult *res, gpointer user_data)
+{
+       GError *error = NULL;
+       enum dvpnlib_err error_type = DVPNLIB_ERR_NONE;
+       GVariant *ret;
+       struct common_reply_data *reply_data;
+
+       reply_data = user_data;
+       if (!reply_data)
+               return;
+
+       if (!vpn_manager)
+               goto done;
+
+       if (!vpn_manager->dbus_proxy)
+               goto done;
+
+       ret = g_dbus_proxy_call_finish(vpn_manager->dbus_proxy, res, &error);
+       if (!ret) {
+               DBG("%s", error->message);
+               error_type = get_error_type(error);
+
+               g_error_free(error);
+       } else
+               g_variant_unref(ret);
+
+       if (reply_data->cb) {
+               dvpnlib_reply_cb callback = reply_data->cb;
+               callback(error_type, reply_data->data);
+       }
+
+done:
+       g_free(reply_data);
+}
+
+/* Implementation vpn-manager.h */
+
+static void print_variant(const gchar *s, GVariant *v)
+{
+       gchar *temp = g_variant_print(v, true);
+       DBG("%s => %s", s, temp);
+       g_free(temp);
+}
+
+static GVariant *
+settings_from_hash_table(GHashTable *hash_table)
+{
+       GVariantBuilder builder;
+
+       g_variant_builder_init(&builder, G_VARIANT_TYPE("(a{sv})"));
+       g_variant_builder_open(&builder, G_VARIANT_TYPE("a{sv}"));
+
+       GHashTableIter iter;
+       gpointer key, value;
+
+       g_hash_table_iter_init(&iter, hash_table);
+       while (g_hash_table_iter_next(&iter, &key, &value)) {
+               g_variant_builder_add(&builder, "{sv}",
+                               key,
+                               g_variant_new_string(value));
+       }
+
+       g_variant_builder_close(&builder);
+
+       return g_variant_builder_end(&builder);
+}
+
+enum dvpnlib_err dvpnlib_vpn_manager_create(GHashTable *settings,
+                                dvpnlib_reply_cb callback,
+                                void *user_data)
+{
+       GVariant *settings_v;
+
+       assert(vpn_manager != NULL);
+       assert(settings != NULL);
+
+       settings_v = settings_from_hash_table(settings);
+       print_variant("Settings", settings_v);
+
+       struct common_reply_data *reply_data;
+
+       reply_data =
+               common_reply_data_new(callback, user_data, NULL, TRUE);
+
+       if (NULL == reply_data) {
+               DBG("No Memory Available!");
+               return DVPNLIB_ERR_FAILED;
+       }
+
+       return common_set_interface_call_method(
+                       vpn_manager->dbus_proxy,
+                       "Create",
+                       &settings_v,
+                       (GAsyncReadyCallback)create_remove_callback,
+                       reply_data);
+}
+
+enum dvpnlib_err dvpnlib_vpn_manager_remove(const char *path,
+                                dvpnlib_reply_cb callback,
+                                void *user_data)
+{
+       GVariant *value;
+       enum dvpnlib_err ret = DVPNLIB_ERR_NONE;
+
+       assert(vpn_manager != NULL);
+
+       if (!g_variant_is_object_path(path))
+               return DVPNLIB_ERR_FAILED;
+
+       value = g_variant_new("(o)", path);
+
+       struct common_reply_data *reply_data;
+
+       reply_data =
+           common_reply_data_new(callback, user_data, NULL, TRUE);
+
+       if (NULL == reply_data) {
+               DBG("No Memory Available!");
+               return DVPNLIB_ERR_FAILED;
+
+       }
+
+       ret = common_set_interface_call_method(
+                       vpn_manager->dbus_proxy,
+                       "Remove",
+                       &value,
+                       (GAsyncReadyCallback)create_remove_callback,
+                       reply_data);
+
+       return ret;
+}
+
+enum dvpnlib_err dvpnlib_vpn_manager_register_agent(const char *path)
+{
+       GVariant *value;
+
+       assert(vpn_manager != NULL);
+
+       if (!g_variant_is_object_path(path))
+               return DVPNLIB_ERR_FAILED;
+
+       value = g_variant_new("(o)", path);
+
+       return common_set_interface_call_method_sync(
+                       vpn_manager->dbus_proxy,
+                       "RegisterAgent",
+                       &value);
+}
+
+enum dvpnlib_err dvpnlib_vpn_manager_unregister_agent(const char *path)
+{
+       GVariant *value;
+
+       assert(vpn_manager != NULL);
+
+       if (!g_variant_is_object_path(path))
+               return DVPNLIB_ERR_FAILED;
+
+       value = g_variant_new("(o)", path);
+
+       return common_set_interface_call_method_sync(
+                       vpn_manager->dbus_proxy,
+                       "UnregisterAgent",
+                       &value);
+}
+
+void dvpnlib_vpn_manager_set_connection_added_cb(
+                               vpn_connection_added_cb cb,
+                               void *user_data)
+{
+       DBG("");
+
+       assert(vpn_manager != NULL);
+
+       vpn_manager->connection_added_cb = cb;
+       vpn_manager->connection_added_cb_data = user_data;
+}
+
+void dvpnlib_vpn_manager_unset_connection_added_cb()
+{
+       DBG("");
+
+       assert(vpn_manager != NULL);
+
+       vpn_manager->connection_added_cb = NULL;
+       vpn_manager->connection_added_cb_data = NULL;
+}
+
+void dvpnlib_vpn_manager_set_connection_removed_cb(
+                               vpn_connection_removed_cb cb,
+                               void *user_data)
+{
+       DBG("");
+
+       assert(vpn_manager != NULL);
+
+       vpn_manager->connection_removed_cb = cb;
+       vpn_manager->connection_removed_cb_data = user_data;
+}
+
+void dvpnlib_vpn_manager_unset_connection_removed_cb()
+{
+       DBG("");
+
+       assert(vpn_manager != NULL);
+
+       vpn_manager->connection_removed_cb = NULL;
+       vpn_manager->connection_removed_cb_data = NULL;
+}
+
diff --git a/dvpnlib/src/dvpnlib-vpn.c b/dvpnlib/src/dvpnlib-vpn.c
new file mode 100644 (file)
index 0000000..5a0e962
--- /dev/null
@@ -0,0 +1,33 @@
+#include "dvpnlib-internal.h"
+#include "dvpnlib-vpn.h"
+
+struct vpn_manager *vpn_manager;
+
+int dvpnlib_vpn_init(void)
+{
+       DBG("");
+
+       if (vpn_manager != NULL)
+               return 0;
+
+       vpn_manager = create_vpn_manager();
+
+       if (vpn_manager == NULL) {
+               DBG("can't create vpn manager");
+               return -1;
+       }
+
+       sync_vpn_connections();
+
+       return 0;
+}
+
+void dvpnlib_vpn_deinit(void)
+{
+       DBG("");
+
+       free_vpn_manager(vpn_manager);
+       vpn_manager = NULL;
+
+       destroy_vpn_connections();
+}
diff --git a/dvpnlib/src/dvpnlib.c b/dvpnlib/src/dvpnlib.c
new file mode 100644 (file)
index 0000000..b603946
--- /dev/null
@@ -0,0 +1,180 @@
+#include "dvpnlib-internal.h"
+
+/*
+ * D-Bus
+ */
+enum dvpnlib_err common_set_property(GDBusProxy *dbus_proxy,
+                               const char *property,
+                               GVariant *value)
+{
+       gchar *print_str;
+       GError *error = NULL;
+       enum dvpnlib_err ret = DVPNLIB_ERR_NONE;
+
+       print_str = g_variant_print(value, TRUE);
+       DBG("set object %s property %s to %s",
+               g_dbus_proxy_get_object_path(dbus_proxy),
+               property, print_str);
+       g_free(print_str);
+
+       g_dbus_proxy_call_sync(dbus_proxy, "SetProperty",
+                               g_variant_new("(sv)", property, value),
+                               G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+       if (error) {
+               ERROR("%s", error->message);
+               ret = get_error_type(error);
+               g_error_free(error);
+       }
+
+       return ret;
+}
+
+GVariant *common_get_call_method_result(GDBusProxy *dbus_proxy,
+                                         const char *method)
+{
+       if ((!dbus_proxy) || (!method))
+               return NULL;
+
+       GError *error = NULL;
+       GVariant *result;
+
+       DBG("get object %s method %s",
+               g_dbus_proxy_get_object_path(dbus_proxy), method);
+
+       result = g_dbus_proxy_call_sync(dbus_proxy, method, NULL,
+                                           G_DBUS_CALL_FLAGS_NONE, -1,
+                                           NULL, &error);
+       if (!result) {
+               ERROR("%s", error->message);
+               g_error_free(error);
+               return NULL;
+       }
+
+       return result;
+}
+
+enum dvpnlib_err common_set_interface_call_method_sync(
+                                               GDBusProxy *dbus_proxy,
+                                               const char *method,
+                                               GVariant **parameters)
+{
+       if ((!dbus_proxy) || (!method))
+               return DVPNLIB_ERR_FAILED;
+
+       GVariant *result;
+       GError *error = NULL;
+       enum dvpnlib_err ret = DVPNLIB_ERR_NONE;
+
+       DBG("get object %s property %s",
+               g_dbus_proxy_get_object_path(dbus_proxy), method);
+
+       if (parameters)
+               result = g_dbus_proxy_call_sync(dbus_proxy, method, *parameters,
+                              G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+       else
+               result = g_dbus_proxy_call_sync(dbus_proxy, method, NULL,
+                              G_DBUS_CALL_FLAGS_NONE, -1, NULL, &error);
+       if (error) {
+               ERROR("%s", error->message);
+               ret = get_error_type(error);
+               g_error_free(error);
+               return ret;
+       }
+
+       g_variant_unref(result);
+
+       return ret;
+}
+
+enum dvpnlib_err common_set_interface_call_method(GDBusProxy *dbus_proxy,
+                                               const char *method,
+                                               GVariant **parameters,
+                                               GAsyncReadyCallback callback,
+                                               gpointer user_data)
+{
+       if ((!dbus_proxy) || (!method))
+               return DVPNLIB_ERR_FAILED;
+
+       DBG("get object %s property %s",
+               g_dbus_proxy_get_object_path(dbus_proxy), method);
+
+       if (parameters) {
+               g_dbus_proxy_call(dbus_proxy,
+                               method,
+                               *parameters,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, callback, user_data);
+       } else {
+               g_dbus_proxy_call(dbus_proxy,
+                               method,
+                               NULL,
+                               G_DBUS_CALL_FLAGS_NONE,
+                               -1, NULL, callback, user_data);
+       }
+
+       return DVPNLIB_ERR_NONE;
+}
+
+struct common_reply_data *common_reply_data_new(void *cb, void *data,
+                                               void *user, bool flag)
+{
+       struct common_reply_data *ret;
+
+       ret = g_try_new0(struct common_reply_data, 1);
+       if (!ret)
+               return NULL;
+
+       ret->cb = cb;
+       ret->data = data;
+       ret->user = user;
+       ret->flag = flag;
+
+       return ret;
+}
+
+/*
+ * Error
+ */
+struct error_map_t error_map[] = {
+       {"Error.Failed", DVPNLIB_ERR_OPERATION_FAILED},
+       {"Error.InvalidArguments", DVPNLIB_ERR_INVALID_PARAMETER},
+       {"Error.PermissionDenied", DVPNLIB_ERR_PERMISSION_DENIED},
+       {"Error.PassphraseRequired", DVPNLIB_ERR_PASSPHRASE_REQUIRED},
+       {"Error.NotRegistered", DVPNLIB_ERR_NOT_REGISTERED},
+       {"Error.NotUnique", DVPNLIB_ERR_NOT_UNIQUE},
+       {"Error.NotSupported", DVPNLIB_ERR_NOT_SUPPORTED},
+       {"Error.NotImplemented", DVPNLIB_ERR_NOT_IMPLEMENTED},
+       {"Error.NotFound", DVPNLIB_ERR_NOT_FOUND},
+       {"Error.InProgress", DVPNLIB_ERR_IN_PROGRESS},
+       {"Error.AlreadyExists", DVPNLIB_ERR_ALREADY_EXISTS},
+       {"Error.AlreadyEnabled", DVPNLIB_ERR_ALREADY_ENABLED},
+       {"Error.AlreadyDisabled", DVPNLIB_ERR_ALREADY_DISABLED},
+       {"Error.AlreadyConnected", DVPNLIB_ERR_ALREADY_CONNECTED},
+       {"Error.NotConnected", DVPNLIB_ERR_NOT_CONNECTED},
+       {"Error.OperationAborted", DVPNLIB_ERR_OPERATION_ABORTED},
+       {"Error.OperationTimeout", DVPNLIB_ERR_OPERATION_TIMEOUT},
+       {"Error.InvalidService", DVPNLIB_ERR_INVALID_SERVICE},
+       {"Error.InvalidProperty", DVPNLIB_ERR_INVALID_PROPERTY},
+
+       {"Error.Timeout", DVPNLIB_ERR_TIMEOUT},
+       {"Error.Timedout", DVPNLIB_ERR_TIMEOUT},
+       {"Error.UnknownProperty", DVPNLIB_ERR_UNKNOWN_PROPERTY},
+       {"Error.PropertyReadOnly", DVPNLIB_ERR_PROPERTY_READONLY},
+       {"Error.UnknownMethod", DVPNLIB_ERR_UNKNOWN_METHOD},
+};
+
+enum dvpnlib_err get_error_type(GError *error)
+{
+       int i = 0;
+
+       while (error_map[i].error_key_str != NULL) {
+               const gchar *error_info = error_map[i].error_key_str;
+
+               if (g_strrstr(error->message, error_info))
+                       return error_map[i].type;
+
+               i++;
+       }
+
+       return DVPNLIB_ERR_FAILED;
+}
diff --git a/include/vpn.h b/include/vpn.h
new file mode 100644 (file)
index 0000000..ab6e7ea
--- /dev/null
@@ -0,0 +1,381 @@
+/*
+ * Copyright (c) 2014-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 __TIZEN_NETWORK_VPN_H__
+#define __TIZEN_NETWORK_VPN_H__
+
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* @addtogroup CAPI_NETWORK_VPN_MANAGER_MODULE
+* @{
+*/
+
+/**
+ * @brief The handle for vpn.
+ */
+typedef void *vpn_h;
+typedef void *vpn_settings_h;
+
+/**
+* @brief The VPN error type
+*/
+typedef enum {
+       VPN_ERROR_NONE = TIZEN_ERROR_NONE, /**< Successful */
+       VPN_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER, /**< Invalid parameter */
+       VPN_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY, /**< Out of memory error */
+       VPN_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */
+       VPN_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED = TIZEN_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED, /**< Address family not supported */
+       VPN_ERROR_OPERATION_FAILED = TIZEN_ERROR_NETWORK_CLASS|0x0301, /**< Operation failed */
+       VPN_ERROR_NO_CONNECTION = TIZEN_ERROR_NETWORK_CLASS|0x0302, /**< There is no connected AP */
+       VPN_ERROR_NOW_IN_PROGRESS = TIZEN_ERROR_NOW_IN_PROGRESS, /** Now in progress */
+       VPN_ERROR_ALREADY_EXISTS = TIZEN_ERROR_NETWORK_CLASS|0x0303, /**< Already exists */
+       VPN_ERROR_OPERATION_ABORTED = TIZEN_ERROR_NETWORK_CLASS|0x0304, /**< Operation is aborted */
+       VPN_ERROR_DHCP_FAILED = TIZEN_ERROR_NETWORK_CLASS|0x0306, /**< DHCP failed */
+       VPN_ERROR_INVALID_KEY = TIZEN_ERROR_NETWORK_CLASS|0x0307, /**< Invalid key */
+       VPN_ERROR_NO_REPLY = TIZEN_ERROR_NETWORK_CLASS|0x0308, /**< No reply */
+       VPN_ERROR_SECURITY_RESTRICTED = TIZEN_ERROR_NETWORK_CLASS|0x0309, /**< Restricted by security system policy */
+} vpn_error_e;
+
+/**
+* @}
+*/
+
+/**
+* @addtogroup CAPI_NETWORK_VPN_MONITOR_MODULE
+* @{
+*/
+
+/**
+* @brief Called after vpn_create() is completed.
+* @param[in] result  The result
+* @param[in] user_data The user data passed from vpn_create()
+* @pre vpn_create() will invoke this callback function.
+* @see vpn_create()
+*/
+typedef void(*vpn_created_cb)(vpn_error_e result, void *user_data);
+
+/**
+* @brief Called after vpn_remove() is completed.
+* @param[in] result  The result
+* @param[in] user_data The user data passed from vpn_remove()
+* @pre vpn_remove() will invoke this callback function.
+* @see vpn_remove()
+*/
+typedef void(*vpn_removed_cb)(vpn_error_e result, void *user_data);
+/**
+* @}
+*/
+
+/**
+* @brief Called after vpn_connect() is completed.
+* @param[in] result  The result
+* @param[in] user_data The user data passed from vpn_connect()
+* @pre vpn_connect() will invoke this callback function.
+* @see vpn_connect()
+*/
+typedef void(*vpn_connect_cb)(vpn_error_e result, void *user_data);
+
+/**
+* @brief Called after vpn_disconnect() is completed.
+* @param[in] result  The result
+* @param[in] user_data The user data passed from vpn_disconnect()
+* @pre vpn_disconnect() will invoke this callback function.
+* @see vpn_disconnect()
+*/
+typedef void(*vpn_disconnect_cb)(vpn_error_e result, void *user_data);
+/**
+* @}
+*/
+
+
+/**
+* @addtogroup CAPI_NETWORK_VPN_MODULE
+* @{
+*/
+
+/**
+* @brief Initializes VPN
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+*/
+int vpn_initialize(void);
+
+/**
+* @brief Deinitializes VPN
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+*/
+int vpn_deinitialize(void);
+
+/**
+* @}
+*/
+
+/**
+* @addtogroup CAPI_NETWORK_VPN_SETTINGS
+* @{
+*/
+
+/**
+* @brief Initializes VPN Settings
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @see vpn_settings_deinit()
+*/
+int vpn_settings_init();
+
+/**
+* @brief De-Initializes VPN Settings
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @pre vpn_settings_init() Must be called before deinit
+* @see vpn_settings_deinit()
+*/
+int vpn_settings_deinit();
+
+/**
+* @brief Sets VPN Specific Settings
+* @param[in] key  The Key for the Settings
+* @param[in] value The Value for the Settings
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @pre vpn_settings_init() must be  called before calling this API
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @see vpn_settings_deinit()
+*/
+int vpn_settings_set_specific(const char *key, const char *value);
+
+/**
+* @brief Sets VPN Type
+* @param[in] type  The VPN Settings Type
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @pre vpn_settings_init() must be  called before calling this API
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @see vpn_settings_deinit() vpn_settings_init()
+*/
+int vpn_settings_set_type(const char *type);
+
+/**
+* @brief Sets VPN Profile Name
+* @param[in] name  The VPN Settings Name
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @pre vpn_settings_init() must be  called before calling this API
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @see vpn_settings_deinit() vpn_settings_init()
+*/
+int vpn_settings_set_name(const char *name);
+
+/**
+* @brief Sets VPN Profile Host (Name or Address)
+* @param[in] host  The VPN Settings Host
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @pre vpn_settings_init() must be  called before calling this API
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @see vpn_settings_deinit() vpn_settings_init()
+*/
+int vpn_settings_set_host(const char *host);
+
+/**
+* @brief Sets VPN Profile Domain
+* @param[in] domain  The VPN Settings Domain
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @pre vpn_settings_init() must be  called before calling this API
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @see vpn_settings_deinit() vpn_settings_init()
+*/
+int vpn_settings_set_domain(const char *domain);
+
+/**
+* @}
+*/
+
+
+/**
+* @addtogroup CAPI_NETWORK_VPN_MANAGER_MODULE
+* @{
+*/
+
+/**
+* @brief Create VPN Profile, asynchronously.
+* @param[in] settings  The VPN related Settings Handler, This can't be NULL.
+* @param[in] callback  The callback function to be called.
+*   This can be NULL if you don't want to get the notification.
+* @param[in] user_data The user data passed to the callback function
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @retval #VPN_ERROR_SECURITY_RESTRICTED  Restricted by security system policy
+* @post vpn_created_cb() will be invoked
+* @see vpn_settings()
+* @see vpn_created_cb()
+* @see vpn_remove()
+*/
+int vpn_create(vpn_created_cb callback, void *user_data);
+
+/**
+* @brief Remove VPN Profile, asynchronously.
+* @param[in] handle  The VPN Connection Identifier.
+* @param[in] callback  The callback function to be called.
+*   This can be NULL if you don't want to get the notification.
+* @param[in] user_data The user data passed to the callback function
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @post vpn_removed_cb() will be invoked
+* @see vpn_removed_cb()
+* @see vpn_create()
+*/
+int vpn_remove(vpn_h handle, vpn_removed_cb callback, void *user_data);
+
+/**
+* @}
+*/
+
+
+/**
+* @addtogroup CAPI_NETWORK_VPN_CONNECTION_MODULE
+* @{
+*/
+
+/**
+* @brief Connect to a VPN Profile, asynchronously.
+* @param[in] settings  The VPN related Settings Handler, This can't be NULL.
+* @param[in] callback  The callback function to be called.
+*   This can be NULL if you don't want to get the notification.
+* @param[in] user_data The user data passed to the callback function
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @retval #VPN_ERROR_ALREADY_EXISTS  Restricted by security system policy
+* @see vpn_connect_cb()
+* @see vpn_disconnect()
+*/
+int vpn_connect(vpn_h handle, vpn_connect_cb callback, void *user_data);
+
+/**
+* @brief Disconnect from VPN Profile, asynchronously.
+* @param[in] handle  The VPN Connection Identifier.
+* @param[in] callback  The callback function to be called.
+*   This can be NULL if you don't want to get the notification.
+* @param[in] user_data The user data passed to the callback function
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_OPERATION_FAILED  Operation failed
+* @retval #VPN_ERROR_NO_CONNECTION  No Connection
+* @see vpn_disconnect_cb()
+* @see vpn_connect()
+*/
+int vpn_disconnect(vpn_h handle, vpn_disconnect_cb callback, void *user_data);
+
+/**
+* @brief Gets the VPN Handle List.
+* @return Valid GList Pointer on success, otherwise NULL.
+* @see vpn_get_vpn_handle()
+*/
+GList *vpn_get_vpn_handle_list(void);
+
+/**
+* @brief Get Specific VPN Handle based on host & domain.
+* @param[in] host  The VPN Host Identifier.
+* @param[in] domain  The VPN Domain Identifier.
+* @param[out] handle The VPN handle that matches host & domain.
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_INVALID_PARAMETER  Operation failed
+* @see vpn_get_vpn_handle_list()
+*/
+int vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle);
+
+/**
+* @brief Get VPN Info (Name)
+* @param[in] handle The VPN handle for the Request
+* @param[out] name  Name of the VPN
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_INVALID_PARAMETER  Operation failed
+*/
+int vpn_get_vpn_info_name(const vpn_h handle, const char **name);
+
+/**
+* @brief Get VPN Info (Type)
+* @param[in] handle The VPN handle for the Request
+* @param[out] type  Type of the VPN
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_INVALID_PARAMETER  Operation failed
+*/
+int vpn_get_vpn_info_type(const vpn_h handle, const char **type);
+
+/**
+* @brief Get VPN Info (Host)
+* @param[in] handle The VPN handle for the Request
+* @param[out] host  Host of the VPN
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_INVALID_PARAMETER  Operation failed
+*/
+int vpn_get_vpn_info_host(const vpn_h handle, const char **host);
+
+/**
+* @brief Get VPN Info (Domain)
+* @param[in] handle The VPN handle for the Request
+* @param[out] domain  Domain of the VPN
+* @return 0 on success, otherwise negative error value.
+* @retval #VPN_ERROR_NONE  Successful
+* @retval #VPN_ERROR_INVALID_OPERATION  Invalid operation
+* @retval #VPN_ERROR_INVALID_PARAMETER  Operation failed
+*/
+int vpn_get_vpn_info_domain(const vpn_h handle, const char **domain);
+
+/**
+* @}
+*/
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TIZEN_NETWORK_VPN_H__ */
diff --git a/packaging/capi-network-vpn.manifest b/packaging/capi-network-vpn.manifest
new file mode 100644 (file)
index 0000000..017d22d
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+ <request>
+    <domain name="_"/>
+ </request>
+</manifest>
diff --git a/packaging/capi-network-vpn.spec b/packaging/capi-network-vpn.spec
new file mode 100644 (file)
index 0000000..07075d2
--- /dev/null
@@ -0,0 +1,70 @@
+Name:       capi-network-vpn
+Summary:    Default VPN Library
+Version:    0.1.0_0
+Release:    1
+Group:      System/Network
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+Source1001:    capi-network-vpn.manifest
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(vconf)
+BuildRequires:  pkgconfig(capi-base-common)
+
+%description
+Library code for CAPI's to interact with the Default VPN functionality on TIZEN platform.
+
+%package devel
+Summary:  Default VPN Development Package
+Group:    System/Network
+Requires: %{name} = %{version}-%{release}
+
+%description devel
+Development Library for Default VPN functionality on TIZEN platform.
+
+%package test
+Summary:    Default VPN Test Package
+Requires:   %{name} = %{version}
+
+%description test
+Test cases for Default VPN Functionality on TIZEN platform.
+
+%prep
+%setup -q
+cp %{SOURCE1001} .
+
+
+%build
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+%cmake . -DFULLVER=%{version} -DMAJORVER=${MAJORVER}
+
+make %{?_smp_mflags}
+
+
+%install
+%make_install
+
+#License
+mkdir -p %{buildroot}%{_datadir}/license
+cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/capi-network-vpn
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+
+%files
+%manifest %{name}.manifest
+%attr(644,-,-) %{_libdir}/libcapi-network-vpn.so.*
+%{_datadir}/license/capi-network-vpn
+
+%files devel
+%manifest %{name}.manifest
+#%{_includedir}/network/*.h
+%{_libdir}/pkgconfig/*.pc
+%{_libdir}/libcapi-network-vpn.so
+
+%files test
+%manifest %{name}.manifest
+%{_libdir}/vpn-capi-test/capi-vpn-test
diff --git a/src/include/common.h b/src/include/common.h
new file mode 100644 (file)
index 0000000..a0c6053
--- /dev/null
@@ -0,0 +1,57 @@
+/*
+* Network VPN library
+*
+* Copyright (c) 2014-2015 Samsung Electronics. 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 __NETWORK_VPN_COMMON_H__
+#define __NETWORK_VPN_COMMON_H__
+
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif /* __cplusplus */
+
+/**
+ * \addtogroup  profile_managing
+ * \{
+*/
+
+/*===========================================================================
+                               CONSTANTS
+=============================================================================*/
+
+
+/*===========================================================================
+                               ENUMS
+=============================================================================*/
+
+
+/*===========================================================================
+                       STRUCTURES AND OTHER TYPEDEFS
+=============================================================================*/
+
+
+/**
+ * \}
+ */
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __NETWORK_VPN_COMMON_H__ */
diff --git a/src/include/vpn-internal.h b/src/include/vpn-internal.h
new file mode 100644 (file)
index 0000000..7669aa0
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+* Network VPN library
+*
+* Copyright (c) 2014-2015 Samsung Electronics. 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 __VPN_CONNECTION_PRIVATE_H__
+#define __VPN_CONNECTION_PRIVATE_H__
+
+#include <dvpnlib-common.h>
+
+#include "vpn.h"
+#include "common.h"
+
+#define LOGI(fmt, arg...) printf("%s:%d %s() " fmt "\n",  \
+                               __FILE__, __LINE__, __func__, ## arg)
+#define LOGW(fmt, arg...) printf("warning %s:%d %s() " fmt "\n", \
+                               __FILE__, __LINE__, __func__, ## arg)
+#define LOGE(fmt, arg...) printf("error %s:%d %s() " fmt "\n", \
+                               __FILE__, __LINE__, __func__, ## arg)
+
+#undef LOG_TAG
+#define LOG_TAG "CAPI_NETWORK_VPN"
+
+#define VPN_INFO       1
+#define VPN_ERROR      2
+#define VPN_WARN       3
+
+#define VPN_LOG(log_level, format, args...) \
+       do { \
+               switch (log_level) { \
+               case VPN_ERROR: \
+                       LOGE(format, ## args); \
+                       break; \
+               case VPN_WARN: \
+                       LOGW(format, ## args); \
+                       break; \
+               default: \
+                       LOGI(format, ## args); \
+               } \
+       } while (0)
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+bool _vpn_init(void);
+bool _vpn_deinit(void);
+
+int _vpn_settings_init();
+int _vpn_settings_deinit();
+int _vpn_settings_set_specific(const char *key, const char *value);
+
+int _vpn_create(vpn_created_cb callback, void *user_data);
+int _vpn_remove(vpn_h handle, vpn_removed_cb callback, void *user_data);
+
+int _vpn_connect(vpn_h handle, vpn_removed_cb callback, void *user_data);
+int _vpn_disconnect(vpn_h handle);
+
+GList *_vpn_get_vpn_handle_list(void);
+int _vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle);
+int _vpn_get_vpn_info_name(vpn_h handle, const char **name);
+int _vpn_get_vpn_info_type(vpn_h handle, const char **type);
+int _vpn_get_vpn_info_host(vpn_h handle, const char **host);
+int _vpn_get_vpn_info_domain(vpn_h handle, const char **domain);
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif
diff --git a/src/vpn-internal.c b/src/vpn-internal.c
new file mode 100644 (file)
index 0000000..63293ad
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+* Network VPN library
+*
+* Copyright (c) 2014-2015 Samsung Electronics. 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 <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <glib.h>
+
+#include <dvpnlib-vpn.h>
+#include <dvpnlib-vpn-manager.h>
+#include <dvpnlib-vpn-connection.h>
+
+#include "vpn-internal.h"
+
+struct _vpn_cb_s {
+       vpn_created_cb create_cb;
+       void *create_user_data;
+       vpn_removed_cb remove_cb;
+       void *remove_user_data;
+       vpn_connect_cb connect_cb;
+       void *connect_user_data;
+       vpn_disconnect_cb disconnect_cb;
+       void *disconnect_user_data;
+};
+
+static struct _vpn_cb_s vpn_callbacks = {0,};
+static GHashTable *settings_hash;
+
+/*
+ * Utility Functions
+ */
+
+static void print_key_value_string(gpointer key,
+                               gpointer value, gpointer user_data)
+{
+       if (user_data) {
+               VPN_LOG(VPN_INFO, " %s[%s]=%s",
+                       (gchar *)user_data, (gchar *)key, (gchar *)value);
+               return;
+       }
+       VPN_LOG(VPN_INFO, " %s=%s", (gchar *)key, (gchar *)value);
+}
+
+vpn_error_e _dvpnlib_error2vpn_error(enum dvpnlib_err err_type)
+{
+       switch (err_type) {
+       case DVPNLIB_ERR_NONE:
+               return VPN_ERROR_NONE;
+       case DVPNLIB_ERR_ALREADY_EXISTS:
+               return VPN_ERROR_INVALID_OPERATION;
+       case DVPNLIB_ERR_NOT_REGISTERED:
+               return VPN_ERROR_INVALID_OPERATION;
+       case DVPNLIB_ERR_NOT_CONNECTED:
+               return VPN_ERROR_NO_CONNECTION;
+       case DVPNLIB_ERR_ALREADY_CONNECTED:
+               return VPN_ERROR_ALREADY_EXISTS;
+       case DVPNLIB_ERR_IN_PROGRESS:
+               return VPN_ERROR_NOW_IN_PROGRESS;
+       case DVPNLIB_ERR_OPERATION_ABORTED:
+               return VPN_ERROR_OPERATION_ABORTED;
+       case DVPNLIB_ERR_OPERATION_TIMEOUT:
+       case DVPNLIB_ERR_TIMEOUT:
+               return VPN_ERROR_NO_REPLY;
+       default:
+               return VPN_ERROR_OPERATION_FAILED;
+       }
+}
+
+/*
+ *Functions Actually use Default VPN Library
+ */
+
+bool _vpn_init(void)
+{
+       int rv;
+
+       rv = dvpnlib_vpn_init();
+
+       if (rv != 0)
+               return false;
+
+       return true;
+}
+
+bool _vpn_deinit(void)
+{
+       dvpnlib_vpn_deinit();
+       return true;
+}
+
+int _vpn_settings_init()
+{
+       if (settings_hash != NULL) {
+               VPN_LOG(VPN_INFO,
+                       "Settings Hash: %p Already present!", settings_hash);
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       settings_hash = g_hash_table_new_full(
+                               g_str_hash, g_str_equal,
+                               g_free, g_free);
+       VPN_LOG(VPN_INFO, "Settings Hash: %p", settings_hash);
+
+       return VPN_ERROR_NONE;
+}
+
+int _vpn_settings_deinit()
+{
+       if (settings_hash == NULL)
+               return VPN_ERROR_INVALID_OPERATION;
+
+       VPN_LOG(VPN_INFO, "Settings Hash: %p Destroyed", settings_hash);
+       g_hash_table_destroy(settings_hash);
+       settings_hash = NULL;
+
+       return VPN_ERROR_NONE;
+}
+
+int _vpn_settings_set_specific(const char *key, const char *value)
+{
+       VPN_LOG(VPN_INFO,
+               "Settings Hash: %p {%s=%s}", settings_hash, key, value);
+
+       if (key == NULL)
+               return VPN_ERROR_INVALID_PARAMETER;
+
+       if (g_hash_table_contains(settings_hash, key)) {
+               if (value == NULL) {
+                       VPN_LOG(VPN_INFO, "Settings Hash: %p {%s=%s} (Removed)",
+                               settings_hash, key,
+                               (gchar *)g_hash_table_lookup(
+                                       settings_hash, key));
+                       g_hash_table_remove(settings_hash, key);
+                       return VPN_ERROR_NONE;
+               }
+       }
+
+       g_hash_table_replace(settings_hash,
+                       (gpointer)g_strdup(key),
+                       (gpointer)g_strdup(value));
+
+       return VPN_ERROR_NONE;
+}
+
+/*
+ *Callbacks
+ */
+static void __vpn_create_cb(vpn_error_e result)
+{
+       if (vpn_callbacks.create_cb)
+               vpn_callbacks.create_cb(result,
+                               vpn_callbacks.create_user_data);
+
+       vpn_callbacks.create_cb = NULL;
+       vpn_callbacks.create_user_data = NULL;
+}
+
+static void vpn_manager_create_cb(enum dvpnlib_err result,
+                                                       void *user_data)
+{
+       VPN_LOG(VPN_INFO, "callback: %d Settings: %p\n", result, user_data);
+
+       __vpn_create_cb(_dvpnlib_error2vpn_error(result));
+}
+
+static void __vpn_remove_cb(vpn_error_e result)
+{
+       if (vpn_callbacks.create_cb)
+               vpn_callbacks.create_cb(result,
+                               vpn_callbacks.create_user_data);
+
+       vpn_callbacks.remove_cb = NULL;
+       vpn_callbacks.remove_user_data = NULL;
+}
+
+static void vpn_manager_remove_cb(enum dvpnlib_err result,
+                                                       void *user_data)
+{
+       VPN_LOG(VPN_INFO, "callback: %d Settings: %p\n", result, user_data);
+
+       __vpn_remove_cb(_dvpnlib_error2vpn_error(result));
+}
+
+int _vpn_create(vpn_created_cb callback, void *user_data)
+{
+       enum dvpnlib_err err = DVPNLIB_ERR_NONE;
+       if (!settings_hash)
+               return VPN_ERROR_INVALID_OPERATION;
+
+       VPN_LOG(VPN_INFO, "");
+
+       vpn_callbacks.create_cb = callback;
+       vpn_callbacks.create_user_data = user_data;
+
+       g_hash_table_foreach(settings_hash,
+               print_key_value_string, "VPNSettings");
+
+       err = dvpnlib_vpn_manager_create(settings_hash,
+               vpn_manager_create_cb, NULL);
+       if (err != DVPNLIB_ERR_NONE)
+               return _dvpnlib_error2vpn_error(err);
+
+       return VPN_ERROR_NONE;
+
+}
+
+int _vpn_remove(vpn_h handle, vpn_removed_cb callback, void *user_data)
+{
+       enum dvpnlib_err err = DVPNLIB_ERR_NONE;
+
+       VPN_LOG(VPN_INFO, "");
+
+       vpn_callbacks.remove_cb = callback;
+       vpn_callbacks.remove_user_data = user_data;
+
+       GList *connections = vpn_get_connections();
+       if (NULL == g_list_find(connections, handle)) {
+               VPN_LOG(VPN_ERROR, "No Connections with the %p Handle", handle);
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       const char *path = vpn_connection_get_path(handle);
+       err = dvpnlib_vpn_manager_remove(path, vpn_manager_remove_cb, NULL);
+       if (err != DVPNLIB_ERR_NONE)
+               return _dvpnlib_error2vpn_error(err);
+
+       return VPN_ERROR_NONE;
+}
+
+/*
+ *Connect Disconnect Callbacks
+ */
+
+static void __vpn_connect_cb(vpn_error_e result)
+{
+       if (vpn_callbacks.connect_cb)
+               vpn_callbacks.connect_cb(result,
+                               vpn_callbacks.connect_user_data);
+
+       vpn_callbacks.connect_cb = NULL;
+       vpn_callbacks.connect_user_data = NULL;
+}
+
+static void vpn_manager_connect_cb(enum dvpnlib_err result,
+                                                       void *user_data)
+{
+       VPN_LOG(VPN_INFO, "callback: %d Settings: %p\n", result, user_data);
+
+       __vpn_connect_cb(_dvpnlib_error2vpn_error(result));
+}
+
+/*
+ *Connect to VPN Profile
+ */
+
+int _vpn_connect(vpn_h handle, vpn_removed_cb callback, void *user_data)
+{
+       enum dvpnlib_err err = DVPNLIB_ERR_NONE;
+
+       VPN_LOG(VPN_INFO, "");
+
+       vpn_callbacks.connect_cb = callback;
+       vpn_callbacks.connect_user_data = user_data;
+
+       GList *connections = vpn_get_connections();
+       if (NULL == g_list_find(connections, handle)) {
+               VPN_LOG(VPN_ERROR, "No Connections with the %p Handle", handle);
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       enum vpn_connection_state state = vpn_connection_get_state(handle);
+       if (state == VPN_CONN_STATE_READY)
+               return VPN_ERROR_ALREADY_EXISTS;
+
+       err = vpn_connection_connect(handle, vpn_manager_connect_cb, NULL);
+       if (err != DVPNLIB_ERR_NONE)
+               return _dvpnlib_error2vpn_error(err);
+
+       return VPN_ERROR_NONE;
+}
+
+/*
+ *Disconnect from VPN Profile
+ */
+
+int _vpn_disconnect(vpn_h handle)
+{
+       enum dvpnlib_err err = DVPNLIB_ERR_NONE;
+
+       VPN_LOG(VPN_INFO, "");
+
+       GList *connections = vpn_get_connections();
+       if (NULL == g_list_find(connections, handle)) {
+               VPN_LOG(VPN_ERROR, "No Connections with the %p Handle", handle);
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       enum vpn_connection_state state = vpn_connection_get_state(handle);
+       if (state != VPN_CONN_STATE_READY)
+               return VPN_ERROR_NO_CONNECTION;
+
+       err = vpn_connection_disconnect(handle);
+       if (err != DVPNLIB_ERR_NONE)
+               return _dvpnlib_error2vpn_error(err);
+
+       return VPN_ERROR_NONE;
+}
+
+/*
+ *Gets the VPN Handles List from VPN Profile
+ */
+GList *_vpn_get_vpn_handle_list(void)
+{
+       return vpn_get_connections();
+}
+
+/*
+ * Get a specific VPN Handle based on host & domain parameters
+ */
+int _vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle)
+{
+       VPN_LOG(VPN_INFO, "");
+
+       struct vpn_connection *connection = vpn_get_connection(host, domain);
+
+       if (connection == NULL) {
+               VPN_LOG(VPN_ERROR, "host=%s domain=%s", host, domain);
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       *handle = connection;
+       return VPN_ERROR_NONE;
+}
+
+/*
+ * Get VPN Info (Name) from VPN Handle
+ */
+int _vpn_get_vpn_info_name(vpn_h handle, const char **name)
+{
+       VPN_LOG(VPN_INFO, "");
+
+       GList *connections = vpn_get_connections();
+       if (NULL == g_list_find(connections, handle)) {
+               VPN_LOG(VPN_ERROR, "No Connections with the %p Handle", handle);
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       *name = vpn_connection_get_name(handle);
+       return VPN_ERROR_NONE;
+}
+
+/*
+ * Get VPN Info (Type) from VPN Handle
+ */
+int _vpn_get_vpn_info_type(vpn_h handle, const char **type)
+{
+       VPN_LOG(VPN_INFO, "");
+
+       GList *connections = vpn_get_connections();
+       if (NULL == g_list_find(connections, handle)) {
+               VPN_LOG(VPN_ERROR, "No Connections with the %p Handle", handle);
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       *type = vpn_connection_get_type(handle);
+       return VPN_ERROR_NONE;
+}
+
+/*
+ * Get VPN Info (Host) from VPN Handle
+ */
+int _vpn_get_vpn_info_host(vpn_h handle, const char **host)
+{
+       VPN_LOG(VPN_INFO, "");
+
+       GList *connections = vpn_get_connections();
+       if (NULL == g_list_find(connections, handle)) {
+               VPN_LOG(VPN_ERROR, "No Connections with the %p Handle", handle);
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       *host = vpn_connection_get_host(handle);
+       return VPN_ERROR_NONE;
+}
+
+/*
+ * Get VPN Info (Domain) from VPN Handle
+ */
+int _vpn_get_vpn_info_domain(vpn_h handle, const char **domain)
+{
+       VPN_LOG(VPN_INFO, "");
+
+       GList *connections = vpn_get_connections();
+       if (NULL == g_list_find(connections, handle)) {
+               VPN_LOG(VPN_ERROR, "No Connections with the %p Handle", handle);
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       *domain = vpn_connection_get_domain(handle);
+       return VPN_ERROR_NONE;
+}
diff --git a/src/vpn.c b/src/vpn.c
new file mode 100644 (file)
index 0000000..ec45d53
--- /dev/null
+++ b/src/vpn.c
@@ -0,0 +1,388 @@
+/*
+* Network VPN library
+*
+* Copyright (c) 2014-2015 Samsung Electronics. 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 <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <vconf/vconf.h>
+
+#include "vpn-internal.h"
+
+static bool is_init = false;
+
+EXPORT_API int vpn_initialize(void)
+{
+       if (is_init) {
+               VPN_LOG(VPN_ERROR, "Already initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (_vpn_init() == false) {
+               VPN_LOG(VPN_ERROR, "Init failed!\n");
+               return VPN_ERROR_OPERATION_FAILED;
+       }
+
+       is_init = true;
+
+       VPN_LOG(VPN_INFO, "VPN successfully initialized!\n");
+
+       return VPN_ERROR_NONE;
+}
+
+EXPORT_API int vpn_deinitialize(void)
+{
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (_vpn_deinit() == false) {
+               VPN_LOG(VPN_ERROR, "Deinit failed!\n");
+               return VPN_ERROR_OPERATION_FAILED;
+       }
+
+       is_init = false;
+       VPN_LOG(VPN_INFO, "VPN successfully de-initialized!\n");
+
+       return VPN_ERROR_NONE;
+}
+
+/* Settings API's */
+EXPORT_API int vpn_settings_init()
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       rv = _vpn_settings_init();
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Settings Deinit failed.\n");
+
+       return rv;
+}
+
+EXPORT_API int vpn_settings_deinit()
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       rv = _vpn_settings_deinit();
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Settings Deinit failed.\n");
+
+       return rv;
+}
+
+EXPORT_API int vpn_settings_set_specific(const char *key, const char *value)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       rv = _vpn_settings_set_specific(key, value);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Settings Deinit failed.\n");
+
+       return rv;
+}
+
+
+EXPORT_API int vpn_settings_set_type(const char *type)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       rv = _vpn_settings_set_specific("Type", type);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Settings Deinit failed.\n");
+
+       return rv;
+}
+
+EXPORT_API int vpn_settings_set_name(const char *name)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       rv = _vpn_settings_set_specific("Name", name);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Settings Deinit failed.\n");
+
+       return rv;
+}
+
+EXPORT_API int vpn_settings_set_host(const char *host)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       rv = _vpn_settings_set_specific("Host", host);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Settings Deinit failed.\n");
+
+       return rv;
+}
+
+EXPORT_API int vpn_settings_set_domain(const char *domain)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       rv = _vpn_settings_set_specific("Domain", domain);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Settings Deinit failed.\n");
+
+       return rv;
+}
+
+EXPORT_API int vpn_create(vpn_created_cb callback, void *user_data)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       rv = _vpn_create(callback, user_data);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Create failed.\n");
+
+       return rv;
+}
+
+EXPORT_API
+int vpn_remove(vpn_h handle, vpn_removed_cb callback, void *user_data)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (handle == NULL) {
+               VPN_LOG(VPN_ERROR, "VPN Handle is NULL\n");
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       rv = _vpn_remove(handle, callback, user_data);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Remove failed.\n");
+
+       return rv;
+}
+
+EXPORT_API
+int vpn_connect(vpn_h handle, vpn_connect_cb callback, void *user_data)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (handle == NULL) {
+               VPN_LOG(VPN_ERROR, "VPN Handle is NULL\n");
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       rv = _vpn_connect(handle, callback, user_data);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Remove failed.\n");
+
+       return rv;
+}
+
+EXPORT_API
+int vpn_disconnect(vpn_h handle, vpn_disconnect_cb callback, void *user_data)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (handle == NULL) {
+               VPN_LOG(VPN_ERROR, "VPN Handle is NULL\n");
+               return VPN_ERROR_INVALID_PARAMETER;
+       }
+
+       rv = _vpn_disconnect(handle);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Remove failed.\n");
+
+       return rv;
+}
+
+EXPORT_API
+GList *vpn_get_vpn_handle_list(void)
+{
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return NULL;
+       }
+
+       return _vpn_get_vpn_handle_list();
+}
+
+EXPORT_API
+int vpn_get_vpn_handle(const char *host, const char *domain, vpn_h *handle)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (host == NULL || domain == NULL || handle == NULL)
+               return VPN_ERROR_INVALID_PARAMETER;
+
+       rv = _vpn_get_vpn_handle(host, domain, handle);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Get Handle failed.\n");
+
+       return rv;
+}
+
+EXPORT_API
+int vpn_get_vpn_info_name(const vpn_h handle, const char **name)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (handle == NULL || name == NULL)
+               return VPN_ERROR_INVALID_PARAMETER;
+
+       rv = _vpn_get_vpn_info_name(handle, name);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Get Info (Name) failed.\n");
+
+       return rv;
+}
+
+EXPORT_API
+int vpn_get_vpn_info_type(const vpn_h handle, const char **type)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (handle == NULL || type == NULL)
+               return VPN_ERROR_INVALID_PARAMETER;
+
+       rv = _vpn_get_vpn_info_type(handle, type);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Get Info (Type) failed.\n");
+
+       return rv;
+}
+
+EXPORT_API
+int vpn_get_vpn_info_host(const vpn_h handle, const char **host)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (handle == NULL || host == NULL)
+               return VPN_ERROR_INVALID_PARAMETER;
+
+       rv = _vpn_get_vpn_info_host(handle, host);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Get Info (Host) failed.\n");
+
+       return rv;
+}
+
+EXPORT_API
+int vpn_get_vpn_info_domain(const vpn_h handle, const char **domain)
+{
+       int rv;
+
+       if (is_init == false) {
+               VPN_LOG(VPN_ERROR, "Not initialized\n");
+               return VPN_ERROR_INVALID_OPERATION;
+       }
+
+       if (handle == NULL || domain == NULL)
+               return VPN_ERROR_INVALID_PARAMETER;
+
+       rv = _vpn_get_vpn_info_domain(handle, domain);
+
+       if (rv != VPN_ERROR_NONE)
+               VPN_LOG(VPN_ERROR, "Error!! VPN Get Info (Domain) failed.\n");
+
+       return rv;
+}
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..1ff2267
--- /dev/null
@@ -0,0 +1,20 @@
+SET(fw_test "capi-vpn-test")
+
+SET(dependents "capi-base-common glib-2.0")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_test} REQUIRED ${dependents})
+FOREACH(flag ${${fw_test}_CFLAGS})
+    SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall")
+
+aux_source_directory(. sources)
+FOREACH(src ${sources})
+    GET_FILENAME_COMPONENT(src_name ${src} NAME_WE)
+    MESSAGE("${fw_test}")
+    ADD_EXECUTABLE(${fw_test} ${src})
+    TARGET_LINK_LIBRARIES(${fw_test} ${fw_name} ${${fw_test}_LDFLAGS})
+    INSTALL(TARGETS ${fw_test} DESTINATION ${LIB_INSTALL_DIR}/vpn-capi-test/)
+ENDFOREACH()
diff --git a/test/vpn_test.c b/test/vpn_test.c
new file mode 100644 (file)
index 0000000..3ee6009
--- /dev/null
@@ -0,0 +1,456 @@
+/*
+ * Copyright (c) 2014-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 <glib.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/un.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <assert.h>
+#include <vpn.h>
+#include <tizen_error.h>
+
+gboolean test_thread(GIOChannel *source,
+                       GIOCondition condition,
+                       gpointer data);
+
+static const char *__test_convert_error_to_string(vpn_error_e err_type)
+{
+       switch (err_type) {
+       case VPN_ERROR_NONE:
+               return "NONE";
+       case VPN_ERROR_INVALID_PARAMETER:
+               return "INVALID_PARAMETER";
+       case VPN_ERROR_OUT_OF_MEMORY:
+               return "OUT_OF_MEMORY";
+       case VPN_ERROR_INVALID_OPERATION:
+               return "INVALID_OPERATION";
+       case VPN_ERROR_ADDRESS_FAMILY_NOT_SUPPORTED:
+               return "ADDRESS_FAMILY_NOT_SUPPORTED";
+       case VPN_ERROR_OPERATION_FAILED:
+               return "OPERATION_FAILED";
+       case VPN_ERROR_NO_CONNECTION:
+               return "NO_CONNECTION";
+       case VPN_ERROR_NOW_IN_PROGRESS:
+               return "NOW_IN_PROGRESS";
+       case VPN_ERROR_ALREADY_EXISTS:
+               return "ALREADY_EXISTS";
+       case VPN_ERROR_OPERATION_ABORTED:
+               return "OPERATION_ABORTED";
+       case VPN_ERROR_DHCP_FAILED:
+               return "DHCP_FAILED";
+       case VPN_ERROR_INVALID_KEY:
+               return "INVALID_KEY";
+       case VPN_ERROR_NO_REPLY:
+               return "NO_REPLY";
+       case VPN_ERROR_SECURITY_RESTRICTED:
+               return "SECURITY_RESTRICTED";
+       }
+
+       return "UNKNOWN";
+}
+
+static void __test_created_callback(vpn_error_e result,
+                               void *user_data)
+{
+       if (result == VPN_ERROR_NONE)
+               printf("VPN Create Succeeded\n");
+       else
+               printf("VPN Create Failed! error : %s",
+                               __test_convert_error_to_string(result));
+}
+
+static void __test_removed_callback(vpn_error_e result,
+                               void *user_data)
+{
+       if (result == VPN_ERROR_NONE)
+               printf("VPN Remove Succeeded\n");
+       else
+               printf("VPN Remove Failed! error : %s",
+                               __test_convert_error_to_string(result));
+}
+
+static void __test_connect_callback(vpn_error_e result,
+                               void *user_data)
+{
+       if (result == VPN_ERROR_NONE)
+               printf("VPN Connect Succeeded\n");
+       else
+               printf("VPN Connect Failed! error : %s",
+                               __test_convert_error_to_string(result));
+}
+
+static void __test_disconnect_callback(vpn_error_e result,
+                               void *user_data)
+{
+       if (result == VPN_ERROR_NONE)
+               printf("VPN Disconnect Succeeded\n");
+       else
+               printf("VPN Disconnect Failed! error : %s",
+                               __test_convert_error_to_string(result));
+}
+
+static void _test_get_vpn_handle(vpn_h *handle_ptr)
+{
+       assert(handle_ptr != NULL);
+
+       char host_str[128] = { 0 };
+       char domain_str[128] = { 0 };
+       const char *name = NULL;
+       const char *type = NULL;
+       const char *host = NULL;
+       const char *domain = NULL;
+
+       GList *iter;
+       GList *handles = vpn_get_vpn_handle_list();
+       for (iter = handles; iter != NULL; iter = iter->next) {
+               printf("\n Handle = %p\n", iter->data);
+               vpn_get_vpn_info_name(iter->data, &name);
+               vpn_get_vpn_info_type(iter->data, &type);
+               vpn_get_vpn_info_host(iter->data, &host);
+               vpn_get_vpn_info_domain(iter->data, &domain);
+               printf(" Name[%p] - %s\n", iter->data, name);
+               printf(" Type[%p] - %s\n", iter->data, type);
+               printf(" Host[%p] - %s\n", iter->data, host);
+               printf(" Domain[%p] - %s\n", iter->data, domain);
+       }
+
+       printf("==================================\n");
+       printf(" Please ENTER Host: ");
+       if (scanf(" %s", host_str) < 0)
+               printf("Error in Reading Host String\n");
+
+       printf(" Please ENTER Domain: ");
+       if (scanf(" %s", domain_str) < 0)
+               printf("Error in Reading Domain String\n");
+
+       vpn_get_vpn_handle(host_str, domain_str, handle_ptr);
+}
+
+static void _test_get_user_input(char *buf, char *what)
+{
+       printf("Please ENTER %s:", what);
+       if (scanf(" %[^\n]s", buf) < 0) {
+               printf("Error in Reading the data to Buffer\n");
+       }
+}
+
+int test_vpn_init(void)
+{
+       int rv = vpn_initialize();
+
+       if (rv == VPN_ERROR_NONE) {
+               printf("Register Callbacks if Initialize is Successful\n");
+       } else {
+               printf("VPN init failed [%s]\n",
+                       __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("VPN init succeeded\n");
+       return 1;
+}
+
+int test_vpn_deinit(void)
+{
+       int rv = vpn_deinitialize();
+
+       if (rv != VPN_ERROR_NONE) {
+               printf("VPN init failed [%s]\n",
+                       __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("VPN deinit succeeded\n");
+       return 1;
+}
+
+int test_vpn_settings_init(void)
+{
+       int rv = 0;
+
+       rv = vpn_settings_init();
+
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to Initialize Settings [%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Success Creating Settings API's\n");
+
+       return 1;
+}
+
+int test_vpn_settings_add(void)
+{
+       int rv = 0;
+       char buf[100];
+
+       _test_get_user_input(&buf[0], "Type");
+       rv = vpn_settings_set_type(&buf[0]);
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to VPN Settings Type[%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       _test_get_user_input(&buf[0], "Name");
+       rv = vpn_settings_set_name(&buf[0]);
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to VPN Settings Name[%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       _test_get_user_input(&buf[0], "Host");
+       rv = vpn_settings_set_host(&buf[0]);
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to VPN Settings Host[%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       _test_get_user_input(&buf[0], "Domain");
+       rv = vpn_settings_set_domain(&buf[0]);
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to VPN Settings Domain[%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Success Creating Settings API's\n");
+
+       return 1;
+}
+
+int test_vpn_settings_deinit(void)
+{
+       int rv = 0;
+
+       rv = vpn_settings_deinit();
+
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to Deinitialize Settings [%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Success Deleting Settings API's\n");
+
+       return 1;
+}
+
+int test_vpn_settings_set_specific(void)
+{
+       int rv = 0;
+       char key[100];
+       char value[200];
+
+       _test_get_user_input(&key[0], "Key");
+       _test_get_user_input(&value[0], "Value");
+       rv = vpn_settings_set_specific(&key[0], &value[0]);
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to Set Specific VPN Settings %s[%s]\n",
+                               key, __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Success in VPN Settings Add %s=%s\n", key, value);
+
+       return 1;
+}
+
+int test_vpn_create(void)
+{
+       int rv = 0;
+
+       rv = vpn_create(__test_created_callback, NULL);
+
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to Create VPN Profile [%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Success to Create VPN Profile\n");
+
+       return 1;
+}
+
+int test_vpn_remove(void)
+{
+       int rv = 0;
+
+       /*TODO: Get the List of VPN Profiles Identifiers
+        * Prompt user to which one to be deleted */
+
+       rv = vpn_remove(NULL, __test_removed_callback, NULL);
+
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to Remove VPN Profile [%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Success to Remove VPN Profile\n");
+
+       return 1;
+}
+
+int test_vpn_connect(void)
+{
+       int rv = 0;
+       vpn_h handle = NULL;
+
+       _test_get_vpn_handle(&handle);
+
+       rv = vpn_connect(handle, __test_connect_callback, NULL);
+
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to Connect to VPN Profile [%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Success to Connect VPN Profile\n");
+
+       return 1;
+}
+
+int test_vpn_disconnect(void)
+{
+       int rv = 0;
+       vpn_h handle = NULL;
+
+       _test_get_vpn_handle(&handle);
+
+       rv = vpn_disconnect(handle, __test_disconnect_callback, NULL);
+
+       if (rv != VPN_ERROR_NONE) {
+               printf("Fail to Disconnect from VPN Profile [%s]\n",
+                               __test_convert_error_to_string(rv));
+               return -1;
+       }
+
+       printf("Success to Disconnect VPN Profile\n");
+
+       return 1;
+}
+
+int main(int argc, char **argv)
+{
+       GMainLoop *mainloop;
+       mainloop = g_main_loop_new(NULL, FALSE);
+
+       GIOChannel *channel = g_io_channel_unix_new(0);
+       g_io_add_watch(channel, (G_IO_IN|G_IO_ERR|G_IO_HUP|G_IO_NVAL),
+                       test_thread, NULL);
+
+       printf("Test Thread created...\n");
+
+       g_main_loop_run(mainloop);
+
+       return 0;
+}
+
+gboolean test_thread(GIOChannel *source, GIOCondition condition, gpointer data)
+{
+       int rv;
+       char a[10];
+
+       printf("Event received from stdin\n");
+
+       rv = read(0, a, 10);
+
+       if (rv <= 0 || a[0] == '0') {
+               rv = vpn_deinitialize();
+
+               if (rv != VPN_ERROR_NONE)
+                       printf("Fail to deinitialize.\n");
+
+               exit(1);
+       }
+
+       if (a[0] == '\n' || a[0] == '\r') {
+               printf("\n\n Network Connection API Test App\n\n");
+               printf("Options..\n");
+               printf("1\t- VPN init and set callbacks\n");
+               printf("2\t- VPN deinit(unset callbacks automatically)\n");
+               printf("3\t- VPN Settings Initialize - Initialize Settings for Creating a VPN profile\n");
+               printf("4\t- VPN Settings Delete - Delete Settings VPN profile\n");
+               printf("5\t- VPN Settings Set Specific - Allows to add a specific setting\n");
+               printf("6\t- VPN Settings Add - Add Type,Host,Name,Domain settings\n");
+               printf("7\t- VPN Create - Creates the VPN profile\n");
+               printf("8\t- VPN Remove - Removes the VPN profile\n");
+               printf("9\t- VPN Connect - Connect the VPN profile\n");
+               printf("a\t- VPN Disconnect - Disconnect the VPN profile\n");
+               printf("0\t- Exit\n");
+
+               printf("ENTER  - Show options menu.......\n");
+       }
+
+       switch (a[0]) {
+       case '1':
+               rv = test_vpn_init();
+               break;
+       case '2':
+               rv = test_vpn_deinit();
+               break;
+       case '3':
+               rv = test_vpn_settings_init();
+               break;
+       case '4':
+               rv = test_vpn_settings_deinit();
+               break;
+       case '5':
+               rv = test_vpn_settings_set_specific();
+               break;
+       case '6':
+               rv = test_vpn_settings_add();
+               break;
+       case '7':
+               rv = test_vpn_create();
+               break;
+       case '8':
+               rv = test_vpn_remove();
+               break;
+       case '9':
+               rv = test_vpn_connect();
+               break;
+       case 'a':
+               rv = test_vpn_disconnect();
+               break;
+       default:
+               break;
+       }
+
+       if (rv == 1)
+               printf("Operation succeeded!\n");
+       else
+               printf("Operation failed!\n");
+
+       return TRUE;
+}
+
+