Source code upload 2.0alpha master 2.0_alpha submit/master/20120920.151033
authorSeungyoun Ju <sy39.ju@samsung.com>
Tue, 21 Aug 2012 09:21:17 +0000 (18:21 +0900)
committerSeungyoun Ju <sy39.ju@samsung.com>
Tue, 21 Aug 2012 09:21:17 +0000 (18:21 +0900)
18 files changed:
CMakeLists.txt [new file with mode: 0644]
capi-network-tethering.pc.in [new file with mode: 0644]
debian/capi-network-tethering-dev.install [new file with mode: 0644]
debian/capi-network-tethering.install [new file with mode: 0644]
debian/capi-network-tethering.postinst [new file with mode: 0644]
debian/changelog [new file with mode: 0644]
debian/compat [new file with mode: 0644]
debian/control [new file with mode: 0644]
debian/rules [new file with mode: 0755]
include/marshal.list [new file with mode: 0644]
include/tethering.h [new file with mode: 0644]
include/tethering.xml [new file with mode: 0644]
include/tethering_private.h [new file with mode: 0644]
packaging/capi-network-tethering.spec [new file with mode: 0644]
src/tethering.c [new file with mode: 0644]
src/tethering_client.c [new file with mode: 0644]
test/CMakeLists.txt [new file with mode: 0644]
test/tethering_test.c [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7381298
--- /dev/null
@@ -0,0 +1,100 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+SET(fw_name "capi-network-tethering")
+
+PROJECT(${fw_name})
+
+SET(CMAKE_INSTALL_PREFIX /usr)
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(INC_DIR include)
+INCLUDE_DIRECTORIES(${INC_DIR})
+
+SET(dependents "dlog glib-2.0 capi-base-common dbus-glib-1 vconf")
+
+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")
+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=/usr/lib")
+
+FIND_PROGRAM(MARSHALTOOL NAMES glib-genmarshal)
+EXEC_PROGRAM("${MARSHALTOOL}" ARGS "--prefix=marshal ${INC_DIR}/marshal.list --header > ${INC_DIR}/marshal.h")
+EXEC_PROGRAM("${MARSHALTOOL}" ARGS "--prefix=marshal ${INC_DIR}/marshal.list --body > src/marshal.c")
+
+FIND_PROGRAM(DBUS_BINDING_TOOL NAMES dbus-binding-tool)
+EXEC_PROGRAM("${DBUS_BINDING_TOOL}" ARGS "--prefix=mobileap ${INC_DIR}/tethering.xml --mode=glib-client --output=${INC_DIR}/tethering-client-stub.h")
+
+aux_source_directory(src SOURCES)
+ADD_LIBRARY(${fw_name} SHARED ${SOURCES})
+
+TARGET_LINK_LIBRARIES(${fw_name} ${${fw_name}_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${fw_name} PROPERTIES SOVERSION 0.1.0)
+
+INSTALL(TARGETS ${fw_name} DESTINATION lib)
+INSTALL(
+        DIRECTORY ${INC_DIR}/ DESTINATION include/network
+        FILES_MATCHING
+        PATTERN "*_private.h" EXCLUDE
+        PATTERN "marshal.h" EXCLUDE
+        PATTERN "tethering-client-stub.h" EXCLUDE
+        PATTERN "${INC_DIR}/*.h"
+        )
+
+SET(PC_NAME ${fw_name})
+SET(PC_REQUIRED ${dependents})
+SET(PC_LDFLAGS -l${fw_name})
+SET(PC_CFLAGS -I\${includedir}/network)
+
+CONFIGURE_FILE(
+    capi-network-tethering.pc.in
+    ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc
+    @ONLY
+)
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/${fw_name}.pc DESTINATION lib/pkgconfig)
+
+ADD_SUBDIRECTORY(test)
+
+IF(UNIX)
+
+ADD_CUSTOM_TARGET (distclean @echo cleaning for source distribution)
+ADD_CUSTOM_COMMAND(
+        DEPENDS clean
+        COMMENT "distribution clean"
+        COMMAND find
+        ARGS    .
+        -not -name config.cmake -and \(
+        -name tester.c -or
+        -name Testing -or
+        -name CMakeFiles -or
+        -name cmake.depends -or
+        -name cmake.check_depends -or
+        -name CMakeCache.txt -or
+        -name cmake.check_cache -or
+        -name *.cmake -or
+        -name Makefile -or
+        -name core -or
+        -name core.* -or
+        -name gmon.out -or
+        -name install_manifest.txt -or
+        -name *.pc -or
+        -name *~ \)
+        | grep -v TC | xargs rm -rf
+        TARGET  distclean
+        VERBATIM
+)
+
+ENDIF(UNIX)
+
diff --git a/capi-network-tethering.pc.in b/capi-network-tethering.pc.in
new file mode 100644 (file)
index 0000000..fc8c18b
--- /dev/null
@@ -0,0 +1,14 @@
+# 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} @PC_CFLAGS@
+
diff --git a/debian/capi-network-tethering-dev.install b/debian/capi-network-tethering-dev.install
new file mode 100644 (file)
index 0000000..761a28b
--- /dev/null
@@ -0,0 +1,4 @@
+/usr/include/*
+/usr/include/*/*
+/usr/lib/pkgconfig/*.pc
+
diff --git a/debian/capi-network-tethering.install b/debian/capi-network-tethering.install
new file mode 100644 (file)
index 0000000..4a755a4
--- /dev/null
@@ -0,0 +1 @@
+/usr/lib/lib*.so*
diff --git a/debian/capi-network-tethering.postinst b/debian/capi-network-tethering.postinst
new file mode 100644 (file)
index 0000000..1a24852
--- /dev/null
@@ -0,0 +1 @@
+#!/bin/sh
diff --git a/debian/changelog b/debian/changelog
new file mode 100644 (file)
index 0000000..764f434
--- /dev/null
@@ -0,0 +1,25 @@
+capi-network-tethering (0.0.3-1) unstable; urgency=low
+
+  * Deprecated API from Glib2-2.32.3 is replaced with new one
+  * Git: slp/api/tethering
+  * Tag: capi-network-tethering_0.0.3-1
+
+ -- Seungyoun Ju <sy39.ju@samsung.com>  Fri, 15 Jun 2012 14:30:39 +0900
+
+capi-network-tethering (0.0.1-2) unstable; urgency=low
+
+  * Getting USB Interface API is implemented
+    Use of handle for getting client information is implemented
+    Some API's prototypes are changed
+   * Git: slp/api/tethering
+   * Tag: capi-network-tethering_0.0.1-2
+
+ -- Seungyoun Ju <sy39.ju@samsung.com>  Thu, 31 May 2012 13:54:34 +0900
+
+capi-network-tethering (0.0.1-1) unstable; urgency=low
+
+   * Initial upload
+   * Git: slp/api/tethering
+   * Tag: capi-network-tethering_0.0.1-1
+
+ -- Seungyoun Ju <sy39.ju@samsung.com>  Thu, 29 Mar 2012 10:33:07 +0900
diff --git a/debian/compat b/debian/compat
new file mode 100644 (file)
index 0000000..7ed6ff8
--- /dev/null
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644 (file)
index 0000000..ce02659
--- /dev/null
@@ -0,0 +1,21 @@
+Source: capi-network-tethering
+Section: libs
+Priority: extra
+Maintainer: Kangho Hur <kangho.hur@samsung.com>, ByungWoo Lee <bw1212.lee@samsung.com>, Seungyoun Ju <sy39.ju@samsung.com>, Hocheol Seo <hocheol.seo@samsung.com>
+Build-Depends: debhelper (>= 5), dlog-dev, capi-base-common-dev, libglib2.0-dev, libmobile-ap-dev
+
+Package: capi-network-tethering
+Architecture: any
+Depends: ${misc:Depends}
+Description: The library package for tethering
+
+Package: capi-network-tethering-dev
+Architecture: any
+Depends: ${misc:Depends}, capi-network-tethering (= ${Source-Version}), dlog-dev, capi-base-common-dev, libglib2.0-dev, libmobile-ap-dev
+Description: The development package for tethering library
+
+Package: capi-network-tethering-dbg
+Architecture: any
+Depends: ${misc:Depends}, capi-network-tethering (= ${Source-Version})
+Description: The debug package for tethering library
+
diff --git a/debian/rules b/debian/rules
new file mode 100755 (executable)
index 0000000..beda1a7
--- /dev/null
@@ -0,0 +1,64 @@
+#!/usr/bin/make -f
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+CMAKE_ROOT_DIR ?= $(CURDIR)
+CMAKE_BUILD_DIR ?= $(CURDIR)/cmake_build_tmp
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+       mkdir -p $(CMAKE_BUILD_DIR) && cd $(CMAKE_BUILD_DIR) && cmake ..
+       touch configure-stamp
+
+build: build-stamp
+build-stamp: configure-stamp
+       dh_testdir
+       cd $(CMAKE_BUILD_DIR) && $(MAKE)
+       touch $@
+
+clean:
+       cd $(CMAKE_ROOT_DIR)
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+       rm -f `find . -name *.pc`
+       rm -rf $(CMAKE_BUILD_DIR)
+       dh_clean
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k
+       dh_installdirs
+
+       cd $(CMAKE_BUILD_DIR) && $(MAKE) DESTDIR=$(CURDIR)/debian/tmp install
+
+binary-indep: build install
+
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs
+       dh_installdocs
+       dh_installexamples
+       dh_install --sourcedir=debian/tmp
+       dh_installman
+       dh_link
+       dh_strip --dbg-package=capi-network-tethering-dbg
+       dh_fixperms
+       dh_makeshlibs
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
+
diff --git a/include/marshal.list b/include/marshal.list
new file mode 100644 (file)
index 0000000..410363f
--- /dev/null
@@ -0,0 +1,3 @@
+# DBUS Signal argument converting list
+VOID:STRING,UINT,STRING,STRING,STRING
+
diff --git a/include/tethering.h b/include/tethering.h
new file mode 100644 (file)
index 0000000..8236c66
--- /dev/null
@@ -0,0 +1,639 @@
+/*
+* Copyright (c) 2011 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_TETHERING_H__
+#define __TIZEN_NETWORK_TETHERING_H__
+
+#include <tizen.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @addtogroup CAPI_NETWORK_TETHERING_MANAGER_MODULE
+ * @{
+ */
+
+/**
+ * @brief The handle for tethering.
+ */
+typedef void * tethering_h;
+
+/**
+ * @brief Enumeration for the tethering.
+ */
+typedef enum {
+    TETHERING_ERROR_NONE = TIZEN_ERROR_NONE,  /**< Successful */
+    TETHERING_ERROR_INVALID_PARAMETER = TIZEN_ERROR_INVALID_PARAMETER,  /**< Invalid parameter */
+    TETHERING_ERROR_OUT_OF_MEMORY = TIZEN_ERROR_OUT_OF_MEMORY,  /**< Out of memory */
+    TETHERING_ERROR_RESOURCE_BUSY = TIZEN_ERROR_RESOURCE_BUSY,  /**< Resource busy */
+    TETHERING_ERROR_NOT_ENABLED = TIZEN_ERROR_NETWORK_CLASS | 0x0501,  /**< Not enabled */
+    TETHERING_ERROR_OPERATION_FAILED = TIZEN_ERROR_NETWORK_CLASS | 0x0502,  /**< Operation failed */
+    TETHERING_ERROR_INVALID_OPERATION = TIZEN_ERROR_INVALID_OPERATION, /**< Invalid operation */
+} tethering_error_e;
+
+/**
+ * @brief Enumeration for the type of tethering.
+ */
+typedef enum {
+    TETHERING_TYPE_ALL = 0,  /**< All type */
+    TETHERING_TYPE_USB,  /**< USB type */
+    TETHERING_TYPE_WIFI,  /**< Wi-Fi type */
+    TETHERING_TYPE_BT,  /**< BT type */
+} tethering_type_e;
+
+/**
+ * @brief Enumeration for the cause of disabling the tethering.
+ */
+typedef enum
+{
+    TETHERING_DISABLED_BY_USB_DISCONNECTION = 0,  /**< Disabled due to usb disconnection */
+    TETHERING_DISABLED_BY_FLIGHT_MODE,  /**< Disabled due to flight mode */
+    TETHERING_DISABLED_BY_LOW_BATTERY,  /**< Disabled due to low battery */
+    TETHERING_DISABLED_BY_NETWORK_CLOSE,  /**< Disabled due to pdp network close */
+    TETHERING_DISABLED_BY_TIMEOUT,  /**< Disabled due to timeout */
+    TETHERING_DISABLED_BY_MDM_ON,  /**< Disabled due to mdm on */
+    TETHERING_DISABLED_BY_OTHERS,  /**< Disabled by other apps */
+    TETHERING_DISABLED_BY_REQUEST,  /**< Disabled by your request */
+    TETHERING_DISABLED_BY_WIFI_ON,  /**< Disabled due to Wi-Fi on */
+    TETHERING_DISABLED_BY_BT_OFF,  /**< Disabled due to Bluetooth off */
+} tethering_disabled_cause_e;
+
+/**
+ * @}
+ */
+
+
+/**
+ * @addtogroup CAPI_NETWORK_TETHERING_WIFI_MODULE
+ * @{
+ */
+
+/**
+ * @brief Enumeration for the Wi-Fi security.
+ */
+typedef enum {
+    TETHERING_WIFI_SECURITY_TYPE_NONE = 0,  /**< No Security type */
+    TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK,  /**< WPA2_PSK */
+} tethering_wifi_security_type_e;
+
+/**
+ * @}
+ */
+
+
+/**
+ * @addtogroup CAPI_NETWORK_TETHERING_CLIENT_MODULE
+ * @{
+ */
+
+/**
+ * @brief The handle for tethering client.
+ */
+typedef void * tethering_client_h;
+
+/**
+ * @brief Enumerations of Address family
+ */
+typedef enum {
+    TETHERING_ADDRESS_FAMILY_IPV4 = 0,  /**< IPV4 Address type */
+} tethering_address_family_e;
+
+/**
+ * @}
+ */
+
+
+/**
+ * @addtogroup CAPI_NETWORK_TETHERING_MANAGER_MODULE
+ * @{
+ */
+
+/**
+ * @brief  Called when the tethering is enabled.
+ * @param[in]  result  The result of enabling the tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  is_requested  Indicates whether this change is requested by you
+ * @param[in]  user_data  The user data passed from tethering_set_enabled_cb()
+ * @pre  If you register callback function using tethering_set_enabled_cb(), this will be invoked when the tethering is enabled.
+ * @see        tethering_enable()
+ * @see        tethering_unset_enabled_cb()
+ */
+typedef void (*tethering_enabled_cb)(tethering_error_e result, tethering_type_e type, bool is_requested, void *user_data);
+
+/**
+ * @brief  Called when the tethering is disabled.
+ * @param[in]  result  The result of disabling the tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  cause  The cause of disabling
+ * @param[in]  user_data  The user data passed from tethering_set_disabled_cb()
+ * @pre  If you register callback function using tethering_set_disabled_cb(), this will be invoked when the tethering is disabled.
+ * @see        tethering_set_disabled_cb()
+ * @see        tethering_unset_disabled_cb()
+ */
+typedef void (*tethering_disabled_cb)(tethering_error_e result, tethering_type_e type, tethering_disabled_cause_e cause, void *user_data);
+
+/**
+ * @brief  Called when the connection state is changed.
+ * @remakrs  @c tethering_client_h is valid only in this function. In order to use it outside this function, you must copy the client with tethering_client_clone().
+ * @param[in]  client  The client of which connection state is changed
+ * @param[in]  opened  @c true when connection is opened, otherwise false
+ * @param[in]  user_data  The user data passed from tethering_set_connection_state_changed_cb()
+ * @pre  If you register callback function using tethering_set_connection_state_changed_cb(), this will be invoked when the connection state is changed.
+ * @see        tethering_set_connection_state_changed_cb()
+ * @see        tethering_unset_connection_state_changed_cb()
+ */
+typedef void (*tethering_connection_state_changed_cb)(tethering_client_h client, bool opened, void *user_data);
+
+/**
+ * @brief Called when you get the connected client repeatedly.
+ * @remarks  @a client is valid only in this function. In order to use the client outside this function, you must copy the client with tethering_client_clone().
+ * @param[in]  client  The connected client
+ * @param[in]  user_data  The user data passed from the request function
+ * @return  @c true to continue with the next iteration of the loop, \n @c false to break out of the loop
+ * @pre  tethering_foreach_connected_clients() will invoke this callback.
+ * @see  tethering_foreach_connected_clients()
+ */
+typedef bool(*tethering_connected_client_cb)(tethering_client_h client, void *user_data);
+
+/**
+ * @brief  Called when you get the data usage.
+ * @param[in]  result  The result of getting the data usage
+ * @param[in]  received_data  The usage of received data
+ * @param[in]  sent_data  The usage of sent data
+ * @param[in]  user_data  The user data passed from the request function
+ * @pre  tethering_get_data_usage() will invoked this callback
+ */
+typedef void (*tethering_data_usage_cb)(tethering_error_e result, unsigned long long received_data, unsigned long long sent_data, void *user_data);
+
+/**
+ * @brief  Creates the handle of tethering.
+ * @remarks  The @a tethering must be released tethering_destroy() by you.
+ * @param[out]  tethering  A handle of a new mobile ap handle on success
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @see  tethering_destroy()
+ */
+int tethering_create(tethering_h *tethering);
+
+/**
+ * @brief  Destroys the handle of tethering.
+ * @param[in]  tethering  The handle of tethering
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_create()
+ */
+int tethering_destroy(tethering_h tethering);
+
+/**
+ * @brief Enables the tethering, asynchronously.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @post tethering_enabled_cb() will be invoked.
+ * @see  tethering_is_enabled()
+ * @see  tethering_disable()
+ */
+int tethering_enable(tethering_h tethering, tethering_type_e type);
+
+/**
+ * @brief Disables the tethering, asynchronously.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @post tethering_disabled_cb() will be invoked.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_disable(tethering_h tethering, tethering_type_e type);
+
+/**
+ * @brief  Checks whetehr the tethering is enabled or not.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
+ */
+bool tethering_is_enabled(tethering_h tethering, tethering_type_e type);
+
+/**
+ * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
+ * @remarks @a mac_address must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[out]  mac_address  The MAC address
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address);
+
+/**
+ * @brief Gets the name of network interface. For example, usb0.
+ * @remarks @a interface_name must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[out]  interface_name  The name of network interface
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name);
+
+/**
+ * @brief Gets the local IP address.
+ * @remarks @a ip_address must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
+ * @param[out]  ip_address  The local IP address
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address);
+
+/**
+ * @brief Gets the Gateway address.
+ * @remarks @a gateway_address must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
+ * @param[out]  gateway_address  The local IP address
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address);
+
+/**
+ * @brief Gets the Subnet Mask.
+ * @remarks @a subnet_mask must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
+ * @param[out]  subnet_mask  The local IP address
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask);
+
+/**
+ * @brief Gets the data usage.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  usage  The data usage
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data);
+
+/**
+ * @brief Gets the client which is connected by USB tethering.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  callback  The callback function to invoke
+ * @param[in]  user_data  The user data to be passed to the callback function
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data);
+
+/**
+ * @brief Registers the callback function called when tethering is enabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  callback  The callback function to invoke
+ * @param[in]  user_data  The user data to be passed to the callback function
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_unset_enabled_cb()
+ */
+int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data);
+
+/**
+ * @brief Unregisters the callback function called when tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_set_enabled_cb()
+ */
+int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type);
+
+/**
+ * @brief Registers the callback function called when tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  callback  The callback function to invoke
+ * @param[in]  user_data  The user data to be passed to the callback function
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_unset_disabled_cb()
+ */
+int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data);
+
+/**
+ * @brief Unregisters the callback function called when tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_set_disabled_cb()
+ */
+int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type);
+
+/**
+ * @brief Registers the callback function called when the state of connection is changed.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  callback  The callback function to invoke
+ * @param[in]  user_data  The user data to be passed to the callback function
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_unset_connection_state_changed_cb_cb()
+ */
+int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data);
+
+/**
+ * @brief Unregisters the callback function called when the state of connection is changed.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_set_connection_state_changed_cb()
+ */
+int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @addtogroup CAPI_NETWORK_TETHERING_WIFI_MODULE
+ * @{
+ */
+
+/**
+ * @brief Sets the security type of Wi-Fi tethering.
+ * @remarks You must set this value when Wi-Fi tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The security type
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
+ * @pre  Wi-Fi tethering must be disabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_wifi_get_security_type()
+ */
+int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type);
+
+/**
+ * @brief Gets the security type of Wi-Fi tethering.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  type  The security type
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @see  tethering_wifi_set_security_type()
+ */
+int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type);
+
+/**
+ * @brief Gets the SSID (service set identifier).
+ * @remarks @a ssid must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  ssid  The SSID
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ */
+int tethering_wifi_get_ssid(tethering_h tethering, char **ssid);
+
+/**
+ * @brief Sets the visibility of SSID(service set identifier).
+ * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
+ * @remarks You must set this value when Wi-Fi tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
+ * @pre  Wi-Fi tethering must be disabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_wifi_get_ssid_visibility()
+ */
+int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible);
+
+/**
+ * @brief Gets the visibility of SSID(service set identifier).
+ * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @see  tethering_wifi_set_ssid_visibility()
+ */
+int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible);
+
+/**
+ * @brief Sets the passphrase.
+ * @remarks You must set this value when Wi-Fi tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  passphrase  The passphrase
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
+ * @pre  Wi-Fi tethering must be disabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_wifi_get_passphrase()
+ */
+int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase);
+
+/**
+ * @brief Gets the passphrase.
+ * @remarks @a passphrase must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  passphrase  The passphrase
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @see  tethering_wifi_set_passphrase()
+ */
+int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase);
+
+/**
+ * @}
+ */
+
+
+/**
+ * @addtogroup CAPI_NETWORK_TETHERING_CLIENT_MODULE
+ * @{
+ */
+
+/**
+ * @brief  Clones the handle of client.
+ * @remarks  The @cloned_client must be release tethering_client_destroy() by you.
+ * @param[out]  dest  The cloned client handle
+ * @param[in]  origin  The origin client handle
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @see  tethering_client_destroy()
+ */
+int tethering_client_clone(tethering_client_h *dest, tethering_client_h origin);
+
+/**
+ * @brief  Destroys the handle of client.
+ * @param[in]  client  The handle of client
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_client_clone()
+ */
+int tethering_client_destroy(tethering_client_h client);
+
+/**
+ * @brief  Gets the tethering type of client.
+ * @param[in]  client  The handle of client
+ * @param[out]  type  The type of tethering
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_usb_get_connected_client()
+ * @see  tethering_connection_state_changed_cb()
+ */
+int tethering_client_get_tethering_type(tethering_client_h client, tethering_type_e *type);
+
+/**
+ * @brief  Gets the name of client.
+ * @remarks @a name must be released with free() by you.
+ * @param[in]  client  The handle of client
+ * @param[out]  name  The name of client
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @see  tethering_usb_get_connected_client()
+ * @see  tethering_connection_state_changed_cb()
+ */
+int tethering_client_get_name(tethering_client_h client, char **name);
+
+/**
+ * @brief  Gets the IP address of client.
+ * @remarks @a ip_address must be released with free() by you.
+ * @param[in]  client  The handle of client
+ * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
+ * @param[out]  ip_address  The IP address
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @see  tethering_usb_get_connected_client()
+ * @see  tethering_connection_state_changed_cb()
+ */
+int tethering_client_get_ip_address(tethering_client_h client, tethering_address_family_e address_family, char **ip_address);
+
+/**
+ * @brief  Gets the MAC address of client such as "FC:A1:3E:D6:B1:B1".
+ * @remarks @a mac_address must be released with free() by you.
+ * @param[in]  client  The handle of client
+ * @param[out]  mac_address  The MAC address
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @see  tethering_usb_get_connected_client()
+ * @see  tethering_connection_state_changed_cb()
+ */
+int tethering_client_get_mac_address(tethering_client_h client, char **mac_address);
+
+/**
+ * @}
+ */
+
+
+#ifdef __cplusplus
+ }
+#endif
+
+#endif /* __TIZEN_NETWORK_TETHERING_H__ */
+
+
diff --git a/include/tethering.xml b/include/tethering.xml
new file mode 100644 (file)
index 0000000..dbba8e1
--- /dev/null
@@ -0,0 +1,178 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+
+<!DOCTYPE node PUBLIC
+       "-//freedesktop//DTD D-Bus Object Introspection 1.0//EN"
+       "http://standards.freedesktop.org/dbus/1.0/introspect.dtd">
+
+<node>
+       <interface name="com.samsung.mobileap">
+
+               <!-- Method definitions -->
+
+               <method name="deinit">
+               </method>
+
+               <method name="disable">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="u" name="result" direction="out"/>
+               </method>
+
+               <method name="enable_wifi_tethering">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="ssid" direction="in"/>
+                       <arg type="s" name="key" direction="in"/>
+                       <arg type="i" name="visibility" direction="in"/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="u" name="result" direction="out"/>
+               </method>
+
+               <method name="disable_wifi_tethering">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="u" name="result" direction="out"/>
+               </method>
+
+               <method name="enable_bt_tethering">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="u" name="result" direction="out"/>
+               </method>
+
+               <method name="disable_bt_tethering">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="u" name="result" direction="out"/>
+               </method>
+
+               <method name="enable_usb_tethering">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="u" name="result" direction="out"/>
+               </method>
+
+               <method name="disable_usb_tethering">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="u" name="result" direction="out"/>
+               </method>
+
+               <method name="get_station_info">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="a(usss)" name="station" direction="out"/>
+               </method>
+
+               <method name="get_usb_station_info">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="a(sss)" name="usb_station" direction="out"/>
+               </method>
+
+               <method name="get_data_packet_usage">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="u" name="type" direction="out"/>
+                       <arg type="t" name="rx_data" direction="out"/>
+                       <arg type="t" name="tx_data" direction="out"/>
+               </method>
+
+               <method name="get_usb_interface_info">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="a(ssss)" name="interface" direction="out"/>
+               </method>
+
+               <method name="get_wifi_tethering_hide_mode">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="i" name="hide_mode" direction="out"/>
+               </method>
+
+               <method name="set_wifi_tethering_hide_mode">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="i" name="hide_mode" direction="in"/>
+               </method>
+
+               <method name="get_wifi_tethering_ssid">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="ssid" direction="out"/>
+               </method>
+
+               <method name="get_wifi_tethering_security_type">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="security_type" direction="out"/>
+               </method>
+
+               <method name="set_wifi_tethering_security_type">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="security_type" direction="in"/>
+               </method>
+
+               <method name="get_wifi_tethering_passphrase">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="passphrase" direction="out"/>
+                       <arg type="u" name="len" direction="out"/>
+               </method>
+
+               <method name="set_wifi_tethering_passphrase">
+                       <annotation name="org.freedesktop.DBus.GLib.Async" value=""/>
+                       <arg type="s" name="passphrase" direction="in"/>
+                       <arg type="u" name="len" direction="in"/>
+               </method>
+
+               <!-- Signal (D-Bus) definitions -->
+               <signal name="net_closed">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="sta_connected">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="sta_disconnected">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="wifi_on">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="wifi_off">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="usb_on">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="usb_off">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="bluetooth_on">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="bluetooth_off">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="no_data_timeout">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="low_batt_mode">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="flight_mode">
+                       <arg type="s" name="arg1" direction="out"/>
+               </signal>
+
+               <signal name="dhcp_status">
+                       <arg type="s" name="member" direction="out"/>
+                       <arg type="s" name="ip" direction="out"/>
+                       <arg type="s" name="mac" direction="out"/>
+                       <arg type="s" name="name" direction="out"/>
+               </signal>
+
+       </interface>
+</node>
+
diff --git a/include/tethering_private.h b/include/tethering_private.h
new file mode 100644 (file)
index 0000000..56e55ac
--- /dev/null
@@ -0,0 +1,256 @@
+/*
+* Copyright (c) 2011 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 __TETHERING_PRIVATE_H__
+#define __TETHERING_PRIVATE_H__
+
+#define LOG_TAG        "tethering"
+
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <dlog.h>
+
+#include "tethering.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef API
+#define API __attribute__ ((visibility("default")))
+#endif
+
+#ifndef DEPRECATED_API
+#  define DEPRECATED_API __attribute__ ((deprecated))
+#endif
+
+#define DBG(fmt, args...) LOGD("[%s()][Ln:%d] "fmt, __func__, __LINE__, ##args)
+#define WARN(fmt, args...) LOGW("[%s()][Ln:%d] "fmt, __func__, __LINE__, ##args)
+#define ERR(fmt, args...) LOGE("[%s()][Ln:%d] "fmt, __func__, __LINE__, ##args)
+
+#define _warn_if(expr, fmt, arg...) do { \
+               if (expr) { \
+                       WARN(fmt, ##arg); \
+               } \
+       } while (0)
+
+#define _ret_if(expr) do { \
+               if (expr) { \
+                       return; \
+               } \
+       } while (0)
+
+#define _retv_if(expr, val) do { \
+               if (expr) { \
+                       return (val); \
+               } \
+       } while (0)
+
+#define _retm_if(expr, fmt, arg...) do { \
+               if (expr) { \
+                       ERR(fmt, ##arg); \
+                       return; \
+               } \
+       } while (0)
+
+#define _retvm_if(expr, val, fmt, arg...) do { \
+               if (expr) { \
+                       ERR(fmt, ##arg); \
+                       return (val); \
+               } \
+       } while (0)
+
+/**
+* Start of mobileap-agent common values
+* When these values are changed, mobileap-agent should be also changed.
+* But some of those will be removed.
+*/
+
+/*
+* from mobileap_lib.h
+*/
+
+/**
+* WiFi tethering configuration
+*/
+#define TETHERING_WIFI_CHANNEL         7       /**< Channel number */
+#define TETHERING_WIFI_BSSID_LEN       6       /**< BSSID Length */
+#define TETHERING_WIFI_PASSPHRASE_MIN_LEN      8       /**< Minimum length of wifi key */
+#define TETHERING_WIFI_PASSPHRASE_MAX_LEN      63      /**< Maximum length of wifi key */
+
+/**
+* Common configuration
+*/
+#define TETHERING_MAX_WIFI_STA         8
+#define TETHERING_MAX_BT_STA           7
+#define TETHERING_MAX_USB_STA          1
+#define TETHERING_MAX_CONNECTED_STA    16      /**< Maximum connected station. 8(Wi-Fi) + 7(BT) + 1(USB) */
+
+#define TETHERING_NAME_UNKNOWN         "UNKNOWN"
+
+#define TETHERING_TYPE_MAX             4       /**< All, USB, Wi-Fi, BT */
+#define TETHERING_STR_INFO_LEN         20      /**< length of the ip or mac address */
+#define TETHERING_STR_HOSTNAME_LEN     32      /**< length of the hostname */
+
+/**
+* Mobile AP error code
+*/
+typedef enum {
+       MOBILE_AP_ERROR_NONE,                   /**< No error */
+       MOBILE_AP_ERROR_RESOURCE,               /**< Socket creation error, file open error */
+       MOBILE_AP_ERROR_INTERNAL,               /**< Driver related error */
+       MOBILE_AP_ERROR_INVALID_PARAM,          /**< Invalid parameter */
+       MOBILE_AP_ERROR_ALREADY_ENABLED,        /**< Mobile AP is already ON */
+       MOBILE_AP_ERROR_NOT_ENABLED,            /**< Mobile AP is not ON, so cannot be disabled */
+       MOBILE_AP_ERROR_NET_OPEN,               /**< PDP network open error */
+       MOBILE_AP_ERROR_NET_CLOSE,              /**< PDP network close error */
+       MOBILE_AP_ERROR_DHCP,                   /**< DHCP error */
+       MOBILE_AP_ERROR_IN_PROGRESS,            /**< Request is in progress */
+       MOBILE_AP_ERROR_NOT_PERMITTED,          /**< Operation is not permitted */
+
+       MOBILE_AP_ERROR_MAX
+} mobile_ap_error_code_e;
+
+/**
+* Event type on callback
+*/
+typedef enum {
+       MOBILE_AP_ENABLE_CFM,
+       MOBILE_AP_DISABLE_CFM,
+
+       MOBILE_AP_ENABLE_WIFI_TETHERING_CFM,
+       MOBILE_AP_DISABLE_WIFI_TETHERING_CFM,
+       MOBILE_AP_CHANGE_WIFI_CONFIG_CFM,
+
+       MOBILE_AP_ENABLE_USB_TETHERING_CFM,
+       MOBILE_AP_DISABLE_USB_TETHERING_CFM,
+
+       MOBILE_AP_ENABLE_BT_TETHERING_CFM,
+       MOBILE_AP_DISABLE_BT_TETHERING_CFM,
+
+       MOBILE_AP_GET_STATION_INFO_CFM,
+       MOBILE_AP_GET_DATA_PACKET_USAGE_CFM
+} mobile_ap_event_e;
+
+typedef enum {
+       MOBILE_AP_TYPE_WIFI,
+       MOBILE_AP_TYPE_USB,
+       MOBILE_AP_TYPE_BT,
+       MOBILE_AP_TYPE_MAX,
+} mobile_ap_type_e;
+
+
+/*
+* from mobileap_internal.h
+*/
+#define DBUS_STRUCT_UINT_STRING (dbus_g_type_get_struct ("GValueArray", \
+                       G_TYPE_UINT, G_TYPE_STRING, G_TYPE_INVALID))
+
+#define DBUS_STRUCT_STATIONS (dbus_g_type_get_struct ("GValueArray", \
+                       G_TYPE_UINT, G_TYPE_STRING, G_TYPE_STRING, \
+                       G_TYPE_STRING, G_TYPE_INVALID))
+
+#define DBUS_STRUCT_STATION (dbus_g_type_get_struct ("GValueArray", \
+                       G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, \
+                       G_TYPE_INVALID))
+
+#define DBUS_STRUCT_INTERFACE (dbus_g_type_get_struct ("GValueArray", \
+                       G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, \
+                       G_TYPE_STRING, G_TYPE_INVALID))
+
+#define TETHERING_SERVICE_OBJECT_PATH  "/MobileAP"
+#define TETHERING_SERVICE_NAME         "com.samsung.mobileap"
+#define TETHERING_SERVICE_INTERFACE    "com.samsung.mobileap"
+
+#define TETHERING_SIGNAL_NAME_LEN      64
+
+#define SIGNAL_NAME_NET_CLOSED         "net_closed"
+#define SIGNAL_NAME_STA_CONNECT                "sta_connected"
+#define SIGNAL_NAME_STA_DISCONNECT     "sta_disconnected"
+#define SIGNAL_NAME_WIFI_TETHER_ON     "wifi_on"
+#define SIGNAL_NAME_WIFI_TETHER_OFF    "wifi_off"
+#define SIGNAL_NAME_USB_TETHER_ON      "usb_on"
+#define SIGNAL_NAME_USB_TETHER_OFF     "usb_off"
+#define SIGNAL_NAME_BT_TETHER_ON       "bluetooth_on"
+#define SIGNAL_NAME_BT_TETHER_OFF      "bluetooth_off"
+#define SIGNAL_NAME_NO_DATA_TIMEOUT    "no_data_timeout"
+#define SIGNAL_NAME_LOW_BATTERY_MODE   "low_batt_mode"
+#define SIGNAL_NAME_FLIGHT_MODE                "flight_mode"
+#define SIGNAL_NAME_DHCP_STATUS                "dhcp_status"
+
+#define SIGNAL_MSG_NOT_AVAIL_INTERFACE "Interface is not available"
+
+/* Network Interface */
+#define TETHERING_SUBNET_MASK          "255.255.255.0"
+
+#define TETHERING_USB_IF               "usb0"
+#define TETHERING_USB_GATEWAY          "192.168.129.1"
+
+#define TETHERING_WIFI_IF              "wlan0"
+#define TETHERING_WIFI_GATEWAY         "192.168.61.1"
+
+#define TETHERING_BT_IF                        "bnep0"
+#define TETHERING_BT_GATEWAY           "192.168.130.1"
+/**
+* End of mobileap-agent common values
+*/
+
+#define TETHERING_DEFAULT_SSID                         "Redwood"
+#define TETHERING_DEFAULT_PASSPHRASE                   "eoiugkl!"
+#define TETHERING_WIFI_SECURITY_TYPE_OPEN_STR          "open"
+#define TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR      "wpa2-psk"
+
+
+typedef void (*__handle_cb_t)(DBusGProxy *proxy, const char *name, gpointer data);
+typedef struct {
+       char name[TETHERING_SIGNAL_NAME_LEN];
+       __handle_cb_t cb;
+} __tethering_sig_t;
+
+typedef struct {
+        DBusGConnection *client_bus;
+        DBusGProxy *client_bus_proxy;
+
+       tethering_enabled_cb enabled_cb[TETHERING_TYPE_MAX];
+       void *enabled_user_data[TETHERING_TYPE_MAX];
+       tethering_disabled_cb disabled_cb[TETHERING_TYPE_MAX];
+       void *disabled_user_data[TETHERING_TYPE_MAX];
+       tethering_connection_state_changed_cb changed_cb[TETHERING_TYPE_MAX];
+       void *changed_user_data[TETHERING_TYPE_MAX];
+       tethering_data_usage_cb data_usage_cb;
+       void *data_usage_user_data;
+} __tethering_h;
+
+typedef struct {
+       tethering_type_e interface;                     /**< interface type */
+       char ip[TETHERING_STR_INFO_LEN];                /**< assigned IP address */
+       char mac[TETHERING_STR_INFO_LEN];               /**< MAC Address */
+       char hostname[TETHERING_STR_HOSTNAME_LEN];      /**< alphanumeric name */
+} __tethering_client_h;
+
+typedef struct {
+       tethering_type_e interface;                     /**< interface type */
+       char interface_name[TETHERING_STR_INFO_LEN];    /**< interface alphanumeric name */
+       char ip_address[TETHERING_STR_INFO_LEN];        /**< assigned ip addresss to interface */
+       char gateway_address[TETHERING_STR_INFO_LEN];   /**< gateway address of interface */
+       char subnet_mask[TETHERING_STR_INFO_LEN];       /**< subnet mask of interface */
+} __tethering_interface_t;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __TETHERING_PRIVATE_H__ */
diff --git a/packaging/capi-network-tethering.spec b/packaging/capi-network-tethering.spec
new file mode 100644 (file)
index 0000000..c85fe30
--- /dev/null
@@ -0,0 +1,73 @@
+Name:       capi-network-tethering
+Summary:    Tethering Framework
+Version:    0.0.8
+Release:    1
+Group:      TO_BE/FILLED_IN
+License:    TO_BE/FILLED_IN
+Source0:    %{name}-%{version}.tar.gz
+Requires(post):   /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+
+BuildRequires: pkgconfig(dlog)
+BuildRequires: pkgconfig(dbus-glib-1)
+BuildRequires: pkgconfig(capi-base-common)
+BuildRequires: pkgconfig(glib-2.0)
+BuildRequires: pkgconfig(vconf)
+BuildRequires: cmake
+
+%description
+Tethering framework library for CAPI
+
+%package devel
+Summary:       Development package for Tethering framework library
+Group:         Development/Libraries
+Requires:      %{name} = %{version}-%{release}
+%description devel
+Development package for Tethering framework library
+
+%prep
+%setup -q
+
+%build
+cmake . -DCMAKE_INSTALL_PREFIX=/usr
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%post -p /sbin/ldconfig
+
+%postun -p /sbin/ldconfig
+
+%files
+%defattr(-,root,root,-)
+%{_libdir}/*.so.*
+
+%files devel
+%defattr(-,root,root,-)
+%{_includedir}/network/*.h
+%{_libdir}/pkgconfig/*.pc
+%{_libdir}/*.so
+
+%changelog
+* Mon Aug 20 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.0.8-1
+- Deprecated APIs are removed
+
+* Wed Aug 01 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.0.7-1
+- Managed APIs are implemented for Wi-Fi tethering settings
+
+* Sat Jul 21 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.0.6-1
+- Fix tethering callback issue (JIRA S1-6197)
+
+* Tue Jul 10 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.0.5
+- Getting MAC address API is implemented
+- TETHERING_TYPE_ALL case is implemented
+- Test code is implemented
+
+* Tue Jun 26 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.0.4
+- All internal APIs are implemented
+
+* Fri Jun 15 2012 Seungyoun Ju <sy39.ju@samsung.com> 0.0.3
+- Deprecated API from Glib2-2.32.3 is replaced with new one
diff --git a/src/tethering.c b/src/tethering.c
new file mode 100644 (file)
index 0000000..e2ebbfa
--- /dev/null
@@ -0,0 +1,1782 @@
+/*
+* Copyright (c) 2011 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <net/if.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+
+#include <vconf.h>
+
+#include "tethering-client-stub.h"
+#include "marshal.h"
+#include "tethering_private.h"
+
+static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data);
+
+static __tethering_sig_t sigs[] = {
+       {SIGNAL_NAME_NET_CLOSED, __handle_net_closed},
+       {SIGNAL_NAME_WIFI_TETHER_ON, __handle_wifi_tether_on},
+       {SIGNAL_NAME_WIFI_TETHER_OFF, __handle_wifi_tether_off},
+       {SIGNAL_NAME_USB_TETHER_ON, __handle_usb_tether_on},
+       {SIGNAL_NAME_USB_TETHER_OFF, __handle_usb_tether_off},
+       {SIGNAL_NAME_BT_TETHER_ON, __handle_bt_tether_on},
+       {SIGNAL_NAME_BT_TETHER_OFF, __handle_bt_tether_off},
+       {SIGNAL_NAME_NO_DATA_TIMEOUT, __handle_no_data_timeout},
+       {SIGNAL_NAME_LOW_BATTERY_MODE, __handle_low_battery_mode},
+       {SIGNAL_NAME_FLIGHT_MODE, __handle_flight_mode},
+       {"", NULL}};
+
+static bool __any_tethering_is_enabled(tethering_h tethering)
+{
+       if (tethering_is_enabled(tethering, TETHERING_TYPE_USB) ||
+                       tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) ||
+                       tethering_is_enabled(tethering, TETHERING_TYPE_BT))
+               return true;
+
+       return false;
+}
+
+static tethering_error_e __get_error(int agent_error)
+{
+       tethering_error_e err = TETHERING_ERROR_NONE;
+
+       switch (agent_error) {
+       case MOBILE_AP_ERROR_NONE:
+               err = TETHERING_ERROR_NONE;
+               break;
+
+       case MOBILE_AP_ERROR_RESOURCE:
+               err = TETHERING_ERROR_OUT_OF_MEMORY;
+               break;
+
+       case MOBILE_AP_ERROR_INTERNAL:
+               err = TETHERING_ERROR_OPERATION_FAILED;
+               break;
+
+       case MOBILE_AP_ERROR_INVALID_PARAM:
+               err = TETHERING_ERROR_INVALID_PARAMETER;
+               break;
+
+       case MOBILE_AP_ERROR_ALREADY_ENABLED:
+               err = TETHERING_ERROR_OPERATION_FAILED;
+               break;
+
+       case MOBILE_AP_ERROR_NOT_ENABLED:
+               err = TETHERING_ERROR_NOT_ENABLED;
+               break;
+
+       case MOBILE_AP_ERROR_NET_OPEN:
+               err = TETHERING_ERROR_OPERATION_FAILED;
+               break;
+
+       case MOBILE_AP_ERROR_NET_CLOSE:
+               err = TETHERING_ERROR_OPERATION_FAILED;
+               break;
+
+       case MOBILE_AP_ERROR_DHCP:
+               err = TETHERING_ERROR_OPERATION_FAILED;
+               break;
+
+       case MOBILE_AP_ERROR_IN_PROGRESS:
+               err = TETHERING_ERROR_OPERATION_FAILED;
+               break;
+
+       case MOBILE_AP_ERROR_NOT_PERMITTED:
+               err = TETHERING_ERROR_OPERATION_FAILED;
+               break;
+
+       default:
+               ERR("Not defined error : %d\n", agent_error);
+               err = TETHERING_ERROR_OPERATION_FAILED;
+               break;
+       }
+
+       return err;
+}
+
+static void __handle_dhcp(DBusGProxy *proxy, const char *member,
+               guint interface, const char *ip, const char *mac,
+               const char *name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       bool opened = false;
+       tethering_type_e type = 0;
+       tethering_connection_state_changed_cb ccb = NULL;
+       __tethering_client_h client = {0, };
+       void *data = NULL;
+
+       if (!g_strcmp0(member, "DhcpConnected")) {
+               opened = true;
+       } else if (!g_strcmp0(member, "DhcpLeaseDeleted")) {
+               opened = false;
+       } else {
+               ERR("Unknown event [%s]\n", member);
+               return;
+       }
+
+       if (interface == MOBILE_AP_TYPE_USB)
+               type = TETHERING_TYPE_USB;
+       else if (interface == MOBILE_AP_TYPE_WIFI)
+               type = TETHERING_TYPE_WIFI;
+       else if (interface == MOBILE_AP_TYPE_BT)
+               type = TETHERING_TYPE_BT;
+       else {
+               ERR("Not supported tethering type [%d]\n", interface);
+               return;
+       }
+
+       ccb = th->changed_cb[type];
+       if (ccb == NULL)
+               return;
+       data = th->changed_user_data[type];
+
+       client.interface = type;
+       g_strlcpy(client.ip, ip, sizeof(client.ip));
+       g_strlcpy(client.mac, mac, sizeof(client.mac));
+       g_strlcpy(client.hostname, name, sizeof(client.hostname));
+
+       ccb((tethering_client_h)&client, opened, data);
+
+       return;
+}
+
+static void __handle_net_closed(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = 0;
+       tethering_disabled_cb dcb = NULL;
+       void *data = NULL;
+       tethering_disabled_cause_e code = TETHERING_DISABLED_BY_NETWORK_CLOSE;
+
+       for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
+               dcb = th->disabled_cb[type];
+               if (dcb == NULL)
+                       continue;
+               data = th->disabled_user_data[type];
+
+               dcb(TETHERING_ERROR_NONE, type, code, data);
+       }
+
+       return;
+}
+
+static void __handle_wifi_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = TETHERING_TYPE_WIFI;
+       bool is_requested = false;
+       tethering_enabled_cb ecb = NULL;
+       void *data = NULL;
+
+       ecb = th->enabled_cb[type];
+       if (ecb == NULL)
+               return;
+       data = th->enabled_user_data[type];
+
+       ecb(TETHERING_ERROR_NONE, type, is_requested, data);
+}
+
+static void __handle_wifi_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = TETHERING_TYPE_WIFI;
+       tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
+       tethering_disabled_cb dcb = NULL;
+       void *data = NULL;
+
+       dcb = th->disabled_cb[type];
+       if (dcb == NULL)
+               return;
+       data = th->disabled_user_data[type];
+
+       if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
+               code = TETHERING_DISABLED_BY_WIFI_ON;
+       dcb(TETHERING_ERROR_NONE, type, code, data);
+
+       return;
+}
+
+static void __handle_usb_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = TETHERING_TYPE_USB;
+       bool is_requested = false;
+       tethering_enabled_cb ecb = NULL;
+       void *data = NULL;
+
+       ecb = th->enabled_cb[type];
+       if (ecb == NULL)
+               return;
+       data = th->enabled_user_data[type];
+
+       ecb(TETHERING_ERROR_NONE, type, is_requested, data);
+}
+
+static void __handle_usb_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = TETHERING_TYPE_USB;
+       tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
+       tethering_disabled_cb dcb = NULL;
+       void *data = NULL;
+
+       dcb = th->disabled_cb[type];
+       if (dcb == NULL)
+               return;
+       data = th->disabled_user_data[type];
+
+       if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
+               code = TETHERING_DISABLED_BY_USB_DISCONNECTION;
+       dcb(TETHERING_ERROR_NONE, type, code, data);
+
+       return;
+}
+
+static void __handle_bt_tether_on(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = TETHERING_TYPE_BT;
+       bool is_requested = false;
+       tethering_enabled_cb ecb = NULL;
+       void *data = NULL;
+
+       ecb = th->enabled_cb[type];
+       if (ecb == NULL)
+               return;
+       data = th->enabled_user_data[type];
+
+       ecb(TETHERING_ERROR_NONE, type, is_requested, data);
+}
+
+static void __handle_bt_tether_off(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = TETHERING_TYPE_BT;
+       tethering_disabled_cause_e code = TETHERING_DISABLED_BY_OTHERS;
+       tethering_disabled_cb dcb = NULL;
+       void *data = NULL;
+
+       dcb = th->disabled_cb[type];
+       if (dcb == NULL)
+               return;
+       data = th->disabled_user_data[type];
+
+       if (!g_strcmp0(value_name, SIGNAL_MSG_NOT_AVAIL_INTERFACE))
+               code = TETHERING_DISABLED_BY_BT_OFF;
+       dcb(TETHERING_ERROR_NONE, type, code, data);
+
+       return;
+}
+
+static void __handle_no_data_timeout(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = 0;
+       tethering_disabled_cb dcb = NULL;
+       void *data = NULL;
+       tethering_disabled_cause_e code = TETHERING_DISABLED_BY_TIMEOUT;
+
+       for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
+               dcb = th->disabled_cb[type];
+               if (dcb == NULL)
+                       continue;
+               data = th->disabled_user_data[type];
+
+               dcb(TETHERING_ERROR_NONE, type, code, data);
+       }
+}
+
+static void __handle_low_battery_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = 0;
+       tethering_disabled_cb dcb = NULL;
+       void *data = NULL;
+       tethering_disabled_cause_e code = TETHERING_DISABLED_BY_LOW_BATTERY;
+
+       for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
+               dcb = th->disabled_cb[type];
+               if (dcb == NULL)
+                       continue;
+               data = th->disabled_user_data[type];
+
+               dcb(TETHERING_ERROR_NONE, type, code, data);
+       }
+}
+
+static void __handle_flight_mode(DBusGProxy *proxy, const char *value_name, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+       tethering_type_e type = 0;
+       tethering_disabled_cb dcb = NULL;
+       void *data = NULL;
+       tethering_disabled_cause_e code = TETHERING_DISABLED_BY_FLIGHT_MODE;
+
+       for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
+               dcb = th->disabled_cb[type];
+               if (dcb == NULL)
+                       continue;
+               data = th->disabled_user_data[type];
+
+               dcb(TETHERING_ERROR_NONE, type, code, data);
+       }
+}
+
+static void __cfm_cb(DBusGProxy *remoteobj, guint event, guint info,
+               GError *g_error, gpointer user_data)
+{
+       DBG("+\n");
+
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       tethering_h tethering = (tethering_h)user_data;
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+
+       tethering_type_e type = 0;
+       tethering_error_e error = __get_error(info);
+       bool is_requested = true;
+       tethering_disabled_cause_e code = TETHERING_DISABLED_BY_REQUEST;
+
+       tethering_enabled_cb ecb = NULL;
+       tethering_disabled_cb dcb = NULL;
+       void *data = NULL;
+
+       if (g_error) {
+               ERR("DBus error [%s]\n", g_error->message);
+               return;
+       }
+
+       DBG("cfm event : %d info : %d\n", event, info);
+       switch (event) {
+       case MOBILE_AP_ENABLE_WIFI_TETHERING_CFM:
+               type = TETHERING_TYPE_WIFI;
+               ecb = th->enabled_cb[type];
+               data = th->enabled_user_data[type];
+               if (ecb)
+                       ecb(error, type, is_requested, data);
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
+                               G_CALLBACK(__handle_wifi_tether_on),
+                               (gpointer)tethering, NULL);
+               break;
+
+       case MOBILE_AP_DISABLE_WIFI_TETHERING_CFM:
+               type = TETHERING_TYPE_WIFI;
+               dcb = th->disabled_cb[type];
+               data = th->disabled_user_data[type];
+               if (dcb)
+                       dcb(error, type, code, data);
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
+                               G_CALLBACK(__handle_wifi_tether_off),
+                               (gpointer)tethering, NULL);
+               break;
+
+       case MOBILE_AP_ENABLE_BT_TETHERING_CFM:
+               type = TETHERING_TYPE_BT;
+               ecb = th->enabled_cb[type];
+               data = th->enabled_user_data[type];
+               if (ecb)
+                       ecb(error, type, is_requested, data);
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
+                               G_CALLBACK(__handle_bt_tether_on),
+                               (gpointer)tethering, NULL);
+               break;
+
+       case MOBILE_AP_DISABLE_BT_TETHERING_CFM:
+               type = TETHERING_TYPE_BT;
+               dcb = th->disabled_cb[type];
+               data = th->disabled_user_data[type];
+               if (dcb)
+                       dcb(error, type, code, data);
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
+                               G_CALLBACK(__handle_bt_tether_off),
+                               (gpointer)tethering, NULL);
+               break;
+
+       case MOBILE_AP_ENABLE_USB_TETHERING_CFM:
+               type = TETHERING_TYPE_USB;
+               ecb = th->enabled_cb[type];
+               data = th->enabled_user_data[type];
+               if (ecb)
+                       ecb(error, type, is_requested, data);
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
+                               G_CALLBACK(__handle_usb_tether_on),
+                               (gpointer)tethering, NULL);
+               break;
+
+       case MOBILE_AP_DISABLE_USB_TETHERING_CFM:
+               type = TETHERING_TYPE_USB;
+               dcb = th->disabled_cb[type];
+               data = th->disabled_user_data[type];
+               if (dcb)
+                       dcb(error, type, code, data);
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
+                               G_CALLBACK(__handle_usb_tether_off),
+                               (gpointer)tethering, NULL);
+               break;
+
+       case MOBILE_AP_DISABLE_CFM:
+               for (type = TETHERING_TYPE_USB; type <= TETHERING_TYPE_BT; type++) {
+                       dcb = th->disabled_cb[type];
+                       if (dcb == NULL)
+                               continue;
+                       data = th->disabled_user_data[type];
+
+                       dcb(error, type, code, data);
+               }
+
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
+                               G_CALLBACK(__handle_usb_tether_off),
+                               (gpointer)tethering, NULL);
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
+                               G_CALLBACK(__handle_wifi_tether_off),
+                               (gpointer)tethering, NULL);
+               dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
+                               G_CALLBACK(__handle_bt_tether_off),
+                               (gpointer)tethering, NULL);
+               break;
+
+       default:
+               ERR("Invalid event\n");
+               return;
+       }
+
+       return;
+}
+
+static void __get_data_usage_cb(DBusGProxy *remoteobj, guint event,
+               guint64 tx_bytes, guint64 rx_bytes,
+               GError *error, gpointer user_data)
+{
+       _retm_if(user_data == NULL, "parameter(user_data) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)user_data;
+
+       if (th->data_usage_cb == NULL) {
+               ERR("There is no data_usage_cb\n");
+               return;
+       }
+
+       if (error || event != MOBILE_AP_GET_DATA_PACKET_USAGE_CFM) {
+               if (error)  {
+                       ERR("DBus fail [%s]\n", error->message);
+                       g_error_free(error);
+               }
+
+               th->data_usage_cb(TETHERING_ERROR_OPERATION_FAILED,
+                               0LL, 0LL, th->data_usage_user_data);
+
+               th->data_usage_cb = NULL;
+               th->data_usage_user_data = NULL;
+
+               return;
+       }
+
+       th->data_usage_cb(TETHERING_ERROR_NONE,
+                       rx_bytes, tx_bytes, th->data_usage_user_data);
+
+       th->data_usage_cb = NULL;
+       th->data_usage_user_data = NULL;
+
+       return;
+}
+
+static void __connect_signals(tethering_h tethering)
+{
+       _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+       int i = 0;
+
+       for (i = 0; sigs[i].cb != NULL; i++) {
+               dbus_g_proxy_add_signal(proxy, sigs[i].name,
+                               G_TYPE_STRING, G_TYPE_INVALID);
+               dbus_g_proxy_connect_signal(proxy, sigs[i].name,
+                               G_CALLBACK(sigs[i].cb), (gpointer)tethering, NULL);
+       }
+
+       dbus_g_object_register_marshaller(marshal_VOID__STRING_UINT_STRING_STRING_STRING,
+                       G_TYPE_NONE, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
+                       G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+       dbus_g_proxy_add_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
+                       G_TYPE_STRING, G_TYPE_UINT, G_TYPE_STRING,
+                       G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INVALID);
+       dbus_g_proxy_connect_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
+                       G_CALLBACK(__handle_dhcp), (gpointer)tethering, NULL);
+
+       return;
+}
+
+static void __disconnect_signals(tethering_h tethering)
+{
+       _retm_if(tethering == NULL, "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+
+       int i = 0;
+
+       for (i = 0; sigs[i].cb != NULL; i++) {
+               dbus_g_proxy_disconnect_signal(proxy, sigs[i].name,
+                               G_CALLBACK(sigs[i].cb), (gpointer)tethering);
+       }
+
+       dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_DHCP_STATUS,
+                       G_CALLBACK(__handle_dhcp), (gpointer)tethering);
+
+       return;
+}
+
+static bool __get_intf_name(tethering_type_e type, char *buf, unsigned int len)
+{
+       _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
+
+       switch (type) {
+       case TETHERING_TYPE_USB:
+               g_strlcpy(buf, TETHERING_USB_IF, len);
+               break;
+
+       case TETHERING_TYPE_WIFI:
+               g_strlcpy(buf, TETHERING_WIFI_IF, len);
+               break;
+
+       case TETHERING_TYPE_BT:
+               g_strlcpy(buf, TETHERING_BT_IF, len);
+               break;
+
+       default:
+               ERR("Not supported type : %d\n", type);
+               return false;
+       }
+
+       return true;
+}
+
+static bool __get_gateway_addr(tethering_type_e type, char *buf, unsigned int len)
+{
+       _retvm_if(buf == NULL, false, "parameter(buf) is NULL\n");
+
+       switch (type) {
+       case TETHERING_TYPE_USB:
+               g_strlcpy(buf, TETHERING_USB_GATEWAY, len);
+               break;
+
+       case TETHERING_TYPE_WIFI:
+               g_strlcpy(buf, TETHERING_WIFI_GATEWAY, len);
+               break;
+
+       case TETHERING_TYPE_BT:
+               g_strlcpy(buf, TETHERING_BT_GATEWAY, len);
+               break;
+
+       default:
+               ERR("Not supported type : %d\n", type);
+               return false;
+       }
+
+       return true;
+}
+
+/**
+ * @brief  Creates the handle of tethering.
+ * @remarks  The @a tethering must be released tethering_destroy() by you.
+ * @param[out]  tethering  A handle of a new mobile ap handle on success
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @see  tethering_destroy()
+ */
+API int tethering_create(tethering_h *tethering)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = NULL;
+       GError *error = NULL;
+
+       th = (__tethering_h *)malloc(sizeof(__tethering_h));
+       _retvm_if(th == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
+                       "malloc is failed\n");
+       memset(th, 0x00, sizeof(__tethering_h));
+
+       g_type_init();
+       th->client_bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
+       if (error) {
+               ERR("Couldn't connect to the System bus[%s]", error->message);
+               g_error_free(error);
+               free(th);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       th->client_bus_proxy = dbus_g_proxy_new_for_name(th->client_bus,
+                       TETHERING_SERVICE_NAME,
+                       TETHERING_SERVICE_OBJECT_PATH,
+                       TETHERING_SERVICE_INTERFACE);
+       if (!th->client_bus_proxy) {
+               ERR("Couldn't create the proxy object");
+               dbus_g_connection_unref(th->client_bus);
+               free(th);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       __connect_signals((tethering_h)th);
+
+       *tethering = (tethering_h)th;
+       DBG("Tethering Handle : 0x%X\n", th);
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief  Destroys the handle of tethering.
+ * @param[in]  tethering  The handle of tethering
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_create()
+ */
+API int tethering_destroy(tethering_h tethering)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       GError *error = NULL;
+
+       DBG("Tethering Handle : 0x%X\n", th);
+       com_samsung_mobileap_deinit(th->client_bus_proxy, &error);
+       if (error) {
+               ERR("tethering_destroy is failed [%s]", error->message);
+               g_error_free(error);
+       }
+       __disconnect_signals(tethering);
+
+       g_object_unref(th->client_bus_proxy);
+       dbus_g_connection_unref(th->client_bus);
+       memset(th, 0x00, sizeof(__tethering_h));
+       free(th);
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Enables the tethering, asynchronously.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @post tethering_enabled_cb() will be invoked.
+ * @see  tethering_is_enabled()
+ * @see  tethering_disable()
+ */
+int tethering_enable(tethering_h tethering, tethering_type_e type)
+{
+       DBG("+\n");
+
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+
+       switch (type) {
+       case TETHERING_TYPE_USB:
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
+                               G_CALLBACK(__handle_usb_tether_on),
+                               (gpointer)tethering);
+               com_samsung_mobileap_enable_usb_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+               break;
+
+       case TETHERING_TYPE_WIFI:
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
+                               G_CALLBACK(__handle_wifi_tether_on),
+                               (gpointer)tethering);
+               com_samsung_mobileap_enable_wifi_tethering_async(proxy, "", "", false,
+                               __cfm_cb, (gpointer)tethering);
+               break;
+
+       case TETHERING_TYPE_BT:
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
+                               G_CALLBACK(__handle_bt_tether_on),
+                               (gpointer)tethering);
+               com_samsung_mobileap_enable_bt_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+
+               break;
+
+       case TETHERING_TYPE_ALL:
+               /* TETHERING_TYPE_USB */
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_ON,
+                               G_CALLBACK(__handle_usb_tether_on),
+                               (gpointer)tethering);
+               com_samsung_mobileap_enable_usb_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+
+               /* TETHERING_TYPE_WIFI */
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_ON,
+                               G_CALLBACK(__handle_wifi_tether_on),
+                               (gpointer)tethering);
+               com_samsung_mobileap_enable_wifi_tethering_async(proxy, "", "", false,
+                               __cfm_cb, (gpointer)tethering);
+
+               /* TETHERING_TYPE_BT */
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_ON,
+                               G_CALLBACK(__handle_bt_tether_on),
+                               (gpointer)tethering);
+               com_samsung_mobileap_enable_bt_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+               break;
+
+       default:
+               ERR("Unknown type : %d\n", type);
+               return TETHERING_ERROR_INVALID_PARAMETER;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Disables the tethering, asynchronously.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @post tethering_disabled_cb() will be invoked.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+API int tethering_disable(tethering_h tethering, tethering_type_e type)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+
+       switch (type) {
+       case TETHERING_TYPE_USB:
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
+                               G_CALLBACK(__handle_usb_tether_off),
+                               (gpointer)tethering);
+               com_samsung_mobileap_disable_usb_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+               break;
+
+       case TETHERING_TYPE_WIFI:
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
+                               G_CALLBACK(__handle_wifi_tether_off),
+                               (gpointer)tethering);
+               com_samsung_mobileap_disable_wifi_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+               break;
+       case TETHERING_TYPE_BT:
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
+                               G_CALLBACK(__handle_bt_tether_off),
+                               (gpointer)tethering);
+               com_samsung_mobileap_disable_bt_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+               break;
+
+       case TETHERING_TYPE_ALL:
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_USB_TETHER_OFF,
+                               G_CALLBACK(__handle_usb_tether_off),
+                               (gpointer)tethering);
+               com_samsung_mobileap_disable_usb_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_WIFI_TETHER_OFF,
+                               G_CALLBACK(__handle_wifi_tether_off),
+                               (gpointer)tethering);
+               com_samsung_mobileap_disable_wifi_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+
+               dbus_g_proxy_disconnect_signal(proxy, SIGNAL_NAME_BT_TETHER_OFF,
+                               G_CALLBACK(__handle_bt_tether_off),
+                               (gpointer)tethering);
+               com_samsung_mobileap_disable_bt_tethering_async(proxy,
+                               __cfm_cb, (gpointer)tethering);
+               break;
+
+       default :
+               ERR("Not supported tethering type [%d]\n", type);
+               return TETHERING_ERROR_INVALID_PARAMETER;
+               break;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief  Checks whetehr the tethering is enabled or not.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @return  @c true if tethering is enabled, \n @c false if tethering is disabled.
+ */
+API bool tethering_is_enabled(tethering_h tethering, tethering_type_e type)
+{
+       int is_on = 0;
+       int vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_NONE;
+
+       if (vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &is_on) != 0) {
+               return FALSE;
+       }
+
+       switch (type) {
+       case TETHERING_TYPE_USB:
+               vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_USB;
+               break;
+
+       case TETHERING_TYPE_WIFI:
+               vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI;
+               break;
+
+       case TETHERING_TYPE_BT:
+               vconf_type = VCONFKEY_MOBILE_HOTSPOT_MODE_BT;
+               break;
+
+       default:
+               ERR("Not supported type : %d\n", type);
+               break;
+       }
+
+       return is_on & vconf_type ? true : false;
+}
+
+/**
+ * @brief  Gets the MAC address of local device as "FC:A1:3E:D6:B1:B1".
+ * @remarks @a mac_address must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[out]  mac_address  The MAC address
+ * @return  0 on success, otherwise a negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_get_mac_address(tethering_h tethering, tethering_type_e type, char **mac_address)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(mac_address) is NULL\n");
+       _retvm_if(tethering_is_enabled(tethering, type) == false,
+                       TETHERING_ERROR_NOT_ENABLED,
+                       "tethering type[%d] is not enabled\n", type);
+
+       struct ifreq ifr;
+       int s = 0;
+       char *macbuf = NULL;
+
+       _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
+                       TETHERING_ERROR_OPERATION_FAILED,
+                       "getting interface name is failed\n");
+
+       s = socket(AF_INET, SOCK_DGRAM, 0);
+       _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
+                       "getting socket is failed\n");
+       if (ioctl(s, SIOCGIFHWADDR, &ifr) < 0) {
+               ERR("getting mac is failed\n");
+               close(s);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+       close(s);
+
+       macbuf = (char *)malloc(TETHERING_STR_INFO_LEN);
+       _retvm_if(macbuf == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
+                       "Not enough memory\n");
+       snprintf(macbuf, TETHERING_STR_INFO_LEN, "%02X:%02X:%02X:%02X:%02X:%02X",
+                       (unsigned char)ifr.ifr_hwaddr.sa_data[0],
+                       (unsigned char)ifr.ifr_hwaddr.sa_data[1],
+                       (unsigned char)ifr.ifr_hwaddr.sa_data[2],
+                       (unsigned char)ifr.ifr_hwaddr.sa_data[3],
+                       (unsigned char)ifr.ifr_hwaddr.sa_data[4],
+                       (unsigned char)ifr.ifr_hwaddr.sa_data[5]);
+
+       *mac_address = macbuf;
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the name of network interface. For example, usb0.
+ * @remarks @a interface_name must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[out]  interface_name  The name of network interface
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+API int tethering_get_network_interface_name(tethering_h tethering, tethering_type_e type, char **interface_name)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(interface_name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(interface_name) is NULL\n");
+       _retvm_if(tethering_is_enabled(tethering, type) == false,
+                       TETHERING_ERROR_NOT_ENABLED,
+                       "tethering type[%d] is not enabled\n", type);
+
+       char intf[TETHERING_STR_INFO_LEN] = {0, };
+
+       _retvm_if(!__get_intf_name(type, intf, sizeof(intf)),
+                       TETHERING_ERROR_OPERATION_FAILED,
+                       "getting interface name is failed\n");
+       *interface_name = strdup(intf);
+       _retvm_if(*interface_name == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
+                       "Not enough memory\n");
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the local IP address.
+ * @remarks @a ip_address must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
+ * @param[out]  ip_address  The local IP address
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+API int tethering_get_ip_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **ip_address)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(ip_address) is NULL\n");
+       _retvm_if(tethering_is_enabled(tethering, type) == false,
+                       TETHERING_ERROR_NOT_ENABLED,
+                       "tethering type[%d] is not enabled\n", type);
+
+       struct ifreq ifr;
+       int s = 0;
+       char *ipbuf = NULL;
+
+       _retvm_if(!__get_intf_name(type, ifr.ifr_name, sizeof(ifr.ifr_name)),
+                       TETHERING_ERROR_OPERATION_FAILED,
+                       "getting interface name is failed\n");
+
+       s = socket(AF_INET, SOCK_DGRAM, 0);
+       _retvm_if(s < 0, TETHERING_ERROR_OPERATION_FAILED,
+                       "getting socket is failed\n");
+       if (ioctl(s, SIOCGIFADDR, &ifr) < 0) {
+               ERR("ioctl is failed\n");
+               close(s);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+       close(s);
+
+       ipbuf = inet_ntoa(((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr);
+       *ip_address = strdup(ipbuf);
+       _retvm_if(*ip_address == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
+                       "Not enough memory\n");
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the Gateway address.
+ * @remarks @a gateway_address must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
+ * @param[out]  gateway_address  The local IP address
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+API int tethering_get_gateway_address(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **gateway_address)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(gateway_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(gateway_address) is NULL\n");
+       _retvm_if(tethering_is_enabled(tethering, type) == false,
+                       TETHERING_ERROR_NOT_ENABLED,
+                       "tethering type[%d] is not enabled\n", type);
+
+       char gateway_buf[TETHERING_STR_INFO_LEN] = {0, };
+
+       _retvm_if(!__get_gateway_addr(type, gateway_buf, sizeof(gateway_buf)),
+                       TETHERING_ERROR_OPERATION_FAILED,
+                       "getting gateway address is failed\n");
+
+       *gateway_address = strdup(gateway_buf);
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the Subnet Mask.
+ * @remarks @a subnet_mask must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  address_family  The address family of IP address. Currently, #TETHERING_ADDRESS_FAMILY_IPV4 is only supported.
+ * @param[out]  subnet_mask  The local IP address
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+int tethering_get_subnet_mask(tethering_h tethering, tethering_type_e type, tethering_address_family_e address_family, char **subnet_mask)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(tethering_is_enabled(tethering, type) == false,
+                       TETHERING_ERROR_NOT_ENABLED,
+                       "tethering is not enabled\n");
+       _retvm_if(subnet_mask == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(subnet_mask) is NULL\n");
+
+       *subnet_mask = strdup(TETHERING_SUBNET_MASK);
+       _retvm_if(*subnet_mask == NULL, TETHERING_ERROR_OUT_OF_MEMORY,
+                       "Not enough memory\n");
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the data usage.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  usage  The data usage
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+API int tethering_get_data_usage(tethering_h tethering, tethering_data_usage_cb callback, void *user_data)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(callback) is NULL\n");
+       _retvm_if(__any_tethering_is_enabled(tethering) == false,
+                       TETHERING_ERROR_NOT_ENABLED,
+                       "tethering is not enabled\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+
+       th->data_usage_cb = callback;
+       th->data_usage_user_data = user_data;
+
+       com_samsung_mobileap_get_data_packet_usage_async(proxy,
+                       __get_data_usage_cb, (gpointer)th);
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the client which is connected by USB tethering.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  callback  The callback function to invoke
+ * @param[in]  user_data  The user data to be passed to the callback function
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_NOT_ENABLED  Not enabled
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @pre  tethering must be enabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_enable()
+ */
+API int tethering_foreach_connected_clients(tethering_h tethering, tethering_type_e type, tethering_connected_client_cb callback, void *user_data)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(callback) is NULL\n");
+       _retvm_if(__any_tethering_is_enabled(tethering) == false,
+                       TETHERING_ERROR_NOT_ENABLED,
+                       "tethering is not enabled\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       __tethering_client_h client = {0, };
+
+       guint event = 0;
+       GPtrArray *array = NULL;
+       GValue value = {0, {{0}}};
+       GError *error = NULL;
+       int i = 0;
+       int no_of_client = 0;
+       guint interface = 0;
+       gchar *ip = NULL;
+       gchar *mac = NULL;
+       gchar *hostname = NULL;
+
+       com_samsung_mobileap_get_station_info(th->client_bus_proxy, &event,
+                       &array, &error);
+       if (error != NULL) {
+               ERR("DBus fail : %s\n", error->message);
+               g_error_free(error);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       g_value_init(&value, DBUS_STRUCT_STATIONS);
+       no_of_client = array->len;
+       for (i = 0; i < no_of_client; i++) {
+               g_value_set_boxed(&value, g_ptr_array_index(array, i));
+
+               dbus_g_type_struct_get(&value, 0, &interface, 1, &ip,
+                               2, &mac, 3, &hostname, G_MAXUINT);
+
+               if (interface == MOBILE_AP_TYPE_USB)
+                       client.interface = TETHERING_TYPE_USB;
+               else if (interface == MOBILE_AP_TYPE_WIFI)
+                       client.interface = TETHERING_TYPE_WIFI;
+               else if (interface == MOBILE_AP_TYPE_BT)
+                       client.interface = TETHERING_TYPE_BT;
+
+               if (client.interface != type && TETHERING_TYPE_ALL != type)
+                       continue;
+
+               g_strlcpy(client.ip, ip, sizeof(client.ip));
+               g_strlcpy(client.mac, mac, sizeof(client.mac));
+               g_strlcpy(client.hostname, hostname, sizeof(client.hostname));
+
+               if (callback((tethering_client_h)&client, user_data) == false) {
+                       DBG("iteration is stopped\n");
+                       return TETHERING_ERROR_NONE;
+               }
+       }
+
+       if (array->len > 0)
+               g_ptr_array_free(array, TRUE);
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Registers the callback function called when tethering is enabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  callback  The callback function to invoke
+ * @param[in]  user_data  The user data to be passed to the callback function
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_unset_enabled_cb()
+ */
+API int tethering_set_enabled_cb(tethering_h tethering, tethering_type_e type, tethering_enabled_cb callback, void *user_data)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(callback) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       tethering_type_e ti;
+
+       if (type != TETHERING_TYPE_ALL) {
+               th->enabled_cb[type] = callback;
+               th->enabled_user_data[type] = user_data;
+
+               return TETHERING_ERROR_NONE;
+       }
+
+       /* TETHERING_TYPE_ALL */
+       for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
+               th->enabled_cb[ti] = callback;
+               th->enabled_user_data[ti] = user_data;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Unregisters the callback function called when tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_set_enabled_cb()
+ */
+API int tethering_unset_enabled_cb(tethering_h tethering, tethering_type_e type)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       tethering_type_e ti;
+
+       if (type != TETHERING_TYPE_ALL) {
+               th->enabled_cb[type] = NULL;
+               th->enabled_user_data[type] = NULL;
+
+               return TETHERING_ERROR_NONE;
+       }
+
+       /* TETHERING_TYPE_ALL */
+       for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
+               th->enabled_cb[ti] = NULL;
+               th->enabled_user_data[ti] = NULL;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Registers the callback function called when tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  callback  The callback function to invoke
+ * @param[in]  user_data  The user data to be passed to the callback function
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_unset_disabled_cb()
+ */
+API int tethering_set_disabled_cb(tethering_h tethering, tethering_type_e type, tethering_disabled_cb callback, void *user_data)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(callback) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       tethering_type_e ti;
+
+       if (type != TETHERING_TYPE_ALL) {
+               th->disabled_cb[type] = callback;
+               th->disabled_user_data[type] = user_data;
+
+               return TETHERING_ERROR_NONE;
+       }
+
+       /* TETHERING_TYPE_ALL */
+       for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
+               th->disabled_cb[ti] = callback;
+               th->disabled_user_data[ti] = user_data;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Unregisters the callback function called when tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_set_disabled_cb()
+ */
+API int tethering_unset_disabled_cb(tethering_h tethering, tethering_type_e type)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       tethering_type_e ti;
+
+       if (type != TETHERING_TYPE_ALL) {
+               th->disabled_cb[type] = NULL;
+               th->disabled_user_data[type] = NULL;
+
+               return TETHERING_ERROR_NONE;
+       }
+
+       /* TETHERING_TYPE_ALL */
+       for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
+               th->disabled_cb[ti] = NULL;
+               th->disabled_user_data[ti] = NULL;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Registers the callback function called when the state of connection is changed.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @param[in]  callback  The callback function to invoke
+ * @param[in]  user_data  The user data to be passed to the callback function
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_unset_connection_state_changed_cb_cb()
+ */
+API int tethering_set_connection_state_changed_cb(tethering_h tethering, tethering_type_e type, tethering_connection_state_changed_cb callback, void *user_data)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(callback == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(callback) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       tethering_type_e ti;
+
+       if (type != TETHERING_TYPE_ALL) {
+               th->changed_cb[type] = callback;
+               th->changed_user_data[type] = user_data;
+
+               return TETHERING_ERROR_NONE;
+       }
+
+       /* TETHERING_TYPE_ALL */
+       for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
+               th->changed_cb[ti] = callback;
+               th->changed_user_data[ti] = user_data;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Unregisters the callback function called when the state of connection is changed.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The type of tethering
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @see  tethering_set_connection_state_changed_cb()
+ */
+API int tethering_unset_connection_state_changed_cb(tethering_h tethering, tethering_type_e type)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       tethering_type_e ti;
+
+       if (type != TETHERING_TYPE_ALL) {
+               th->changed_cb[type] = NULL;
+               th->changed_user_data[type] = NULL;
+
+               return TETHERING_ERROR_NONE;
+       }
+
+       /* TETHERING_TYPE_ALL */
+       for (ti = TETHERING_TYPE_USB; ti <= TETHERING_TYPE_BT; ti++) {
+               th->changed_cb[ti] = NULL;
+               th->changed_user_data[ti] = NULL;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Sets the security type of Wi-Fi tethering.
+ * @remarks You must set this value when Wi-Fi tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  type  The security type
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
+ * @pre  Wi-Fi tethering must be disabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_wifi_get_security_type()
+ */
+API int tethering_wifi_set_security_type(tethering_h tethering, tethering_wifi_security_type_e type)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == true,
+                       TETHERING_ERROR_INVALID_OPERATION,
+                       "Wi-Fi tethering is enabled\n");
+       DBG("+\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+       GError *error = NULL;
+       char *type_str = NULL;
+
+       if (type == TETHERING_WIFI_SECURITY_TYPE_NONE) {
+               type_str = TETHERING_WIFI_SECURITY_TYPE_OPEN_STR;
+       } else if (type == TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK) {
+               type_str = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR;
+       } else {
+               ERR("Unsupported type\n");
+               return TETHERING_ERROR_INVALID_PARAMETER;
+       }
+
+       com_samsung_mobileap_set_wifi_tethering_security_type(proxy, type_str, &error);
+       if (error != NULL) {
+               ERR("DBus fail : %s\n", error->message);
+               g_error_free(error);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       DBG("-\n");
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the security type of Wi-Fi tethering.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  type  The security type
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @see  tethering_wifi_set_security_type()
+ */
+API int tethering_wifi_get_security_type(tethering_h tethering, tethering_wifi_security_type_e *type)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(type) is NULL\n");
+       DBG("+\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+       GError *error = NULL;
+       char *type_str = NULL;
+
+       com_samsung_mobileap_get_wifi_tethering_security_type(proxy, &type_str, &error);
+       if (error != NULL) {
+               ERR("DBus fail : %s\n", error->message);
+               g_error_free(error);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       if (type_str == NULL)
+               return TETHERING_ERROR_OPERATION_FAILED;
+
+       DBG("security type : %s\n", type_str);
+       if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_OPEN_STR) == 0)
+               *type = TETHERING_WIFI_SECURITY_TYPE_NONE;
+       else if (strcmp(type_str, TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK_STR) == 0)
+               *type = TETHERING_WIFI_SECURITY_TYPE_WPA2_PSK;
+       else {
+               ERR("Unknown security type : %s\n", type_str);
+               g_free(type_str);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       g_free(type_str);
+
+       DBG("-\n");
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the SSID (service set identifier).
+ * @remarks @a ssid must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  ssid  The SSID
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ */
+API int tethering_wifi_get_ssid(tethering_h tethering, char **ssid)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(ssid == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(ssid) is NULL\n");
+       DBG("+\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+       GError *error = NULL;
+       char *ssid_buf = NULL;
+
+       com_samsung_mobileap_get_wifi_tethering_ssid(proxy, &ssid_buf, &error);
+       if (error != NULL) {
+               ERR("dbus fail : %s\n", error->message);
+               g_error_free(error);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       if (ssid_buf == NULL)
+               return TETHERING_ERROR_OPERATION_FAILED;
+
+       *ssid = strdup(ssid_buf);
+       if (*ssid == NULL) {
+               ERR("Memory allocation failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       g_free(ssid_buf);
+
+       DBG("-\n");
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Sets the visibility of SSID(service set identifier).
+ * @details If you set the visibility invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
+ * @remarks You must set this value when Wi-Fi tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
+ * @pre  Wi-Fi tethering must be disabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_wifi_get_ssid_visibility()
+ */
+int tethering_wifi_set_ssid_visibility(tethering_h tethering, bool visible)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == true,
+                       TETHERING_ERROR_INVALID_OPERATION,
+                       "Wi-Fi tethering is enabled\n");
+       DBG("+\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+       GError *error = NULL;
+       int hide_mode = 0;
+
+       if (visible)
+               hide_mode = VCONFKEY_MOBILE_AP_HIDE_OFF;
+       else
+               hide_mode = VCONFKEY_MOBILE_AP_HIDE_ON;
+
+       com_samsung_mobileap_set_wifi_tethering_hide_mode(proxy, hide_mode, &error);
+       if (error != NULL) {
+               ERR("dbus fail : %s\n", error->message);
+               g_error_free(error);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       DBG("-\n");
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the visibility of SSID(service set identifier).
+ * @details If the visibility is set invisible, then the SSID of this device is hidden. So, Wi-Fi scan can't find your device.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  visible  The visibility of SSID: (@c true = visible, @c false = invisible)
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @see  tethering_wifi_set_ssid_visibility()
+ */
+API int tethering_wifi_get_ssid_visibility(tethering_h tethering, bool *visible)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(visible == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(enabled) is NULL\n");
+       DBG("+\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+       GError *error = NULL;
+       int hide_mode = 0;
+
+       com_samsung_mobileap_get_wifi_tethering_hide_mode(proxy, &hide_mode, &error);
+       if (error != NULL) {
+               ERR("dbus fail : %s\n", error->message);
+               g_error_free(error);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+       DBG("hide mode : %d\n", hide_mode);
+
+       if (hide_mode == VCONFKEY_MOBILE_AP_HIDE_OFF)
+               *visible = true;
+       else
+               *visible = false;
+
+       DBG("-\n");
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Sets the passphrase.
+ * @remarks You must set this value when Wi-Fi tethering is disabled.
+ * @param[in]  tethering  The handle of tethering
+ * @param[in]  passphrase  The passphrase
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @retval  #TETHERING_ERROR_INVALID_OPERATION  Invalid operation
+ * @pre  Wi-Fi tethering must be disabled.
+ * @see  tethering_is_enabled()
+ * @see  tethering_wifi_get_passphrase()
+ */
+API int tethering_wifi_set_passphrase(tethering_h tethering, const char *passphrase)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(tethering_is_enabled(tethering, TETHERING_TYPE_WIFI) == true,
+                       TETHERING_ERROR_INVALID_OPERATION,
+                       "Wi-Fi tethering is enabled\n");
+       _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(passphrase) is NULL\n");
+       DBG("+\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+       GError *error = NULL;
+
+       com_samsung_mobileap_set_wifi_tethering_passphrase(proxy,
+                       passphrase, strlen(passphrase), &error);
+       if (error != NULL) {
+               ERR("dbus fail : %s\n", error->message);
+               g_error_free(error);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       DBG("-\n");
+       return TETHERING_ERROR_NONE;
+}
+
+/**
+ * @brief Gets the passphrase.
+ * @remarks @a passphrase must be released with free() by you.
+ * @param[in]  tethering  The handle of tethering
+ * @param[out]  passphrase  The passphrase
+ * @return 0 on success, otherwise negative error value.
+ * @retval  #TETHERING_ERROR_NONE  Successful
+ * @retval  #TETHERING_ERROR_INVALID_PARAMETER  Invalid parameter
+ * @retval  #TETHERING_ERROR_OUT_OF_MEMORY  Out of memory
+ * @retval  #TETHERING_ERROR_OPERATION_FAILED  Operation failed
+ * @see  tethering_wifi_set_passphrase()
+ */
+API int tethering_wifi_get_passphrase(tethering_h tethering, char **passphrase)
+{
+       _retvm_if(tethering == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(tethering) is NULL\n");
+       _retvm_if(passphrase == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "parameter(passphrase) is NULL\n");
+       DBG("+\n");
+
+       __tethering_h *th = (__tethering_h *)tethering;
+       DBusGProxy *proxy = th->client_bus_proxy;
+       GError *error = NULL;
+       char *passphrase_buf = NULL;
+       unsigned int len = 0;
+
+       com_samsung_mobileap_get_wifi_tethering_passphrase(proxy,
+                       &passphrase_buf, &len, &error);
+       if (error != NULL) {
+               ERR("dbus fail : %s\n", error->message);
+               g_error_free(error);
+               return TETHERING_ERROR_OPERATION_FAILED;
+       }
+
+       if (passphrase_buf == NULL)
+               return TETHERING_ERROR_OPERATION_FAILED;
+
+       *passphrase = strdup(passphrase_buf);
+       if (*passphrase == NULL) {
+               ERR("Memory allocation failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       g_free(passphrase_buf);
+
+       DBG("-\n");
+       return TETHERING_ERROR_NONE;
+}
diff --git a/src/tethering_client.c b/src/tethering_client.c
new file mode 100644 (file)
index 0000000..3dca574
--- /dev/null
@@ -0,0 +1,119 @@
+/*
+* Copyright (c) 2011 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 <stdlib.h>
+#include <string.h>
+#include "tethering_private.h"
+
+int tethering_client_clone(tethering_client_h *dest, tethering_client_h origin)
+{
+       _retvm_if(dest == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(dest) is NULL\n");
+
+       __tethering_client_h *si = NULL;
+
+       si = malloc(sizeof(__tethering_client_h));
+       if (si == NULL) {
+               ERR("malloc is failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       memcpy(si, (__tethering_client_h *)origin,
+                       sizeof(__tethering_client_h));
+
+       *dest = (tethering_client_h)si;
+
+       return TETHERING_ERROR_NONE;
+}
+
+int tethering_client_destroy(tethering_client_h client)
+{
+       _retvm_if(client == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(client) is NULL\n");
+
+       free(client);
+
+       return TETHERING_ERROR_NONE;
+}
+
+int tethering_client_get_tethering_type(tethering_client_h client, tethering_type_e *type)
+{
+       _retvm_if(client == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(client) is NULL\n");
+       _retvm_if(type == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(type) is NULL\n");
+
+       __tethering_client_h *si = (__tethering_client_h *)client;
+
+       *type = si->interface;
+
+       return TETHERING_ERROR_NONE;
+}
+
+int tethering_client_get_name(tethering_client_h client, char **name)
+{
+       _retvm_if(client == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(client) is NULL\n");
+       _retvm_if(name == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(name) is NULL\n");
+
+       __tethering_client_h *si = (__tethering_client_h *)client;
+
+       *name = strdup(si->hostname);
+       if (*name == NULL) {
+               ERR("strdup is failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+int tethering_client_get_ip_address(tethering_client_h client, tethering_address_family_e address_family, char **ip_address)
+{
+       _retvm_if(client == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(client) is NULL\n");
+       _retvm_if(ip_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(ip_address) is NULL\n");
+
+       __tethering_client_h *si = (__tethering_client_h *)client;
+
+       *ip_address = strdup(si->ip);
+       if (*ip_address == NULL) {
+               ERR("strdup is failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
+int tethering_client_get_mac_address(tethering_client_h client, char **mac_address)
+{
+       _retvm_if(client == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(client) is NULL\n");
+       _retvm_if(mac_address == NULL, TETHERING_ERROR_INVALID_PARAMETER,
+                       "Parameter(mac_address) is NULL\n");
+
+       __tethering_client_h *si = (__tethering_client_h *)client;
+
+       *mac_address = strdup(si->mac);
+       if (*mac_address == NULL) {
+               ERR("strdup is failed\n");
+               return TETHERING_ERROR_OUT_OF_MEMORY;
+       }
+
+       return TETHERING_ERROR_NONE;
+}
+
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
new file mode 100644 (file)
index 0000000..7715cac
--- /dev/null
@@ -0,0 +1,17 @@
+SET(fw_test "${fw_name}-test")
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(${fw_test} REQUIRED glib-2.0)
+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("${src_name}")
+    ADD_EXECUTABLE(${src_name} ${src})
+    TARGET_LINK_LIBRARIES(${src_name} ${fw_name} ${${fw_test}_LDFLAGS})
+ENDFOREACH()
diff --git a/test/tethering_test.c b/test/tethering_test.c
new file mode 100644 (file)
index 0000000..a0f8ffc
--- /dev/null
@@ -0,0 +1,650 @@
+/*
+* Copyright (c) 2011 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+
+#include <vconf.h>
+
+#include "tethering.h"
+
+#define INPUT_BUF_LEN          32
+#define DISABLE_REASON_TEXT_LEN        64
+#define COMMON_STR_BUF_LEN     32
+
+typedef struct {
+       tethering_enabled_cb enabled_cb;
+       tethering_disabled_cb disabled_cb;
+       tethering_connection_state_changed_cb changed_cb;
+} __tethering_cbs;
+
+static GMainLoop *mainloop = NULL;
+
+static bool __is_err(tethering_error_e ret)
+{
+       char *err_msg = NULL;
+
+       switch (ret) {
+       case TETHERING_ERROR_INVALID_PARAMETER:
+               err_msg = "Wrong parameter is used";
+               break;
+
+       case TETHERING_ERROR_OUT_OF_MEMORY:
+               err_msg = "Memory is not enough";
+               break;
+
+       case TETHERING_ERROR_NONE:
+               return false;
+
+       case TETHERING_ERROR_NOT_ENABLED:
+               err_msg = "Tethering is not enabled";
+               break;
+
+       case TETHERING_ERROR_OPERATION_FAILED:
+               err_msg = "Operation is failed";
+               break;
+
+       case TETHERING_ERROR_RESOURCE_BUSY:
+               err_msg = "Resource is busy";
+               break;
+
+       default:
+               err_msg = "This should not be happened";
+               break;
+       }
+
+       g_print("%s\n", err_msg);
+
+       return true;
+}
+
+static const char *__convert_tethering_type_to_str(const tethering_type_e type)
+{
+       static char str_buf[COMMON_STR_BUF_LEN] = {0, };
+
+       switch (type) {
+       case TETHERING_TYPE_USB:
+               g_strlcpy(str_buf, "USB", sizeof(str_buf));
+               break;
+
+       case TETHERING_TYPE_WIFI:
+               g_strlcpy(str_buf, "Wi-Fi", sizeof(str_buf));
+               break;
+
+       case TETHERING_TYPE_BT:
+               g_strlcpy(str_buf, "Bluetooth", sizeof(str_buf));
+               break;
+
+       default:
+               g_strlcpy(str_buf, "Unknown", sizeof(str_buf));
+               break;
+       }
+
+       return str_buf;
+}
+
+static const char *__convert_disabled_code_to_str(const tethering_disabled_cause_e code)
+{
+       static char str_buf[DISABLE_REASON_TEXT_LEN] = {0, };
+
+       switch (code) {
+       case TETHERING_DISABLED_BY_USB_DISCONNECTION:
+               strncpy(str_buf, "disabled due to usb disconnection", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_FLIGHT_MODE:
+               strncpy(str_buf, "disabled due to flight mode on", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_LOW_BATTERY:
+               strncpy(str_buf, "disabled due to low battery", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_NETWORK_CLOSE:
+               strncpy(str_buf, "disabled due to pdp network close", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_TIMEOUT:
+               strncpy(str_buf, "disabled due to timeout", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_MDM_ON:
+               strncpy(str_buf, "disabled due to mdm on", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_OTHERS:
+               strncpy(str_buf, "disabled by other apps", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_REQUEST:
+               strncpy(str_buf, "disabled by my request", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_WIFI_ON:
+               strncpy(str_buf, "disabled by Wi-Fi station on", sizeof(str_buf));
+               break;
+
+       case TETHERING_DISABLED_BY_BT_OFF:
+               strncpy(str_buf, "disabled by bluetooth off", sizeof(str_buf));
+               break;
+
+       default:
+               strncpy(str_buf, "disabled by unknown reason", sizeof(str_buf));
+               break;
+       }
+
+       return str_buf;
+}
+
+static void __register_cbs(tethering_h th, __tethering_cbs *cbs, void *user_data)
+{
+       tethering_error_e ret = TETHERING_ERROR_NONE;
+
+       ret = tethering_set_enabled_cb(th, TETHERING_TYPE_ALL,
+                       cbs->enabled_cb, user_data);
+       if (__is_err(ret) == true) {
+               g_print("tethering_set_enabled_cb is failed\n");
+       }
+
+       ret = tethering_set_disabled_cb(th, TETHERING_TYPE_ALL,
+                       cbs->disabled_cb, user_data);
+       if (__is_err(ret) == true) {
+               g_print("tethering_set_disabled_cb is failed\n");
+       }
+
+       ret = tethering_set_connection_state_changed_cb(th, TETHERING_TYPE_ALL,
+                       cbs->changed_cb, user_data);
+       if (__is_err(ret) == true) {
+               g_print("tethering_set_connection_state_changed_cb is failed\n");
+       }
+
+       return;
+}
+
+static void __deregister_cbs(tethering_h th)
+{
+       tethering_error_e ret = TETHERING_ERROR_NONE;
+
+       ret = tethering_unset_enabled_cb(th, TETHERING_TYPE_ALL);
+       if (__is_err(ret) == true) {
+               g_print("tethering_unset_enabled_cb is failed\n");
+       }
+
+       ret = tethering_unset_disabled_cb(th, TETHERING_TYPE_ALL);
+       if (__is_err(ret) == true) {
+               g_print("tethering_unset_disabled_cb is failed\n");
+       }
+
+       ret = tethering_unset_connection_state_changed_cb(th, TETHERING_TYPE_ALL);
+       if (__is_err(ret) == true) {
+               g_print("tethering_unset_connection_state_changed_cb is failed\n");
+       }
+
+       return;
+}
+
+/* Tethering callbacks */
+static void __enabled_cb(tethering_error_e error, tethering_type_e type, bool is_requested, void *data)
+{
+       if (error != TETHERING_ERROR_NONE) {
+               if (!is_requested) {
+                       return;
+               }
+
+               g_print("## %s tethering is not enabled. error code[0x%X]\n",
+                               __convert_tethering_type_to_str(type),
+                               error);
+               return;
+       }
+
+       if (is_requested)
+               g_print("## %s tethering is enabled successfully\n",
+                               __convert_tethering_type_to_str(type));
+       else
+               g_print("## %s tethering is enabled by other app\n",
+                               __convert_tethering_type_to_str(type));
+
+       return;
+}
+
+static void __disabled_cb(tethering_error_e error, tethering_type_e type, tethering_disabled_cause_e code, void *data)
+{
+       if (error != TETHERING_ERROR_NONE) {
+               if (code != TETHERING_DISABLED_BY_REQUEST) {
+                       return;
+               }
+
+               g_print("## %s tethering is not disabled. error code[0x%X]\n",
+                               __convert_tethering_type_to_str(type), error);
+               return;
+       }
+
+       g_print("## %s tethering is %s\n",
+                       __convert_tethering_type_to_str(type),
+                       __convert_disabled_code_to_str(code));
+
+       return;
+}
+
+static void __connection_state_changed_cb(tethering_client_h client, bool open, void *data)
+{
+       tethering_client_h clone = NULL;
+       tethering_type_e type;
+       char *ip_address = NULL;
+       char *mac_address = NULL;
+       char *hostname = NULL;
+
+       tethering_client_clone(&clone, client);
+       if (clone == NULL) {
+               g_print("tetheirng_client_clone is failed\n");
+               return;
+       }
+
+       tethering_client_get_tethering_type(clone, &type);
+       tethering_client_get_ip_address(clone,
+                       TETHERING_ADDRESS_FAMILY_IPV4, &ip_address);
+       tethering_client_get_mac_address(clone, &mac_address);
+       tethering_client_get_name(clone, &hostname);
+
+       if (open) {
+               g_print("## New station Type [%s], IP [%s], MAC [%s], hostname [%s]\n",
+                               __convert_tethering_type_to_str(type),
+                               ip_address, mac_address, hostname);
+       } else {
+               g_print("## Disconnected station Type [%s], IP [%s], MAC [%s], hostname [%s]\n",
+                               __convert_tethering_type_to_str(type),
+                               ip_address, mac_address, hostname);
+       }
+
+       if (ip_address)
+               free(ip_address);
+       if (mac_address)
+               free(mac_address);
+       if (hostname)
+               free(hostname);
+
+       tethering_client_destroy(clone);
+
+       return;
+}
+
+static void __data_usage_cb(tethering_error_e result, unsigned long long received_data,
+               unsigned long long sent_data, void *user_data)
+{
+       g_print("__data_usage_cb\n");
+
+       if (result != TETHERING_ERROR_NONE) {
+               g_print("tethering_get_data_usage is failed. error[0x%X]\n", result);
+               return;
+       }
+
+       g_print("## Received data : %llu bytes\n", received_data);
+       g_print("## Sent data : %llu bytes\n", sent_data);
+
+       return;
+}
+
+static bool __clients_foreach_cb(tethering_client_h client, void *data)
+{
+       tethering_client_h clone = NULL;
+       tethering_type_e type;
+       char *ip_address = NULL;
+       char *mac_address = NULL;
+       char *hostname = NULL;
+
+       /* Clone internal information */
+       if (tethering_client_clone(&clone, client) != TETHERING_ERROR_NONE) {
+               g_print("tethering_client_clone is failed\n");
+               return false;
+       }
+
+       /* Get information */
+       if (tethering_client_get_tethering_type(clone, &type) != TETHERING_ERROR_NONE) {
+               g_print("tethering_client_get_type is failed\n");
+       }
+
+       if (tethering_client_get_ip_address(clone, TETHERING_ADDRESS_FAMILY_IPV4, &ip_address) != TETHERING_ERROR_NONE) {
+               g_print("tethering_client_get_ip_address is failed\n");
+       }
+
+       if (tethering_client_get_mac_address(clone, &mac_address) != TETHERING_ERROR_NONE) {
+               g_print("tethering_client_get_mac_address is failed\n");
+       }
+
+       if (tethering_client_get_name(clone, &hostname) != TETHERING_ERROR_NONE) {
+               g_print("tethering_client_get_hostname is failed\n");
+       }
+       /* End of getting information */
+
+       g_print("\n< Client Info. >\n");
+       g_print("\tType %s\n", __convert_tethering_type_to_str(type));
+       g_print("\tIP Address %s\n", ip_address);
+       g_print("\tMAC Address : %s\n", mac_address);
+       g_print("\tHostname : %s\n", hostname);
+
+       /* Destroy cloned objects */
+       if (ip_address)
+               free(ip_address);
+       if (mac_address)
+               free(mac_address);
+       if (hostname)
+               free(hostname);
+
+       tethering_client_destroy(clone);
+
+       /* Continue iteration */
+       return true;
+}
+/* End of tethering callbacks */
+
+static void __enable_tethering(tethering_h th, tethering_type_e type)
+{
+       if (th == NULL)
+               return;
+
+       tethering_error_e error = TETHERING_ERROR_NONE;
+
+       error = tethering_enable(th, type);
+       __is_err(error);
+
+       return;
+}
+
+static void __disable_tethering(tethering_h th, tethering_type_e type)
+{
+       if (th == NULL)
+               return;
+
+       tethering_error_e error = TETHERING_ERROR_NONE;
+
+       error = tethering_disable(th, type);
+       __is_err(error);
+
+       return;
+}
+
+static void __print_interface_info(tethering_h th, tethering_type_e type)
+{
+       char *interface = NULL;
+       char *mac_address = NULL;
+       char *ip_address = NULL;
+       char *gateway_address = NULL;
+       char *subnet_mask = NULL;
+
+       if (tethering_is_enabled(th, type) == FALSE) {
+               g_print("%s tethering is not enabled\n",
+                               __convert_tethering_type_to_str(type));
+               return;
+       }
+
+       tethering_get_network_interface_name(th, type, &interface);
+       tethering_get_mac_address(th, type, &mac_address);
+       tethering_get_ip_address(th, type, TETHERING_ADDRESS_FAMILY_IPV4,
+                       &ip_address);
+       tethering_get_gateway_address(th, type, TETHERING_ADDRESS_FAMILY_IPV4,
+                       &gateway_address);
+       tethering_get_subnet_mask(th, type, TETHERING_ADDRESS_FAMILY_IPV4,
+                       &subnet_mask);
+
+       g_print("interface name : %s\n", interface);
+       g_print("mac address : %s\n", mac_address);
+       g_print("ip address : %s\n", ip_address);
+       g_print("gateway address: %s\n", gateway_address);
+       g_print("subnet mask : %s\n", subnet_mask);
+
+       if (interface)
+               free(interface);
+       if (mac_address)
+               free(mac_address);
+       if (ip_address)
+               free(ip_address);
+       if (gateway_address)
+               free(gateway_address);
+       if (subnet_mask)
+               free(subnet_mask);
+
+       return;
+}
+
+static void __print_wifi_tethering_setting(tethering_h th)
+{
+       char *ssid = NULL;
+       char *passphrase = NULL;
+       bool visibility = false;
+       tethering_wifi_security_type_e security_type = TETHERING_WIFI_SECURITY_TYPE_NONE;
+
+       int error = TETHERING_ERROR_NONE;
+
+       error = tethering_wifi_get_ssid(th, &ssid);
+       if (error != TETHERING_ERROR_NONE)
+               __is_err(error);
+       else
+               g_print("\n\t** WiFi tethering SSID : %s\n", ssid);
+
+       error = tethering_wifi_get_passphrase(th, &passphrase);
+       if (error != TETHERING_ERROR_NONE)
+               __is_err(error);
+       else
+               g_print("\t** WiFi tethering passphrase : %s\n", passphrase);
+
+       error = tethering_wifi_get_ssid_visibility(th, &visibility);
+       if (error != TETHERING_ERROR_NONE)
+               __is_err(error);
+       else
+               g_print("\t** WiFi tethering ssid visibility : %s\n",
+                               visibility ? "visible" : "invisible");
+
+       error = tethering_wifi_get_security_type(th, &security_type);
+       if (error != TETHERING_ERROR_NONE)
+               __is_err(error);
+       else
+               g_print("\t** WiFi tethering security_type : %s\n",
+                               security_type ==
+                               TETHERING_WIFI_SECURITY_TYPE_NONE ?
+                               "open" : "wpa2-psk");
+
+       if (ssid)
+               free(ssid);
+       if (passphrase)
+               free(passphrase);
+
+       return;
+}
+
+void print_menu(void)
+{
+       g_print("\nTo get client information, enter 'clients [USB | WIFI | BT | ALL]'");
+       g_print("\nTo get interface information, enter 'info [USB | WIFI | BT]'");
+       g_print("\nTo get data usage, enter 'get data_usage'");
+       g_print("\nTo enable tethering, enter 'enable [USB | WIFI | BT | ALL]'");
+       g_print("\nTo disable tethering, enter 'disable [USB | WIFI | BT | ALL]'");
+       g_print("\nTo get Wi-Fi tethering setting, enter 'get wifi_setting'");
+       g_print("\nTo set Wi-Fi tethering setting, enter '[set_security_type | set_visibility] [0 | 1]'");
+       g_print("\nTo set Wi-Fi tethering passphrase, enter 'set_passphrase [passphrase]'");
+       g_print("\nTo quit, enter 'quit'\n> ");
+
+       return;
+}
+
+gboolean input(GIOChannel *channel, GIOCondition condition, gpointer data)
+{
+       tethering_h th = (tethering_h)data;
+       tethering_type_e type = 0;
+       tethering_error_e error = 0;
+       gchar buf[INPUT_BUF_LEN] = {0, };
+       gchar *cmd = NULL;
+       gchar *param = NULL;
+       gsize read = 0;
+
+#if !GLIB_CHECK_VERSION(2, 31, 0)
+       if (g_io_channel_read(channel, buf, INPUT_BUF_LEN, &read) != G_IO_ERROR_NONE) {
+               g_print("g_io_channel_read is failed\n");
+               return FALSE;
+       }
+#else
+       GError *err = NULL;
+
+       g_io_channel_read_chars(channel, buf, INPUT_BUF_LEN, &read, &err);
+       if (err != NULL) {
+               g_print("g_io_channel_read is failed : %s\n", err->message);
+               g_error_free(err);
+               return FALSE;
+       }
+#endif
+
+       buf[read] = '\0';
+       g_strstrip(buf);
+
+       cmd = buf;
+       param = strrchr(buf, ' ');
+
+       /* No parameter */
+       if (!strcmp(cmd, "quit")) {
+               g_main_loop_quit(mainloop);
+               return TRUE;
+       }
+
+       if (param == NULL) {
+               print_menu();
+               return TRUE;
+       }
+       *param = '\0';
+       param++;
+
+       /* One parameter except type */
+       if (!strcmp(cmd, "get") && !strcmp(param, "data_usage")) {
+               error = tethering_get_data_usage(th, __data_usage_cb, NULL);
+               if (error != TETHERING_ERROR_NONE)
+                       g_print("tethering_get_data_usage is failed [0x%X]\n",
+                                       error);
+               goto DONE;
+       }
+
+       if (!strcmp(cmd, "get") && !strcmp(param, "wifi_setting")) {
+               __print_wifi_tethering_setting(th);
+               goto DONE;
+       }
+
+       if (!strcmp(cmd, "set_visibility")) {
+               error = tethering_wifi_set_ssid_visibility(th, atoi(param));
+               if (error != TETHERING_ERROR_NONE)
+                       g_print("tethering_wifi_set_ssid_visibility is failed [0x%X]\n",
+                                       error);
+               goto DONE;
+       }
+
+       if (!strcmp(cmd, "set_security_type")) {
+               error = tethering_wifi_set_security_type(th, atoi(param));
+               if (error != TETHERING_ERROR_NONE)
+                       g_print("tethering_wifi_set_security_type is failed [0x%X]\n",
+                                       error);
+               goto DONE;
+       }
+
+       /* This should be removed */
+       if (!strcmp(cmd, "set_passphrase")) {
+               error = tethering_wifi_set_passphrase(th, param);
+               if (error != TETHERING_ERROR_NONE)
+                       g_print("tethering_wifi_set_passphrase is failed [0x%X]\n",
+                                       error);
+               goto DONE;
+       }
+
+       /* One parameter(type) */
+       if (!strcmp(param, "USB"))
+               type = TETHERING_TYPE_USB;
+       else if (!strcmp(param, "WIFI"))
+               type = TETHERING_TYPE_WIFI;
+       else if (!strcmp(param, "BT"))
+               type = TETHERING_TYPE_BT;
+       else if (!strcmp(param, "ALL"))
+               type = TETHERING_TYPE_ALL;
+       else {
+               goto DONE;
+       }
+
+       if (!strcmp(cmd, "clients")) {
+               error = tethering_foreach_connected_clients(th, type,
+                               __clients_foreach_cb, NULL);
+               if (error != TETHERING_ERROR_NONE)
+                       g_print("tethering_get_data_usage is failed [0x%X]\n",
+                                       error);
+       } else if (!strcmp(cmd, "info")) {
+               __print_interface_info(th, type);
+       } else if (!strcmp(cmd, "enable")) {
+               __enable_tethering(th, type);
+       } else if (!strcmp(cmd, "disable")) {
+               __disable_tethering(th, type);
+       } else {
+               goto DONE;
+       }
+
+DONE:
+       print_menu();
+       return TRUE;
+}
+
+int main(int argc, char *argv[])
+{
+       tethering_h th = NULL;
+       GIOChannel *stdin_channel = NULL;
+       tethering_error_e ret = TETHERING_ERROR_NONE;
+       __tethering_cbs cbs = {__enabled_cb, __disabled_cb, __connection_state_changed_cb};
+
+       g_type_init();
+
+       /* Create tethering handle */
+       ret = tethering_create(&th);
+       if (__is_err(ret) == true)
+               return 0;
+
+       /* Register cbs */
+       __register_cbs(th, &cbs, NULL);
+
+       stdin_channel = g_io_channel_unix_new(0);
+       if (stdin_channel == NULL)
+               return 0;
+
+       g_io_channel_set_encoding(stdin_channel, NULL, NULL);
+       g_io_channel_set_flags(stdin_channel,
+                       G_IO_FLAG_APPEND | G_IO_FLAG_NONBLOCK, NULL);
+
+       g_io_add_watch(stdin_channel, G_IO_IN, input, (gpointer)th);
+
+       print_menu();
+
+       mainloop = g_main_loop_new (NULL, 0);
+
+       g_main_loop_run(mainloop);
+       g_main_loop_unref(mainloop);
+
+       /* Deregister cbs */
+       __deregister_cbs(th);
+
+       /* Destroy tethering handle */
+       ret = tethering_destroy(th);
+       __is_err(ret);
+
+       return 0;
+}
+