From 076bad614ace90921ac301ad58eb8424db082232 Mon Sep 17 00:00:00 2001 From: Seungyoun Ju Date: Tue, 21 Aug 2012 18:21:17 +0900 Subject: [PATCH] Source code upload --- CMakeLists.txt | 100 ++ capi-network-tethering.pc.in | 14 + debian/capi-network-tethering-dev.install | 4 + debian/capi-network-tethering.install | 1 + debian/capi-network-tethering.postinst | 1 + debian/changelog | 25 + debian/compat | 1 + debian/control | 21 + debian/rules | 64 ++ include/marshal.list | 3 + include/tethering.h | 639 +++++++++++ include/tethering.xml | 178 +++ include/tethering_private.h | 256 +++++ packaging/capi-network-tethering.spec | 73 ++ src/tethering.c | 1782 +++++++++++++++++++++++++++++ src/tethering_client.c | 119 ++ test/CMakeLists.txt | 17 + test/tethering_test.c | 650 +++++++++++ 18 files changed, 3948 insertions(+) create mode 100644 CMakeLists.txt create mode 100644 capi-network-tethering.pc.in create mode 100644 debian/capi-network-tethering-dev.install create mode 100644 debian/capi-network-tethering.install create mode 100644 debian/capi-network-tethering.postinst create mode 100644 debian/changelog create mode 100644 debian/compat create mode 100644 debian/control create mode 100755 debian/rules create mode 100644 include/marshal.list create mode 100644 include/tethering.h create mode 100644 include/tethering.xml create mode 100644 include/tethering_private.h create mode 100644 packaging/capi-network-tethering.spec create mode 100644 src/tethering.c create mode 100644 src/tethering_client.c create mode 100644 test/CMakeLists.txt create mode 100644 test/tethering_test.c diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..7381298 --- /dev/null +++ b/CMakeLists.txt @@ -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 index 0000000..fc8c18b --- /dev/null +++ b/capi-network-tethering.pc.in @@ -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 index 0000000..761a28b --- /dev/null +++ b/debian/capi-network-tethering-dev.install @@ -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 index 0000000..4a755a4 --- /dev/null +++ b/debian/capi-network-tethering.install @@ -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 index 0000000..1a24852 --- /dev/null +++ b/debian/capi-network-tethering.postinst @@ -0,0 +1 @@ +#!/bin/sh diff --git a/debian/changelog b/debian/changelog new file mode 100644 index 0000000..764f434 --- /dev/null +++ b/debian/changelog @@ -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 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 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 Thu, 29 Mar 2012 10:33:07 +0900 diff --git a/debian/compat b/debian/compat new file mode 100644 index 0000000..7ed6ff8 --- /dev/null +++ b/debian/compat @@ -0,0 +1 @@ +5 diff --git a/debian/control b/debian/control new file mode 100644 index 0000000..ce02659 --- /dev/null +++ b/debian/control @@ -0,0 +1,21 @@ +Source: capi-network-tethering +Section: libs +Priority: extra +Maintainer: Kangho Hur , ByungWoo Lee , Seungyoun Ju , Hocheol Seo +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 index 0000000..beda1a7 --- /dev/null +++ b/debian/rules @@ -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 index 0000000..410363f --- /dev/null +++ b/include/marshal.list @@ -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 index 0000000..8236c66 --- /dev/null +++ b/include/tethering.h @@ -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 + +#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 index 0000000..dbba8e1 --- /dev/null +++ b/include/tethering.xml @@ -0,0 +1,178 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/include/tethering_private.h b/include/tethering_private.h new file mode 100644 index 0000000..56e55ac --- /dev/null +++ b/include/tethering_private.h @@ -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 +#include +#include + +#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 index 0000000..c85fe30 --- /dev/null +++ b/packaging/capi-network-tethering.spec @@ -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 0.0.8-1 +- Deprecated APIs are removed + +* Wed Aug 01 2012 Seungyoun Ju 0.0.7-1 +- Managed APIs are implemented for Wi-Fi tethering settings + +* Sat Jul 21 2012 Seungyoun Ju 0.0.6-1 +- Fix tethering callback issue (JIRA S1-6197) + +* Tue Jul 10 2012 Seungyoun Ju 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 0.0.4 +- All internal APIs are implemented + +* Fri Jun 15 2012 Seungyoun Ju 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 index 0000000..e2ebbfa --- /dev/null +++ b/src/tethering.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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 index 0000000..3dca574 --- /dev/null +++ b/src/tethering_client.c @@ -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 +#include +#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 index 0000000..7715cac --- /dev/null +++ b/test/CMakeLists.txt @@ -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 index 0000000..a0f8ffc --- /dev/null +++ b/test/tethering_test.c @@ -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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#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; +} + -- 2.7.4