--- /dev/null
+Sushil Kumar Yadav <sushil.ky@samsung.com>
+Sushil <sushil.iitk@gmail.com>
--- /dev/null
+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)
--- /dev/null
+Ver 0.1:
+ Added Default VPN CAPI Code
+
--- /dev/null
+
+ 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.
--- /dev/null
+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.
--- /dev/null
+# 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}
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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
--- /dev/null
+#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;
+}
--- /dev/null
+#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(¶meters, &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;
+}
+
--- /dev/null
+#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();
+}
--- /dev/null
+#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;
+}
--- /dev/null
+/*
+ * 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__ */
--- /dev/null
+<manifest>
+ <request>
+ <domain name="_"/>
+ </request>
+</manifest>
--- /dev/null
+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
--- /dev/null
+/*
+* 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__ */
--- /dev/null
+/*
+* 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
--- /dev/null
+/*
+* 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;
+}
--- /dev/null
+/*
+* 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;
+}
+
--- /dev/null
+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()
--- /dev/null
+/*
+ * 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;
+}
+
+