From 18f7993e1c13f1aa510288ade2a34632e36ce155 Mon Sep 17 00:00:00 2001 From: HyungKyu Song Date: Sat, 16 Feb 2013 00:12:33 +0900 Subject: [PATCH] Tizen 2.0 Release --- AUTHORS | 5 + CMakeLists.txt | 95 +++ LICENSE.APLv2 | 202 ++++++ NOTICE | 3 + include/emulator.h | 36 + include/log.h | 50 ++ include/mdm-private.h | 35 + include/netconfig.h | 33 + include/netdbus.h | 76 ++ include/neterror.h | 69 ++ include/netsupplicant.h | 52 ++ include/network-clock.h | 34 + include/network-state.h | 59 ++ include/network-statistics.h | 73 ++ include/signal-handler.h | 34 + include/util.h | 59 ++ include/wifi-agent.h | 55 ++ include/wifi-background-scan.h | 42 ++ include/wifi-eap-config.h | 52 ++ include/wifi-eap.h | 39 + include/wifi-indicator.h | 36 + include/wifi-power.h | 39 + include/wifi-ssid-scan.h | 51 ++ include/wifi-state.h | 75 ++ include/wifi.h | 62 ++ interfaces/netconfig-iface-network-state.xml | 17 + .../netconfig-iface-network-statistics.xml | 33 + interfaces/netconfig-iface-wifi.xml | 61 ++ net-config.manifest | 19 + packaging/net-config.spec | 118 ++++ resources/etc/dbus-1/system.d/net-config.conf | 22 + resources/etc/rc.d/init.d/net-config | 3 + resources/opt/etc/resolv.conf | 2 + .../usr/lib/systemd/system/net-config.service | 10 + .../dbus-1/services/net.netconfig.service | 4 + src/dbus/netdbus.c | 478 +++++++++++++ src/dbus/netsupplicant.c | 273 +++++++ src/main.c | 80 +++ src/neterror.c | 89 +++ src/network-clock.c | 114 +++ src/network-state.c | 666 ++++++++++++++++++ src/network-statistics.c | 452 ++++++++++++ src/signal-handler.c | 394 +++++++++++ src/utils/emulator.c | 118 ++++ src/utils/mdm-private.c | 25 + src/utils/util.c | 429 +++++++++++ src/wifi-agent.c | 193 +++++ src/wifi-background-scan.c | 234 ++++++ src/wifi-eap-config.c | 216 ++++++ src/wifi-eap.c | 471 +++++++++++++ src/wifi-indicator.c | 255 +++++++ src/wifi-power.c | 379 ++++++++++ src/wifi-ssid-scan.c | 496 +++++++++++++ src/wifi-state.c | 445 ++++++++++++ src/wifi.c | 172 +++++ 55 files changed, 7634 insertions(+) create mode 100644 AUTHORS create mode 100644 CMakeLists.txt create mode 100644 LICENSE.APLv2 create mode 100644 NOTICE create mode 100644 include/emulator.h create mode 100644 include/log.h create mode 100644 include/mdm-private.h create mode 100644 include/netconfig.h create mode 100644 include/netdbus.h create mode 100644 include/neterror.h create mode 100644 include/netsupplicant.h create mode 100644 include/network-clock.h create mode 100644 include/network-state.h create mode 100644 include/network-statistics.h create mode 100644 include/signal-handler.h create mode 100644 include/util.h create mode 100644 include/wifi-agent.h create mode 100644 include/wifi-background-scan.h create mode 100644 include/wifi-eap-config.h create mode 100644 include/wifi-eap.h create mode 100644 include/wifi-indicator.h create mode 100644 include/wifi-power.h create mode 100644 include/wifi-ssid-scan.h create mode 100644 include/wifi-state.h create mode 100644 include/wifi.h create mode 100644 interfaces/netconfig-iface-network-state.xml create mode 100644 interfaces/netconfig-iface-network-statistics.xml create mode 100644 interfaces/netconfig-iface-wifi.xml create mode 100644 net-config.manifest create mode 100644 packaging/net-config.spec create mode 100644 resources/etc/dbus-1/system.d/net-config.conf create mode 100755 resources/etc/rc.d/init.d/net-config create mode 100644 resources/opt/etc/resolv.conf create mode 100644 resources/usr/lib/systemd/system/net-config.service create mode 100644 resources/usr/share/dbus-1/services/net.netconfig.service create mode 100644 src/dbus/netdbus.c create mode 100644 src/dbus/netsupplicant.c create mode 100644 src/main.c create mode 100644 src/neterror.c create mode 100644 src/network-clock.c create mode 100644 src/network-state.c create mode 100644 src/network-statistics.c create mode 100644 src/signal-handler.c create mode 100644 src/utils/emulator.c create mode 100644 src/utils/mdm-private.c create mode 100644 src/utils/util.c create mode 100644 src/wifi-agent.c create mode 100644 src/wifi-background-scan.c create mode 100644 src/wifi-eap-config.c create mode 100644 src/wifi-eap.c create mode 100644 src/wifi-indicator.c create mode 100644 src/wifi-power.c create mode 100644 src/wifi-ssid-scan.c create mode 100644 src/wifi-state.c create mode 100644 src/wifi.c diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..df0456d --- /dev/null +++ b/AUTHORS @@ -0,0 +1,5 @@ +Danny Jeongseok Seo +Jeik Jaehyun Kim +Sunkey Lee +Sanghoon Cho +DongHoo Park \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..df45207 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,95 @@ +CMAKE_MINIMUM_REQUIRED(VERSION 2.6) +PROJECT(net-config C) +SET(PACKAGE ${PROJECT_NAME}) +SET(PREFIX ${CMAKE_INSTALL_PREFIX}) +SET(BINDIR "${PREFIX}/sbin") +SET(DATADIR "${PREFIX}/share") +SET(LIBDIR "${PREFIX}/lib") + +SET(SRCS + src/main.c + src/neterror.c + src/wifi.c + src/wifi-power.c + src/wifi-state.c + src/wifi-eap.c + src/network-clock.c + src/network-state.c + src/network-statistics.c + src/wifi-indicator.c + src/signal-handler.c + src/wifi-ssid-scan.c + src/wifi-background-scan.c + src/wifi-agent.c + src/wifi-eap-config.c + src/dbus/netdbus.c + src/dbus/netsupplicant.c + src/utils/util.c + src/utils/emulator.c + src/utils/mdm-private.c + ) + +IF("${CMAKE_BUILD_TYPE}" STREQUAL "") + SET(CMAKE_BUILD_TYPE "Release") +ENDIF("${CMAKE_BUILD_TYPE}" STREQUAL "") +MESSAGE("Build type: ${CMAKE_BUILD_TYPE}") + +INCLUDE(FindPkgConfig) +PKG_CHECK_MODULES(pkgs REQUIRED + glib-2.0 + dbus-glib-1 + dlog + vconf + wifi-direct + tapi + syspopup-caller) + +FOREACH(flag ${pkgs_CFLAGS}) + SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}") +ENDFOREACH(flag) + +SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden -Wall") +SET(CMAKE_C_FLAGS "-I${CMAKE_SOURCE_DIR}/include ${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +SET(CMAKE_C_FLAGS_DEBUG "-O0 -g") +SET(CMAKE_C_FLAGS_RELEASE "-O2") + +FIND_PROGRAM(UNAME NAMES uname) +EXEC_PROGRAM("${UNAME}" ARGS "-m" +OUTPUT_VARIABLE "ARCH") +IF("${ARCH}" STREQUAL "arm") + ADD_DEFINITIONS("-DEMBEDDED_TARGET") + MESSAGE("add -DEMBEDDED_TARGET") +ENDIF("${ARCH}" STREQUAL "arm") + +ADD_DEFINITIONS("-DPACKAGE=\"${PACKAGE}\"") +ADD_DEFINITIONS("-DPREFIX=\"${PREFIX}\"") + +SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed") + +ADD_EXECUTABLE(${PROJECT_NAME} ${SRCS}) +TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${pkgs_LDFLAGS}) + +ADD_CUSTOM_TARGET(netconfig-iface-network-state-glue.h + COMMAND dbus-binding-tool --mode=glib-server --prefix=netconfig_iface_network_state + --output=${CMAKE_SOURCE_DIR}/include/netconfig-iface-network-state-glue.h + ${CMAKE_SOURCE_DIR}/interfaces/netconfig-iface-network-state.xml + DEPENDS ${CMAKE_SOURCE_DIR}/interfaces/netconfig-iface-network-state.xml +) +ADD_CUSTOM_TARGET(netconfig-iface-network-statistics-glue.h + COMMAND dbus-binding-tool --mode=glib-server --prefix=netconfig_iface_network_statistics + --output=${CMAKE_SOURCE_DIR}/include/netconfig-iface-network-statistics-glue.h + ${CMAKE_SOURCE_DIR}/interfaces/netconfig-iface-network-statistics.xml + DEPENDS ${CMAKE_SOURCE_DIR}/interfaces/netconfig-iface-network-statistics.xml +) +ADD_CUSTOM_TARGET(netconfig-iface-wifi-glue.h + COMMAND dbus-binding-tool --mode=glib-server --prefix=netconfig_iface_wifi + --output=${CMAKE_SOURCE_DIR}/include/netconfig-iface-wifi-glue.h + ${CMAKE_SOURCE_DIR}/interfaces/netconfig-iface-wifi.xml + DEPENDS ${CMAKE_SOURCE_DIR}/interfaces/netconfig-iface-wifi.xml +) + +ADD_DEPENDENCIES(${PROJECT_NAME} netconfig-iface-network-state-glue.h) +ADD_DEPENDENCIES(${PROJECT_NAME} netconfig-iface-network-statistics-glue.h) +ADD_DEPENDENCIES(${PROJECT_NAME} netconfig-iface-wifi-glue.h) + +INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${BINDIR}) diff --git a/LICENSE.APLv2 b/LICENSE.APLv2 new file mode 100644 index 0000000..d645695 --- /dev/null +++ b/LICENSE.APLv2 @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..0e0f016 --- /dev/null +++ b/NOTICE @@ -0,0 +1,3 @@ +Copyright (c) Samsung Electronics Co., Ltd. All rights reserved. +Except as noted, this software is licensed under Apache License, Version 2. +Please, see the LICENSE.APLv2 file for Apache License terms and conditions. diff --git a/include/emulator.h b/include/emulator.h new file mode 100644 index 0000000..87914b8 --- /dev/null +++ b/include/emulator.h @@ -0,0 +1,36 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_EMULATOR_H__ +#define __NETCONFIG_EMULATOR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +gboolean netconfig_emulator_is_emulated(void); +void netconfig_emulator_test_and_start(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_EMULATOR_H__ */ diff --git a/include/log.h b/include/log.h new file mode 100644 index 0000000..8904a3d --- /dev/null +++ b/include/log.h @@ -0,0 +1,50 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_LOG_H__ +#define __NETCONFIG_LOG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#undef LOG_TAG +#define LOG_TAG "NET_CONFIG" + +#define __PRT(level, format, arg...) \ + do { \ + char *ch = strrchr(__FILE__, '/'); \ + ch = ch ? ch + 1 : __FILE__; \ + fprintf(stderr, PACKAGE": %s:%s() "format"\n", ch, __FUNCTION__, ## arg); \ + } while(0) + +#define DBG(format, arg...) LOGD(format, ## arg) +#define INFO(format, arg...) LOGI(format, ## arg) +#define WARN(format, arg...) LOGW(format, ## arg) +#define ERR(format, arg...) LOGE(format, ## arg) + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_LOG_H__ */ diff --git a/include/mdm-private.h b/include/mdm-private.h new file mode 100644 index 0000000..073e896 --- /dev/null +++ b/include/mdm-private.h @@ -0,0 +1,35 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 MDM_PRIVATE_H_ +#define MDM_PRIVATE_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +gboolean netconfig_is_wifi_allowed(void); + +#ifdef __cplusplus +} +#endif + +#endif /* MDM_PRIVATE_H_ */ diff --git a/include/netconfig.h b/include/netconfig.h new file mode 100644 index 0000000..0336419 --- /dev/null +++ b/include/netconfig.h @@ -0,0 +1,33 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_H__ +#define __NETCONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#define NETCONFIG_SERVICE "net.netconfig" + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_H__ */ diff --git a/include/netdbus.h b/include/netdbus.h new file mode 100644 index 0000000..af816d9 --- /dev/null +++ b/include/netdbus.h @@ -0,0 +1,76 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_NETDBUS_H__ +#define __NETCONFIG_NETDBUS_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#define CONNMAN_SERVICE "net.connman" +#define CONNMAN_PATH "/net/connman" + +#define CONNMAN_CLOCK_INTERFACE CONNMAN_SERVICE ".Clock" +#define CONNMAN_MANAGER_INTERFACE CONNMAN_SERVICE ".Manager" +#define CONNMAN_SERVICE_INTERFACE CONNMAN_SERVICE ".Service" +#define CONNMAN_TECHNOLOGY_INTERFACE CONNMAN_SERVICE ".Technology" +#define CONNMAN_MANAGER_PATH "/" + +#define CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/cellular_" +#define CONNMAN_WIFI_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/wifi_" +#define CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/ethernet_" +#define CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX CONNMAN_PATH "/service/bluetooth_" +#define CONNMAN_WIFI_TECHNOLOGY_PREFIX CONNMAN_PATH "/technology/wifi" + +#define NETCONFIG_WIFI_INTERFACE "net.netconfig.wifi" +#define NETCONFIG_WIFI_PATH "/net/netconfig/wifi" + +#define DBUS_PATH_MAX_BUFLEN 512 +#define DBUS_STATE_MAX_BUFLEN 64 + +typedef enum { + NETCONFIG_DBUS_RESULT_GET_BGSCAN_MODE, + NETCONFIG_DBUS_RESULT_DEFAULT_TECHNOLOGY, +} netconfig_dbus_result_type; + +gboolean netconfig_is_cellular_profile(const char *profile); +gboolean netconfig_is_wifi_profile(const char *profile); +gboolean netconfig_is_ethernet_profile(const char *profile); +gboolean netconfig_is_bluetooth_profile(const char *profile); + +char *netconfig_wifi_get_connected_service_name(DBusMessage *message); +DBusMessage *netconfig_invoke_dbus_method(const char *dest, const char *path, + const char *interface_name, const char *method, char *param_array[]); +gboolean netconfig_dbus_get_basic_params_string(DBusMessage *message, + char **key, void **value); +gboolean netconfig_dbus_get_basic_params_array(DBusMessage *message, + char **key, void **value); + +DBusGConnection *netconfig_setup_dbus(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_NETDBUS_H__ */ diff --git a/include/neterror.h b/include/neterror.h new file mode 100644 index 0000000..98b0f4b --- /dev/null +++ b/include/neterror.h @@ -0,0 +1,69 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_ERROR_H__ +#define __NETCONFIG_ERROR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "glib.h" + +G_BEGIN_DECLS + +typedef enum { + NETCONFIG_NO_ERROR = 0x00, + NETCONFIG_ERROR_INTERNAL = 0x01, + NETCONFIG_ERROR_NO_SERVICE = 0x02, + NETCONFIG_ERROR_TRASPORT = 0x03, + NETCONFIG_ERROR_NO_PROFILE = 0x04, + NETCONFIG_ERROR_WRONG_PROFILE = 0x05, + NETCONFIG_ERROR_WIFI_LOAD_INPROGRESS = 0x06, + NETCONFIG_ERROR_WIFI_DRIVER_FAILURE = 0x07, + NETCONFIG_ERROR_SECURITY_RESTRICTED = 0x08, + NETCONFIG_ERROR_FAILED_GET_IMSI = 0x09, + NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH = 0x0A, + NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH_WRONG_PARAM = 0x0B, + NETCONFIG_ERROR_FAILED_GET_SIM_AUTH_WRONG_DATA = 0x0C, + NETCONFIG_ERROR_FAILED_GET_SIM_AUTH_DELAY = 0x0D, + NETCONFIG_ERROR_MAX = 0x0E, +} NETCONFIG_ERROR; + +GQuark netconfig_error_quark(void); + +#define NETCONFIG_ERROR_QUARK (netconfig_error_quark()) + +G_END_DECLS + +#ifdef __cplusplus +} +#endif + +void netconfig_error_wifi_load_inprogress(GError **error); +void netconfig_error_wifi_driver_failed(GError **error); +void netconfig_error_security_restricted(GError **error); +void netconfig_error_wifi_direct_failed(GError **error); +void netconfig_error_fail_get_imsi(GError **error); +void netconfig_error_fail_req_sim_auth(GError **error); +void netconfig_error_fail_req_sim_auth_wrong_param(GError **error); +void netconfig_error_fail_get_sim_auth_wrong_data(GError **error); +void netconfig_error_fail_get_sim_auth_delay(GError **error); + +#endif /* __NETCONFIG_ERROR_H__ */ diff --git a/include/netsupplicant.h b/include/netsupplicant.h new file mode 100644 index 0000000..ea5ae37 --- /dev/null +++ b/include/netsupplicant.h @@ -0,0 +1,52 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_NETSUPPLICANT_H__ +#define __NETCONFIG_NETSUPPLICANT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +#define SUPPLICANT_SERVICE "fi.w1.wpa_supplicant1" +#define SUPPLICANT_INTERFACE "fi.w1.wpa_supplicant1" +#define SUPPLICANT_PATH "/fi/w1/wpa_supplicant1" +#define SUPPLICANT_GLOBAL_INTERFACE "org.freedesktop.DBus.Properties" + +struct dbus_input_arguments { + int type; + void *data; +}; + +gboolean netconfig_wifi_get_ifname(char **ifname); +gboolean netconfig_wifi_get_supplicant_interface(char **path); +DBusMessage *netconfig_supplicant_invoke_dbus_method(const char *dest, + DBusConnection *connection, + const char *path, const char *interface_name, + const char *method, GList *args); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_NETSUPPLICANT_H__ */ diff --git a/include/network-clock.h b/include/network-clock.h new file mode 100644 index 0000000..4b1b810 --- /dev/null +++ b/include/network-clock.h @@ -0,0 +1,34 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_NETWORK_CLOCK_H__ +#define __NETCONFIG_NETWORK_CLOCK_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void netconfig_clock_init(void); +void netconfig_clock_deinit(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_NETWORK_CLOCK_H__ */ diff --git a/include/network-state.h b/include/network-state.h new file mode 100644 index 0000000..0f180c8 --- /dev/null +++ b/include/network-state.h @@ -0,0 +1,59 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_NETWORK_STATE_H__ +#define __NETCONFIG_NETWORK_STATE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +G_BEGIN_DECLS + +typedef struct NetconfigNetworkState NetconfigNetworkState; +typedef struct NetconfigNetworkStateClass NetconfigNetworkStateClass; + +#define NETCONFIG_TYPE_NETWORK_STATE ( netconfig_network_state_get_type() ) +#define NETCONFIG_NETWORK_STATE(obj) ( G_TYPE_CHECK_INSTANCE_CAST( (obj),NETCONFIG_TYPE_NETWORK_STATE, NetconfigNetworkState ) ) +#define NETCONFIG_IS_NETWORK_STATE(obj) (G_TYPE_CHECK_INSTANCE_TYPE( (obj), NETCONFIG_TYPE_NETWORK_STATE) ) + +#define NETCONFIG_NETWORK_STATE_CLASS(klass) ( G_TYPE_CHECK_CLASS_CAST( (klass), NETCONFIG_TYPE_NETWORK_STATE, NetconfigNetworkStateClass) ) +#define NETCONFIG_IS_NETWORK_STATE_CLASS(klass) ( G_TYPE_CHECK_CLASS_TYPE( (klass), NETCONFIG_TYPE_NETWORK_STATE) ) +#define NETCONFIG_NETWORK_STATE_GET_CLASS(obj) ( G_TYPE_INSTANCE_GET_CLASS( (obj), NETCONFIG_TYPE_NETWORK_STATE, NetconfigNetworkStateClass ) ) + +GType netconfig_network_state_get_type(void); + +gpointer netconfig_network_state_create_and_init(DBusGConnection *conn); + +const char *netconfig_get_default_profile(void); +const char *netconfig_get_default_ipaddress(void); +const char *netconfig_get_default_proxy(void); +const char *netconfig_wifi_get_connected_essid(const char *default_profile); +void netconfig_set_default_profile(const char *profile); + +G_END_DECLS + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_NETWORK_STATE_H__ */ diff --git a/include/network-statistics.h b/include/network-statistics.h new file mode 100644 index 0000000..ba5883a --- /dev/null +++ b/include/network-statistics.h @@ -0,0 +1,73 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 NETWORK_STATISTICS_H_ +#define NETWORK_STATISTICS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +#include + +G_BEGIN_DECLS + +typedef struct NetconfigNetworkStatistics NetconfigNetworkStatistics; +typedef struct NetconfigNetworkStatisticsClass NetconfigNetworkStatisticsClass; + +#define NETCONFIG_TYPE_NETWORK_STATISTICS ( netconfig_network_statistics_get_type() ) +#define NETCONFIG_NETWORK_STATISTICS(obj) ( G_TYPE_CHECK_INSTANCE_CAST( (obj),NETCONFIG_TYPE_NETWORK_STATISTICS, NetconfigNetworkStatistics ) ) +#define NETCONFIG_IS_NETWORK_STATISTICS(obj) (G_TYPE_CHECK_INSTANCE_TYPE( (obj), NETCONFIG_TYPE_NETWORK_STATISTICS) ) + +#define NETCONFIG_NETWORK_STATISTICS_CLASS(klass) ( G_TYPE_CHECK_CLASS_CAST( (klass), NETCONFIG_TYPE_NETWORK_STATISTICS, NetconfigNetworkStatisticsClass) ) +#define NETCONFIG_IS_NETWORK_STATISTICS_CLASS(klass) ( G_TYPE_CHECK_CLASS_TYPE( (klass), NETCONFIG_TYPE_NETWORK_STATISTICS) ) +#define NETCONFIG_NETWORK_STATISTICS_GET_CLASS(obj) ( G_TYPE_INSTANCE_GET_CLASS( (obj), NETCONFIG_TYPE_NETWORK_STATISTICS, NetconfigNetworkStatisticsClass ) ) + +GType netconfig_network_statistics_get_type(void); + +gpointer netconfig_network_statistics_create_and_init(DBusGConnection *conn); + + +gboolean netconfig_iface_network_statistics_get_wifi_total_tx_bytes(NetconfigNetworkStatistics *network_statistics, guint64 *total_bytes, GError **error); +gboolean netconfig_iface_network_statistics_get_wifi_total_rx_bytes(NetconfigNetworkStatistics *network_statistics, guint64 *total_bytes, GError **error); +gboolean netconfig_iface_network_statistics_get_wifi_last_tx_bytes(NetconfigNetworkStatistics *network_statistics, guint64 *last_bytes, GError **error); +gboolean netconfig_iface_network_statistics_get_wifi_last_rx_bytes(NetconfigNetworkStatistics *network_statistics, guint64 *last_bytes, GError **error); + +gboolean netconfig_iface_network_statistics_reset_cellular_total_tx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error); +gboolean netconfig_iface_network_statistics_reset_cellular_total_rx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error); +gboolean netconfig_iface_network_statistics_reset_cellular_last_tx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error); +gboolean netconfig_iface_network_statistics_reset_cellular_last_rx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error); + +gboolean netconfig_iface_network_statistics_reset_wifi_total_tx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error); +gboolean netconfig_iface_network_statistics_reset_wifi_total_rx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error); +gboolean netconfig_iface_network_statistics_reset_wifi_last_tx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error); +gboolean netconfig_iface_network_statistics_reset_wifi_last_rx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error); + +void netconfig_wifi_statistics_update_powered_off(void); + +G_END_DECLS + +#ifdef __cplusplus +} +#endif + +#endif /* NETWORK_STATISTICS_H_ */ diff --git a/include/signal-handler.h b/include/signal-handler.h new file mode 100644 index 0000000..d802ef8 --- /dev/null +++ b/include/signal-handler.h @@ -0,0 +1,34 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_SIGNAL_HANDLER_H__ +#define __NETCONFIG_SIGNAL_HANDLER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +void netconfig_register_signal(void); +void netconfig_deregister_signal(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_SIGNAL_HANDLER_H__ */ diff --git a/include/util.h b/include/util.h new file mode 100644 index 0000000..8a37f8a --- /dev/null +++ b/include/util.h @@ -0,0 +1,59 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_UTIL_H__ +#define __NETCONFIG_UTIL_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +#include "wifi.h" + +GKeyFile *netconfig_keyfile_load(const char *pathname); +void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname); + +void netconfig_start_timer_seconds(guint secs, + gboolean(*callback) (gpointer), void *user_data, guint *timer_id); +void netconfig_start_timer(guint msecs, + gboolean(*callback) (gpointer), void *user_data, guint *timer_id); +void netconfig_stop_timer(guint *timer_id); + +void netconfig_wifi_device_picker_service_start(void); +void netconfig_wifi_device_picker_service_stop(void); + +gboolean netconfig_is_wifi_direct_on(void); +gboolean netconfig_is_wifi_tethering_on(void); + +gboolean netconfig_execute_file(const char *file_path, + char *const args[], char *const env[]); + +gboolean netconfig_iface_wifi_launch_direct(NetconfigWifi *wifi, GError **error); +void netconfig_set_wifi_mac_address(void); + +void netconfig_add_wifi_found_notification(void); +void netconfig_del_wifi_found_notification(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_UTIL_H__ */ diff --git a/include/wifi-agent.h b/include/wifi-agent.h new file mode 100644 index 0000000..b60a6f5 --- /dev/null +++ b/include/wifi-agent.h @@ -0,0 +1,55 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFI_AGENT_H__ +#define __NETCONFIG_WIFI_AGENT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wifi.h" + +#define NETCONFIG_AGENT_FIELD_NAME "Name" +#define NETCONFIG_AGENT_FIELD_PASSPHRASE "Passphrase" +#define NETCONFIG_AGENT_FIELD_IDENTITY "Identity" + +typedef struct { + char *name; + char *ssid; + char *identity; + char *passphrase; + char *wpspin; + char *username; + char *password; +} NetconfigWifiAgentFields; + +gboolean netconfig_agent_register(void); +gboolean netconfig_agent_unregister(void); +gboolean netconfig_iface_wifi_set_field(NetconfigWifi *wifi, + GHashTable *fields, GError **error); +gboolean netconfig_iface_wifi_request_input(NetconfigWifi *wifi, + gchar *service, GHashTable *fields, + DBusGMethodInvocation *context); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_AGENT_H__ */ diff --git a/include/wifi-background-scan.h b/include/wifi-background-scan.h new file mode 100644 index 0000000..c1d3920 --- /dev/null +++ b/include/wifi-background-scan.h @@ -0,0 +1,42 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFIBACKGROUND_SCAN_H__ +#define __NETCONFIG_WIFIBACKGROUND_SCAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wifi.h" + +void netconfig_wifi_bgscan_start(void); +void netconfig_wifi_bgscan_stop(void); +gboolean netconfig_wifi_get_bgscan_state(void); + +gboolean netconfig_wifi_get_scanning(void); +void netconfig_wifi_set_scanning(gboolean scanning); + +gboolean netconfig_iface_wifi_set_bgscan(NetconfigWifi *wifi, guint scan_mode, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFIBACKGROUND_SCAN_H__ */ diff --git a/include/wifi-eap-config.h b/include/wifi-eap-config.h new file mode 100644 index 0000000..95ae43e --- /dev/null +++ b/include/wifi-eap-config.h @@ -0,0 +1,52 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFI_EAP_CONFIG_H__ +#define __NETCONFIG_WIFI_EAP_CONFIG_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wifi.h" + +#define CONNMAN_STORAGEDIR "/var/lib/connman" + +#define CONNMAN_CONFIG_FIELD_TYPE "Type" +#define CONNMAN_CONFIG_FIELD_NAME "Name" +#define CONNMAN_CONFIG_FIELD_SSID "SSID" +#define CONNMAN_CONFIG_FIELD_EAP_METHOD "EAP" +#define CONNMAN_CONFIG_FIELD_IDENTITY "Identity" +#define CONNMAN_CONFIG_FIELD_PASSPHRASE "Passphrase" +#define CONNMAN_CONFIG_FIELD_PHASE2 "Phase2" +#define CONNMAN_CONFIG_FIELD_CA_CERT_FILE "CACertFile" +#define CONNMAN_CONFIG_FIELD_CLIENT_CERT_FILE "ClientCertFile" +#define CONNMAN_CONFIG_FIELD_PVT_KEY_FILE "PrivateKeyFile" +#define CONNMAN_CONFIG_FIELD_PVT_KEY_PASSPHRASE "PrivateKeyPassphrase" + +gboolean netconfig_iface_wifi_create_config(NetconfigWifi *wifi, + GHashTable *fields, GError **error); +gboolean netconfig_iface_wifi_delete_config(NetconfigWifi *wifi, + gchar *profile, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_EAP_CONFIG_H__ */ diff --git a/include/wifi-eap.h b/include/wifi-eap.h new file mode 100644 index 0000000..0338629 --- /dev/null +++ b/include/wifi-eap.h @@ -0,0 +1,39 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFI_EAP_H__ +#define __NETCONFIG_WIFI_EAP_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wifi.h" + +gboolean netconfig_iface_wifi_get_sim_imsi(NetconfigWifi *wifi, DBusGMethodInvocation *context); +gboolean netconfig_iface_wifi_req_sim_auth(NetconfigWifi *wifi, GArray *rand_data, gboolean *result, GError **error); +gboolean netconfig_iface_wifi_req_aka_auth(NetconfigWifi *wifi, GArray *rand_data, GArray *autn_data, gboolean *result, GError **error); +gboolean netconfig_iface_wifi_get_sim_auth(NetconfigWifi *wifi, DBusGMethodInvocation *context); +gboolean netconfig_iface_wifi_get_aka_auth(NetconfigWifi *wifi, DBusGMethodInvocation *context); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_EAP_H__ */ diff --git a/include/wifi-indicator.h b/include/wifi-indicator.h new file mode 100644 index 0000000..ffdd0d3 --- /dev/null +++ b/include/wifi-indicator.h @@ -0,0 +1,36 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFI_INDICATOR_H__ +#define __NETCONFIG_WIFI_INDICATOR_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +int netconfig_wifi_get_rssi(void); + +void netconfig_wifi_indicator_start(void); +void netconfig_wifi_indicator_stop(void); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_INDICATOR_H__ */ diff --git a/include/wifi-power.h b/include/wifi-power.h new file mode 100644 index 0000000..e6b3ecb --- /dev/null +++ b/include/wifi-power.h @@ -0,0 +1,39 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFI_POWER_H__ +#define __NETCONFIG_WIFI_POWER_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include + +void netconfig_wifi_power_configuration(void); + +gboolean netconfig_iface_wifi_load_driver(NetconfigWifi *wifi, GError **error); +gboolean netconfig_iface_wifi_remove_driver(NetconfigWifi *wifi, GError **error); + + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_POWER_H__ */ diff --git a/include/wifi-ssid-scan.h b/include/wifi-ssid-scan.h new file mode 100644 index 0000000..d3927a5 --- /dev/null +++ b/include/wifi-ssid-scan.h @@ -0,0 +1,51 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFI_SSID_SCAN_H__ +#define __NETCONFIG_WIFI_SSID_SCAN_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wifi.h" + +enum netconfig_wifi_security { + WIFI_SECURITY_UNKNOWN = 0x00, + WIFI_SECURITY_NONE = 0x01, + WIFI_SECURITY_WEP = 0x02, + WIFI_SECURITY_PSK = 0x03, + WIFI_SECURITY_IEEE8021X = 0x04, +}; + +gboolean netconfig_wifi_get_ssid_scan_state(void); + +void netconfig_wifi_notify_ssid_scan_done(void); +void netconfig_wifi_bss_added(DBusMessage *message); + +gboolean netconfig_wifi_ssid_scan(const char *ssid); + +gboolean netconfig_iface_wifi_request_specific_scan(NetconfigWifi *wifi, + gchar *ssid, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_SSID_SCAN_H__ */ diff --git a/include/wifi-state.h b/include/wifi-state.h new file mode 100644 index 0000000..6c84149 --- /dev/null +++ b/include/wifi-state.h @@ -0,0 +1,75 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFI_STATE_H__ +#define __NETCONFIG_WIFI_STATE_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include + +enum netconfig_wifi_service_state { + NETCONFIG_WIFI_UNKNOWN = 0x00, + NETCONFIG_WIFI_IDLE = 0x01, + NETCONFIG_WIFI_CONNECTING = 0x02, + NETCONFIG_WIFI_CONNECTED = 0x03, +}; + +enum netconfig_wifi_tech_state { + NETCONFIG_WIFI_TECH_UNKNOWN = 0x00, + NETCONFIG_WIFI_TECH_OFF = 0x01, + NETCONFIG_WIFI_TECH_POWERED = 0x02, + NETCONFIG_WIFI_TECH_CONNECTED = 0x03, + NETCONFIG_WIFI_TECH_TETHERING_ON = 0x04, +}; + +struct netconfig_wifi_state_notifier { + void (*netconfig_wifi_state_changed) + (enum netconfig_wifi_service_state, void *user_data); + void *user_data; +}; + +void netconfig_wifi_state_set_service_state( + enum netconfig_wifi_service_state state); +enum netconfig_wifi_service_state + netconfig_wifi_state_get_service_state(void); + +enum netconfig_wifi_tech_state + netconfig_wifi_get_technology_state(void); + +void netconfig_wifi_update_power_state(gboolean powered); + +char *netconfig_wifi_get_favorite_service(void); + +void netconfig_wifi_check_network_notification(DBusMessage *message); + +void netconfig_wifi_state_notifier_cleanup(void); +void netconfig_wifi_state_notifier_register( + struct netconfig_wifi_state_notifier *notifier); +void netconfig_wifi_state_notifier_unregister( + struct netconfig_wifi_state_notifier *notifier); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_STATE_H__ */ diff --git a/include/wifi.h b/include/wifi.h new file mode 100644 index 0000000..1e05eb5 --- /dev/null +++ b/include/wifi.h @@ -0,0 +1,62 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 __NETCONFIG_WIFI_H__ +#define __NETCONFIG_WIFI_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include +#include +#include + +G_BEGIN_DECLS + +typedef struct NetconfigWifi NetconfigWifi; +typedef struct NetconfigWifiClass NetconfigWifiClass; + +#define NETCONFIG_TYPE_WIFI (netconfig_wifi_get_type()) +#define NETCONFIG_WIFI(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), NETCONFIG_TYPE_WIFI, NetconfigWifi)) +#define NETCONFIG_IS_WIFI(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), NETCONFIG_TYPE_WIFI)) +#define NETCONFIG_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), NETCONFIG_TYPE_WIFI, NetconfigWifiClass)) +#define NETCONFIG_IS_WIFI_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), NETCONFIG_TYPE_WIFI)) +#define NETCONFIG_WIFI_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NETCONFIG_TYPE_WIFI, NetconfigWifiClass)) + +#define VCONF_WIFI_LAST_POWER_STATE "file/private/wifi/last_power_state" + +enum netconfig_wifi_power_state { + WIFI_POWER_OFF = 0x00, + WIFI_POWER_ON = 0x01, +}; + +GType netconfig_wifi_get_type(void); + +gpointer netconfig_wifi_create_and_init(DBusGConnection *conn); +gboolean netconfig_wifi_remove_driver(void); +void netconfig_wifi_notify_power_completed(gboolean power_on); + +G_END_DECLS + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_H__ */ diff --git a/interfaces/netconfig-iface-network-state.xml b/interfaces/netconfig-iface-network-state.xml new file mode 100644 index 0000000..d2dae90 --- /dev/null +++ b/interfaces/netconfig-iface-network-state.xml @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/interfaces/netconfig-iface-network-statistics.xml b/interfaces/netconfig-iface-network-statistics.xml new file mode 100644 index 0000000..d436a61 --- /dev/null +++ b/interfaces/netconfig-iface-network-statistics.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/interfaces/netconfig-iface-wifi.xml b/interfaces/netconfig-iface-wifi.xml new file mode 100644 index 0000000..d6f862e --- /dev/null +++ b/interfaces/netconfig-iface-wifi.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/net-config.manifest b/net-config.manifest new file mode 100644 index 0000000..8336b1a --- /dev/null +++ b/net-config.manifest @@ -0,0 +1,19 @@ + + + + + + + + + + + + + + + + + + + diff --git a/packaging/net-config.spec b/packaging/net-config.spec new file mode 100644 index 0000000..d34aea6 --- /dev/null +++ b/packaging/net-config.spec @@ -0,0 +1,118 @@ +Name: net-config +Summary: TIZEN Network Configuration Module +Version: 0.1.90_16 +Release: 1 +Group: System/Network +License: Apache License Version 2.0 +Source0: %{name}-%{version}.tar.gz + +BuildRequires: cmake +BuildRequires: pkgconfig(glib-2.0) +BuildRequires: pkgconfig(dbus-glib-1) +BuildRequires: pkgconfig(dlog) +BuildRequires: pkgconfig(vconf) +BuildRequires: pkgconfig(wifi-direct) +BuildRequires: pkgconfig(tapi) +BuildRequires: pkgconfig(syspopup-caller) +Requires(post): /usr/bin/vconftool +Requires: systemd +Requires(post): systemd +Requires(preun): systemd +Requires(postun): systemd + +%description +TIZEN Network Configuration Module + +%prep +%setup -q + + +%build +cmake . -DCMAKE_INSTALL_PREFIX=%{_prefix} + +make %{?_smp_mflags} + + +%install +%make_install + +mkdir -p %{buildroot}%{_datadir}/dbus-1/services +cp resources/usr/share/dbus-1/services/net.netconfig.service %{buildroot}%{_datadir}/dbus-1/services/net.netconfig.service +mkdir -p %{buildroot}%{_sysconfdir}/dbus-1/system.d +cp resources/etc/dbus-1/system.d/net-config.conf %{buildroot}%{_sysconfdir}/dbus-1/system.d/net-config.conf +mkdir -p %{buildroot}/opt/etc +cp resources/opt/etc/resolv.conf %{buildroot}/opt/etc/resolv.conf +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/init.d +cp resources/etc/rc.d/init.d/net-config %{buildroot}%{_sysconfdir}/rc.d/init.d/net-config +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc3.d +ln -s ../init.d/net-config %{buildroot}%{_sysconfdir}/rc.d/rc3.d/S60net-config +mkdir -p %{buildroot}%{_sysconfdir}/rc.d/rc5.d +ln -s ../init.d/net-config %{buildroot}%{_sysconfdir}/rc.d/rc5.d/S60net-config + +# Systemd service file +mkdir -p %{buildroot}%{_libdir}/systemd/system/ +cp resources/usr/lib/systemd/system/net-config.service %{buildroot}%{_libdir}/systemd/system/net-config.service +mkdir -p %{buildroot}%{_libdir}/systemd/system/network.target.wants/ +ln -s ../net-config.service %{buildroot}%{_libdir}/systemd/system/network.target.wants/net-config.service + +#License +mkdir -p %{buildroot}%{_datadir}/license +cp LICENSE.APLv2 %{buildroot}%{_datadir}/license/net-config + +%post + +vconftool set -t int memory/dnet/state 0 -i +vconftool set -t int memory/wifi/state 0 -i +vconftool set -t int memory/wifi/strength 0 -i + +vconftool set -t int memory/dnet/cellular 0 -i +vconftool set -t int memory/dnet/wifi 0 -i +vconftool set -t int memory/dnet/network_config 0 -i +vconftool set -t int memory/dnet/status 0 -i +vconftool set -t string memory/dnet/ip "" -i +vconftool set -t string memory/dnet/proxy "" -i + +vconftool set -t string memory/wifi/connected_ap_name "" -i + +vconftool set -t string db/wifi/bssid_address "" + +#Default Call Statistics +vconftool set -t int db/dnet/statistics/cellular/totalsnt "0" +vconftool set -t int db/dnet/statistics/cellular/totalrcv "0" +vconftool set -t int db/dnet/statistics/cellular/lastsnt "0" +vconftool set -t int db/dnet/statistics/cellular/lastrcv "0" +vconftool set -t int db/dnet/statistics/wifi/totalsnt "0" +vconftool set -t int db/dnet/statistics/wifi/totalrcv "0" +vconftool set -t int db/dnet/statistics/wifi/lastsnt "0" +vconftool set -t int db/dnet/statistics/wifi/lastrcv "0" + +vconftool set -t int file/private/wifi/last_power_state "0" + +systemctl daemon-reload +if [ "$1" == "1" ]; then + systemctl restart net-config.service +fi + +%preun +if [ "$1" == "0" ]; then + systemctl stop net-config.service +fi + +%postun +systemctl daemon-reload +if [ "$1" == "1" ]; then + systemctl restart net-config.service +fi + +%files +%manifest net-config.manifest +%{_sbindir}/* +%attr(644,root,root) /opt/etc/resolv.conf +%{_datadir}/dbus-1/services/* +%{_sysconfdir}/dbus-1/system.d/* +%{_sysconfdir}/rc.d/init.d/net-config +%{_sysconfdir}/rc.d/rc3.d/S60net-config +%{_sysconfdir}/rc.d/rc5.d/S60net-config +%{_libdir}/systemd/system/net-config.service +%{_libdir}/systemd/system/network.target.wants/net-config.service +%{_datadir}/license/net-config diff --git a/resources/etc/dbus-1/system.d/net-config.conf b/resources/etc/dbus-1/system.d/net-config.conf new file mode 100644 index 0000000..cb73052 --- /dev/null +++ b/resources/etc/dbus-1/system.d/net-config.conf @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/resources/etc/rc.d/init.d/net-config b/resources/etc/rc.d/init.d/net-config new file mode 100755 index 0000000..c1c195e --- /dev/null +++ b/resources/etc/rc.d/init.d/net-config @@ -0,0 +1,3 @@ +#!/bin/sh + +/usr/sbin/net-config & diff --git a/resources/opt/etc/resolv.conf b/resources/opt/etc/resolv.conf new file mode 100644 index 0000000..a67674d --- /dev/null +++ b/resources/opt/etc/resolv.conf @@ -0,0 +1,2 @@ +search localdomain +nameserver 127.0.0.1 \ No newline at end of file diff --git a/resources/usr/lib/systemd/system/net-config.service b/resources/usr/lib/systemd/system/net-config.service new file mode 100644 index 0000000..5a564b6 --- /dev/null +++ b/resources/usr/lib/systemd/system/net-config.service @@ -0,0 +1,10 @@ +[Unit] +Description=net config service +After=syslog.target + +[Service] +Type=forking +ExecStart=/usr/sbin/net-config + +[Install] +WantedBy=multi-user.target diff --git a/resources/usr/share/dbus-1/services/net.netconfig.service b/resources/usr/share/dbus-1/services/net.netconfig.service new file mode 100644 index 0000000..6d497a1 --- /dev/null +++ b/resources/usr/share/dbus-1/services/net.netconfig.service @@ -0,0 +1,4 @@ +[D-BUS Service] +Name=net.netconfig +Exec=/usr/sbin/net-config +User=root diff --git a/src/dbus/netdbus.c b/src/dbus/netdbus.c new file mode 100644 index 0000000..e0f7be1 --- /dev/null +++ b/src/dbus/netdbus.c @@ -0,0 +1,478 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "netdbus.h" +#include "netconfig.h" + +#define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000) + +#define DBUS_PARAM_TYPE_STRING "string" +#define DBUS_PARAM_TYPE_INT16 "int16" +#define DBUS_PARAM_TYPE_UINT16 "uint16" +#define DBUS_PARAM_TYPE_INT32 "int32" +#define DBUS_PARAM_TYPE_UINT32 "uint32" +#define DBUS_PARAM_TYPE_INT64 "int64" +#define DBUS_PARAM_TYPE_UINT64 "uint64" +#define DBUS_PARAM_TYPE_DOUBLE "double" +#define DBUS_PARAM_TYPE_BYTE "byte" +#define DBUS_PARAM_TYPE_BOOLEAN "boolean" +#define DBUS_PARAM_TYPE_OBJECT_PATH "objpath" +#define DBUS_PARAM_TYPE_VARIANT "variant" +#define DBUS_PARAM_TYPE_ARRAY "array" + + +static gboolean __netconfig_dbus_append_param_variant( + DBusMessageIter *iter, char *type, char *param) +{ + DBusMessageIter value, array; + char *args = NULL, *ch = NULL; + dbus_bool_t b_value = FALSE; + + if (strcmp(type, DBUS_PARAM_TYPE_STRING) == 0) { + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_STRING_AS_STRING, &value); + + dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, ¶m); + + dbus_message_iter_close_container(iter, &value); + } else if (strcmp(type, DBUS_PARAM_TYPE_BOOLEAN) == 0) { + if (strcmp(param, "true") == 0) { + b_value = TRUE; + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_BOOLEAN_AS_STRING, &value); + dbus_message_iter_append_basic(&value, + DBUS_TYPE_BOOLEAN, &b_value); + dbus_message_iter_close_container(iter, &value); + } else if (strcmp(param, "false") == 0) { + b_value = FALSE; + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_BOOLEAN_AS_STRING, &value); + dbus_message_iter_append_basic(&value, + DBUS_TYPE_BOOLEAN, &b_value); + dbus_message_iter_close_container(iter, &value); + } else { + ERR("Error!!! Expected \"true\" or" + "\"false\" instead of \"%s\"", ch); + return FALSE; + } + } else if (strcmp(type, DBUS_PARAM_TYPE_OBJECT_PATH) == 0) { + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_OBJECT_PATH_AS_STRING, &value); + + dbus_message_iter_append_basic(&value, DBUS_TYPE_OBJECT_PATH, ¶m); + + dbus_message_iter_close_container(iter, &value); + } else if (strcmp(type, DBUS_PARAM_TYPE_ARRAY) == 0) { + args = param; + ch = strchr(args, ':'); + if (ch == NULL) { + ERR("Error!!! Invalid data format[\"%s\"]", args); + return FALSE; + } + *ch = 0; ch++; + + if (strcmp(args, DBUS_PARAM_TYPE_STRING) == 0) { + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, + &value); + + dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, + DBUS_TYPE_STRING_AS_STRING, &array); + + dbus_message_iter_append_basic(&array, DBUS_TYPE_STRING, &ch); + + dbus_message_iter_close_container(&value, &array); + + dbus_message_iter_close_container(iter, &value); + } else if (strcmp(args, DBUS_PARAM_TYPE_OBJECT_PATH) == 0) { + dbus_message_iter_open_container(iter, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_OBJECT_PATH_AS_STRING, + &value); + + dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, + DBUS_TYPE_OBJECT_PATH_AS_STRING, &array); + + dbus_message_iter_append_basic(&array, DBUS_TYPE_OBJECT_PATH, &ch); + + dbus_message_iter_close_container(&value, &array); + + dbus_message_iter_close_container(iter, &value); + } else { + ERR("Error!!! Not supported data format[\"%s\"]", args); + return FALSE; + } + } else { + ERR("Error!!! Not supported data format[\"%s\"]", args); + return FALSE; + } + + return TRUE; +} + +static gboolean __netconfig_dbus_append_param( + DBusMessage *message, char *param_array[]) +{ + int count = 0; + dbus_uint32_t uint32 = 0; + DBusMessageIter iter; + char *args = NULL, *ch = NULL; + + if (param_array == NULL) + return TRUE; + + dbus_message_iter_init_append(message, &iter); + + while (param_array[count] != NULL) { + args = param_array[count]; + DBG("parameter %d - [%s]", count, param_array[count]); + + ch = strchr(args, ':'); + if (ch == NULL) { + ERR("Error!!! Invalid parameter[\"%s\"]\n", args); + return FALSE; + } + *ch = 0; ch++; + + if (strcmp(args, DBUS_PARAM_TYPE_STRING) == 0) { + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &ch); + } else if (strcmp(args, DBUS_PARAM_TYPE_UINT32) == 0) { + uint32 = strtoul(ch, NULL, 0); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_UINT32, &uint32); + } else if (strcmp(args, DBUS_PARAM_TYPE_VARIANT) == 0) { + args = ch; + ch = strchr(args, ':'); + if (ch == NULL) { + ERR("Error!!! Invalid data format[\"%s\"]\n", args); + return FALSE; + } + *ch = 0; ch++; + + if (__netconfig_dbus_append_param_variant(&iter, args, ch) != TRUE) + return FALSE; + + } else if (strcmp(args, DBUS_PARAM_TYPE_OBJECT_PATH) == 0) { + dbus_message_iter_append_basic(&iter, DBUS_TYPE_OBJECT_PATH, &ch); + } else { + ERR("Error!!! Not supported data format[\"%s\"]", args); + return FALSE; + } + + count++; + } + + return TRUE; +} + +gboolean netconfig_dbus_get_basic_params_string(DBusMessage *message, + char **key, void **value) +{ + DBusMessageIter args, variant; + int type = 0; + + if (key == NULL) + return FALSE; + + /* read parameters */ + if (dbus_message_iter_init(message, &args) == FALSE) { + DBG("Message does not have parameters"); + return FALSE; + } + + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { + DBG("Argument type %d", dbus_message_iter_get_arg_type(&args)); + return FALSE; + } + + dbus_message_iter_get_basic(&args, key); + + if (value == NULL) + return TRUE; + + dbus_message_iter_next(&args); + + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_VARIANT) { + DBG("Argument type %d", dbus_message_iter_get_arg_type(&args)); + return TRUE; + } + + dbus_message_iter_recurse(&args, &variant); + + type = dbus_message_iter_get_arg_type(&variant); + if (type == DBUS_TYPE_STRING) + dbus_message_iter_get_basic(&variant, value); + else if (type == DBUS_TYPE_BYTE || type == DBUS_TYPE_BOOLEAN || + type == DBUS_TYPE_INT16 || type == DBUS_TYPE_UINT16 || + type == DBUS_TYPE_INT32 || type == DBUS_TYPE_UINT32 || + type == DBUS_TYPE_DOUBLE) + dbus_message_iter_get_basic(&variant, *value); + else + DBG("Argument type %d", type); + + return TRUE; +} + +gboolean netconfig_dbus_get_basic_params_array(DBusMessage *message, + char **key, void **value) +{ + DBusMessageIter args, dict, entry, variant; + int type = 0; + + if (key == NULL) + return FALSE; + + /* read parameters */ + if (dbus_message_iter_init(message, &args) == FALSE) { + DBG("Message does not have parameters"); + return FALSE; + } + + if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_ARRAY) { + DBG("Argument type %d", dbus_message_iter_get_arg_type(&args)); + return FALSE; + } + + dbus_message_iter_recurse(&args, &dict); + + if (dbus_message_iter_get_arg_type(&dict) != DBUS_TYPE_DICT_ENTRY) { + DBG("Argument type %d", dbus_message_iter_get_arg_type(&dict)); + return FALSE; + } + + dbus_message_iter_recurse(&dict, &entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) { + DBG("Argument type %d", dbus_message_iter_get_arg_type(&entry)); + return FALSE; + } + + dbus_message_iter_get_basic(&entry, key); + + if (value == NULL) + return TRUE; + + dbus_message_iter_next(&entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) { + DBG("Argument type %d", dbus_message_iter_get_arg_type(&entry)); + return TRUE; + } + + dbus_message_iter_recurse(&entry, &variant); + + type = dbus_message_iter_get_arg_type(&variant); + if (type == DBUS_TYPE_STRING) + dbus_message_iter_get_basic(&variant, value); + else if (type == DBUS_TYPE_BYTE || type == DBUS_TYPE_BOOLEAN || + type == DBUS_TYPE_INT16 || type == DBUS_TYPE_UINT16 || + type == DBUS_TYPE_INT32 || type == DBUS_TYPE_UINT32 || + type == DBUS_TYPE_DOUBLE) + dbus_message_iter_get_basic(&variant, *value); + else + DBG("Argument type %d", type); + + return TRUE; +} + +gboolean netconfig_is_cellular_profile(const char *profile) +{ + if (profile == NULL) + return FALSE; + + return g_str_has_prefix(profile, CONNMAN_CELLULAR_SERVICE_PROFILE_PREFIX); +} + +gboolean netconfig_is_wifi_profile(const char *profile) +{ + if (profile == NULL) + return FALSE; + + return g_str_has_prefix(profile, CONNMAN_WIFI_SERVICE_PROFILE_PREFIX); +} + +gboolean netconfig_is_ethernet_profile(const char *profile) +{ + if (profile == NULL) + return FALSE; + + return g_str_has_prefix(profile, CONNMAN_ETHERNET_SERVICE_PROFILE_PREFIX); +} + +gboolean netconfig_is_bluetooth_profile(const char *profile) +{ + if (profile == NULL) + return FALSE; + + return g_str_has_prefix(profile, CONNMAN_BLUETOOTH_SERVICE_PROFILE_PREFIX); +} + +DBusMessage *netconfig_invoke_dbus_method(const char *dest, const char *path, + const char *interface_name, const char *method, char *param_array[]) +{ + DBusError error; + DBusConnection *conn = NULL; + DBusMessage *reply = NULL; + DBusMessage *message = NULL; + + DBG("[DBUS Sync] %s %s %s", interface_name, method, path); + + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (conn == NULL) { + ERR("Failed to get system bus"); + return NULL; + } + + message = dbus_message_new_method_call(dest, path, interface_name, method); + if (message == NULL) { + ERR("Error!!! Failed to GetProperties"); + dbus_connection_unref(conn); + return NULL; + } + + if (__netconfig_dbus_append_param(message, param_array) == FALSE) { + ERR("Error!!! __netconfig_dbus_append_param() failed"); + dbus_message_unref(message); + dbus_connection_unref(conn); + return NULL; + } + + dbus_error_init(&error); + + reply = dbus_connection_send_with_reply_and_block(conn, message, + NETCONFIG_DBUS_REPLY_TIMEOUT, &error); + + if (reply == NULL) { + if (dbus_error_is_set(&error) == TRUE) { + ERR("Error!!! dbus_connection_send_with_reply_and_block() failed. " + "DBus error [%s: %s]", error.name, error.message); + + dbus_error_free(&error); + } else + ERR("Error!!! Failed to get properties"); + + dbus_message_unref(message); + dbus_connection_unref(conn); + + return NULL; + } + + dbus_message_unref(message); + dbus_connection_unref(conn); + + return reply; +} + +char *netconfig_wifi_get_connected_service_name(DBusMessage *message) +{ + int is_connected = 0; + char *essid_name = NULL; + DBusMessageIter iter, array; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &array); + + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, string; + const char *key = NULL; + + dbus_message_iter_recurse(&array, &entry); + dbus_message_iter_get_basic(&entry, &key); + + if (g_str_equal(key, "State") == TRUE && is_connected == 0) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &string); + + if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&string, &key); + + if (g_str_equal(key, "ready") == TRUE || + g_str_equal(key, "online") == TRUE) + is_connected = 1; + } + } else if (g_str_equal(key, "Name") == TRUE) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &string); + + if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&string, &key); + + essid_name = (char *)g_strdup(key); + } + } + + dbus_message_iter_next(&array); + } + + if (is_connected == 1 && essid_name != NULL) + return essid_name; + + if (essid_name != NULL) + g_free(essid_name); + + return NULL; +} + +DBusGConnection *netconfig_setup_dbus(void) +{ + DBusGConnection* connection = NULL; + GError *error = NULL; + DBusGProxy *proxy; + guint rv = 0; + + connection = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + ERR("Fail to get DBus(%s)", error->message); + g_error_free(error); + + return connection; + } + + INFO("Successfully get system DBus connection(%p)", connection); + + proxy = dbus_g_proxy_new_for_name(connection, "org.freedesktop.DBus", + "/org/freedesktop/DBus", + "org.freedesktop.DBus"); + + if (!dbus_g_proxy_call(proxy, "RequestName", &error, + G_TYPE_STRING, NETCONFIG_SERVICE, G_TYPE_UINT, 0, + G_TYPE_INVALID, G_TYPE_UINT, &rv, + G_TYPE_INVALID)) { + ERR("Failed to acquire service(%s) error(%s)", + NETCONFIG_SERVICE, error->message); + g_error_free(error); + + dbus_g_connection_unref(connection); + + return NULL; + } + + if (rv != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) { + ERR("Service name is already in use"); + + dbus_g_connection_unref(connection); + + return NULL; + } + + return connection; +} diff --git a/src/dbus/netsupplicant.c b/src/dbus/netsupplicant.c new file mode 100644 index 0000000..d3926d5 --- /dev/null +++ b/src/dbus/netsupplicant.c @@ -0,0 +1,273 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "netdbus.h" +#include "netsupplicant.h" + +#define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000) + +static void setup_dbus_args(gpointer data, gpointer user_data) +{ + struct dbus_input_arguments *args; + DBusMessageIter *iter; + + if (data != NULL && user_data != NULL) { + args = (struct dbus_input_arguments *)data; + iter = (DBusMessageIter *) user_data; + + dbus_message_iter_append_basic(iter, args->type, + &(args->data)); + } +} + +static GList *setup_input_args(GList *list, + struct dbus_input_arguments *items) +{ + struct dbus_input_arguments *iter = items; + + if (iter == NULL) + return NULL; + + while (iter->data) { + list = g_list_append(list, iter); + iter++; + } + + return list; +} + +gboolean netconfig_wifi_get_ifname(char **ifname) +{ + DBusConnection *connection = NULL; + DBusMessage *message = NULL; + DBusMessageIter iter; + int MessageType = 0; + char *ptr = (char *)*ifname; + const char *temp = NULL; + + char object_path[DBUS_PATH_MAX_BUFLEN] = { 0, }; + char *path_ptr = &object_path[0]; + + GList *input_args = NULL; + struct dbus_input_arguments args[] = { + {DBUS_TYPE_STRING, SUPPLICANT_INTERFACE ".Interface"}, + {DBUS_TYPE_STRING, "Ifname"}, + {0, NULL} + }; + + if (ptr == NULL) + return FALSE; + + if (netconfig_wifi_get_supplicant_interface(&path_ptr) != TRUE) { + DBG("Fail to get wpa_supplicant DBus path"); + return FALSE; + } + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) { + ERR("Error!!! Fail to get system DBus"); + return FALSE; + } + + input_args = setup_input_args(input_args, args); + + message = netconfig_supplicant_invoke_dbus_method( + SUPPLICANT_SERVICE, connection, + path_ptr, + SUPPLICANT_GLOBAL_INTERFACE, "Get", + input_args); + + g_list_free(input_args); + + if (message == NULL) { + ERR("Error!!! Failed to get service properties"); + goto error; + } + + MessageType = dbus_message_get_type(message); + + if (MessageType == DBUS_MESSAGE_TYPE_ERROR) { + const char *err_ptr = dbus_message_get_error_name(message); + ERR("Error!!! Error message received %s", err_ptr); + goto error; + } + + dbus_message_iter_init(message, &iter); + + if ((MessageType = dbus_message_iter_get_arg_type(&iter)) + == DBUS_TYPE_VARIANT) { + DBusMessageIter string_type; + dbus_message_iter_recurse(&iter, &string_type); + + if ((MessageType = dbus_message_iter_get_arg_type(&string_type)) + == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&string_type, &temp); + } else + goto error; + } else + goto error; + + g_strlcpy(ptr, temp, 16); + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return TRUE; + +error: + if (message != NULL) + dbus_message_unref(message); + + if (connection != NULL) + dbus_connection_unref(connection); + + return FALSE; +} + +gboolean netconfig_wifi_get_supplicant_interface(char **path) +{ + DBusConnection *connection = NULL; + DBusMessage *message = NULL; + DBusMessageIter iter; + int MessageType = 0; + char *ptr = (char *)*path; + const char *temp = NULL; + + GList *input_args = NULL; + struct dbus_input_arguments args[] = { + {DBUS_TYPE_STRING, SUPPLICANT_INTERFACE}, + {DBUS_TYPE_STRING, "Interfaces"}, + {0, NULL} + }; + + if (ptr == NULL) + return FALSE; + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) { + ERR("Error!!! Fail to get system DBus"); + return FALSE; + } + + input_args = setup_input_args(input_args, args); + + message = netconfig_supplicant_invoke_dbus_method( + SUPPLICANT_SERVICE, connection, + SUPPLICANT_PATH, + SUPPLICANT_GLOBAL_INTERFACE, "Get", + input_args); + + g_list_free(input_args); + + if (message == NULL) { + ERR("Error!!! Failed to get service properties"); + goto error; + } + + MessageType = dbus_message_get_type(message); + + if (MessageType == DBUS_MESSAGE_TYPE_ERROR) { + const char *err_msg = dbus_message_get_error_name(message); + ERR("Error!!! Error message received %s", err_msg); + goto error; + } + + dbus_message_iter_init(message, &iter); + if ((MessageType = dbus_message_iter_get_arg_type(&iter)) + == DBUS_TYPE_VARIANT) { + DBusMessageIter array; + dbus_message_iter_recurse(&iter, &array); + + if ((MessageType = dbus_message_iter_get_arg_type(&array)) + == DBUS_TYPE_ARRAY) { + DBusMessageIter object_path; + dbus_message_iter_recurse(&array, &object_path); + + if ((MessageType = dbus_message_iter_get_arg_type(&object_path)) + == DBUS_TYPE_OBJECT_PATH) + dbus_message_iter_get_basic(&object_path, &temp); + else + goto error; + } else + goto error; + } else + goto error; + + g_strlcpy(ptr, temp, DBUS_PATH_MAX_BUFLEN); + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return TRUE; + +error: + if (message != NULL) + dbus_message_unref(message); + + if (connection != NULL) + dbus_connection_unref(connection); + + return FALSE; +} + +DBusMessage *netconfig_supplicant_invoke_dbus_method(const char *dest, + DBusConnection *connection, + const char *path, const char *interface_name, + const char *method, GList *args) +{ + DBusError error; + DBusMessageIter iter; + DBusMessage *reply = NULL; + DBusMessage *message = NULL; + + message = dbus_message_new_method_call(dest, path, interface_name, method); + if (message == NULL) { + ERR("Error!!! DBus method call fail"); + return NULL; + } + + dbus_message_iter_init_append(message, &iter); + + if (args != NULL) + g_list_foreach(args, setup_dbus_args, (gpointer) &iter); + + dbus_error_init(&error); + + reply = dbus_connection_send_with_reply_and_block(connection, message, + NETCONFIG_DBUS_REPLY_TIMEOUT, &error); + + if (reply == NULL) { + if (dbus_error_is_set(&error) == TRUE) { + ERR("Error!!! dbus_connection_send_with_reply_and_block() failed. DBus error [%s: %s]", + error.name, error.message); + + dbus_error_free(&error); + } else + ERR("Error!!! Failed to get properties"); + + dbus_message_unref(message); + + return NULL; + } + + dbus_message_unref(message); + + return reply; +} diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..f64b694 --- /dev/null +++ b/src/main.c @@ -0,0 +1,80 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "wifi.h" +#include "util.h" +#include "emulator.h" +#include "netdbus.h" +#include "network-clock.h" +#include "network-state.h" +#include "network-statistics.h" +#include "signal-handler.h" +#include "wifi-agent.h" + +static GMainLoop *main_loop = NULL; + +int main(int argc, char* argv[]) +{ + DBusGConnection *connection; + + DBG("Network Configuration Module"); + + if (daemon(0, 0) != 0) + DBG("Cannot start daemon"); + + netconfig_set_wifi_mac_address(); + + g_type_init(); + + main_loop = g_main_loop_new(NULL, FALSE); + + connection = netconfig_setup_dbus(); + if (connection == NULL) + return -1; + + if (netconfig_network_state_create_and_init(connection) == NULL) + return -1; + + netconfig_register_signal(); + + /* Registering the agent for exchanging security credentials */ + netconfig_agent_register(); + + if (netconfig_wifi_create_and_init(connection) == NULL) + return -1; + + if (netconfig_network_statistics_create_and_init(connection) == NULL) + return -1; + + /* If its environment uses Emulator, network configuration is set by emulator default */ + netconfig_emulator_test_and_start(); + + g_main_loop_run(main_loop); + + netconfig_deregister_signal(); + netconfig_wifi_state_notifier_cleanup(); + + /* Unregistering the agent */ + netconfig_agent_unregister(); + + return 0; +} diff --git a/src/neterror.c b/src/neterror.c new file mode 100644 index 0000000..0c55268 --- /dev/null +++ b/src/neterror.c @@ -0,0 +1,89 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "neterror.h" +#include "netconfig.h" + +#define NETCONFIG_ERROR_INTERFACE NETCONFIG_SERVICE ".Error" + +GQuark netconfig_error_quark(void) +{ + static GQuark quark = 0; + + if (!quark) + quark = g_quark_from_static_string("netconfig_error"); + + return quark; +} + +void netconfig_error_wifi_load_inprogress(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_WIFI_LOAD_INPROGRESS, + NETCONFIG_ERROR_INTERFACE ".WifiLoadInprogress"); +} + +void netconfig_error_wifi_driver_failed(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_WIFI_DRIVER_FAILURE, + NETCONFIG_ERROR_INTERFACE ".WifiDriverFailed"); +} + +void netconfig_error_security_restricted(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_SECURITY_RESTRICTED, + NETCONFIG_ERROR_INTERFACE ".SecurityRestricted"); +} + +void netconfig_error_wifi_direct_failed(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_WIFI_DRIVER_FAILURE, + NETCONFIG_ERROR_INTERFACE ".WifiDirectFailed"); +} + +void netconfig_error_fail_get_imsi(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_FAILED_GET_IMSI, + NETCONFIG_ERROR_INTERFACE".FailGetSimImsi"); +} + +void netconfig_error_fail_req_sim_auth(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH, + NETCONFIG_ERROR_INTERFACE".FailReqSimAuth"); +} + +void netconfig_error_fail_req_sim_auth_wrong_param(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_FAILED_REQ_SIM_AUTH_WRONG_PARAM, + NETCONFIG_ERROR_INTERFACE".FailReqSimAuthWrongParam"); +} + +void netconfig_error_fail_get_sim_auth_wrong_data(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_FAILED_GET_SIM_AUTH_WRONG_DATA, + NETCONFIG_ERROR_INTERFACE".FailGetSimAuthWrongData"); +} + +void netconfig_error_fail_get_sim_auth_delay(GError **error) +{ + g_set_error(error, netconfig_error_quark(), NETCONFIG_ERROR_FAILED_GET_SIM_AUTH_DELAY, + NETCONFIG_ERROR_INTERFACE".FailGetSimAuthDelay"); +} diff --git a/src/network-clock.c b/src/network-clock.c new file mode 100644 index 0000000..a09e3b1 --- /dev/null +++ b/src/network-clock.c @@ -0,0 +1,114 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "util.h" +#include "netdbus.h" +#include "wifi-state.h" + +#define NTP_SERVER "pool.ntp.org" +#define CONNMAN_GLOBAL_SETTING "/var/lib/connman/settings" + +static void __netconfig_clock_clear_timeserver(void) +{ + GKeyFile *keyfile = NULL; + + keyfile = netconfig_keyfile_load(CONNMAN_GLOBAL_SETTING); + + if (keyfile == NULL) + return; + + g_key_file_remove_key(keyfile, "global", "Timeservers", NULL); + + netconfig_keyfile_save(keyfile, CONNMAN_GLOBAL_SETTING); +} + +static gboolean __netconfig_clock_clear_timeserver_timer(gpointer data) +{ + INFO("Clear NTP server"); + + __netconfig_clock_clear_timeserver(); + + return FALSE; +} + +static void __netconfig_clock_set_timeserver(const char *server) +{ + DBusMessage* reply = NULL; + char param1[] = "string:Timeservers"; + char *param2 = NULL; + char *param_array[] = {NULL, NULL, NULL}; + + param2 = g_strdup_printf("variant:array:string:%s", server); + + param_array[0] = param1; + param_array[1] = param2; + + reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_CLOCK_INTERFACE, + "SetProperty", param_array); + if (reply == NULL) { + ERR("Failed to configure NTP server"); + return; + } + + dbus_message_unref(reply); +} + +static void __netconfig_clock( + enum netconfig_wifi_service_state state, void *user_data) +{ + gboolean automatic_time_update = 0; + guint timeserver_clear_timer = 0; + + if (state != NETCONFIG_WIFI_CONNECTED) + return; + + vconf_get_bool( + VCONFKEY_SETAPPL_STATE_AUTOMATIC_TIME_UPDATE_BOOL, + &automatic_time_update); + + if (automatic_time_update == FALSE) { + INFO("Automatic time update is not set (%d)", automatic_time_update); + return; + } + + __netconfig_clock_set_timeserver((const char *)NTP_SERVER); + + netconfig_start_timer_seconds(5, __netconfig_clock_clear_timeserver_timer, + NULL, ×erver_clear_timer); +} + +static struct netconfig_wifi_state_notifier netconfig_clock_notifier = { + .netconfig_wifi_state_changed = __netconfig_clock, + .user_data = NULL, +}; + +void netconfig_clock_init(void) +{ + netconfig_wifi_state_notifier_register(&netconfig_clock_notifier); +} + +void netconfig_clock_deinit(void) +{ + netconfig_wifi_state_notifier_unregister(&netconfig_clock_notifier); +} diff --git a/src/network-state.c b/src/network-state.c new file mode 100644 index 0000000..ff5c701 --- /dev/null +++ b/src/network-state.c @@ -0,0 +1,666 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "wifi.h" +#include "log.h" +#include "util.h" +#include "netdbus.h" +#include "neterror.h" +#include "emulator.h" +#include "wifi-state.h" +#include "network-state.h" + +#define NETCONFIG_NETWORK_STATE_PATH "/net/netconfig/network" +#define ROUTE_EXEC_PATH "/sbin/route" + +#define PROP_DEFAULT FALSE +#define PROP_DEFAULT_STR NULL + + +gboolean netconfig_iface_network_state_add_route( + NetconfigNetworkState *master, + gchar *ip_addr, gchar *netmask, + gchar *interface, gboolean *result, GError **error); + +gboolean netconfig_iface_network_state_remove_route( + NetconfigNetworkState *master, + gchar *ip_addr, gchar *netmask, + gchar *interface, gboolean *result, GError **error); + +#include "netconfig-iface-network-state-glue.h" + +enum { + PROP_O, + PROP_NETWORK_STATE_CONN, + PROP_NETWORK_STATE_PATH, +}; + +struct NetconfigNetworkStateClass { + GObjectClass parent; +}; + +struct NetconfigNetworkState { + GObject parent; + + DBusGConnection *conn; + gchar *path; +}; + +G_DEFINE_TYPE(NetconfigNetworkState, netconfig_network_state, G_TYPE_OBJECT); + + +static void __netconfig_network_state_gobject_get_property(GObject *object, + guint prop_id, GValue *value, GParamSpec *pspec) +{ + return; +} + +static void __netconfig_network_state_gobject_set_property(GObject *object, + guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NetconfigNetworkState *network_state = NETCONFIG_NETWORK_STATE(object); + + switch (prop_id) { + case PROP_NETWORK_STATE_CONN: + { + network_state->conn = g_value_get_boxed(value); + INFO("network_state(%p) set conn(%p)", network_state, network_state->conn); + break; + } + + case PROP_NETWORK_STATE_PATH: + { + if (network_state->path) + g_free(network_state->path); + + network_state->path = g_value_dup_string(value); + INFO("network_state(%p) path(%s)", network_state, network_state->path); + + break; + } + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + +static void netconfig_network_state_init(NetconfigNetworkState *network_state) +{ + DBG("network_state initialize"); + + network_state->conn = NULL; + network_state->path = g_strdup(PROP_DEFAULT_STR); +} + +static void netconfig_network_state_class_init(NetconfigNetworkStateClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + DBG("class initialize"); + + object_class->get_property = __netconfig_network_state_gobject_get_property; + object_class->set_property = __netconfig_network_state_gobject_set_property; + + /* DBus register */ + dbus_g_object_type_install_info(NETCONFIG_TYPE_NETWORK_STATE, + &dbus_glib_netconfig_iface_network_state_object_info); + + /* property */ + g_object_class_install_property(object_class, PROP_NETWORK_STATE_CONN, + g_param_spec_boxed("conn", "CONNECTION", "DBus connection", + DBUS_TYPE_G_CONNECTION, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property(object_class, PROP_NETWORK_STATE_PATH, + g_param_spec_string("path", "Path", "Object path", + PROP_DEFAULT_STR, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + +struct netconfig_default_connection { + char *profile; + char *ifname; + char *ipaddress; + char *proxy; + char *essid; +}; + +static struct netconfig_default_connection + netconfig_default_connection_info; + +static void __netconfig_pop_3g_alert_syspoppup(void) +{ + int rv = 0; + bundle *b = NULL; + int wifi_ug_state = 0; + + vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state); + if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) + return; + + b = bundle_create(); + + bundle_add(b, "_SYSPOPUP_TITLE_", "Cellular connection popup"); + bundle_add(b, "_SYSPOPUP_TYPE_", "notification"); + bundle_add(b, "_SYSPOPUP_CONTENT_", "connected"); + + DBG("Launch 3G alert network popup"); + rv = aul_launch_app("org.tizen.net-popup", b); + + bundle_free(b); +} + +static gboolean __netconfig_is_connected(const char *profile) +{ + gboolean is_connected = FALSE; + DBusMessage *message = NULL; + DBusMessageIter iter, array; + + if (profile == NULL) + return FALSE; + + message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, profile, + CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL); + if (message == NULL) { + ERR("Failed to get service properties"); + return is_connected; + } + + if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) { + const char *ptr = dbus_message_get_error_name(message); + ERR("Error!!! Error message received [%s]", ptr); + goto done; + } + + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &array); + + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, string; + const char *key = NULL; + + dbus_message_iter_recurse(&array, &entry); + dbus_message_iter_get_basic(&entry, &key); + + if (g_str_equal(key, "State") == TRUE) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &string); + + if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&string, &key); + + if (g_str_equal(key, "ready") == TRUE || + g_str_equal(key, "online") == TRUE) { + is_connected = TRUE; + + break; + } + } + } + + dbus_message_iter_next(&array); + } + +done: + if (message != NULL) + dbus_message_unref(message); + + return is_connected; +} + +static char *__netconfig_get_default_profile(void) +{ + DBusMessage *message = NULL; + GSList *service_profiles = NULL; + GSList *list = NULL; + DBusMessageIter iter, dict; + char *default_profile = NULL; + + message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, + "GetServices", NULL); + if (message == NULL) { + ERR("Failed to get profiles"); + return NULL; + } + + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &dict); + + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) { + DBusMessageIter entry; + const char *object_path = NULL; + + dbus_message_iter_recurse(&dict, &entry); + dbus_message_iter_get_basic(&entry, &object_path); + + if (object_path) + service_profiles = g_slist_append( + service_profiles, + g_strdup(object_path)); + + dbus_message_iter_next(&dict); + } + + for (list = service_profiles; list != NULL; list = list->next) { + char *profile_path = list->data; + + if (__netconfig_is_connected((const char *)profile_path) == TRUE) { + default_profile = g_strdup(profile_path); + break; + } + } + + g_slist_free(service_profiles); + + dbus_message_unref(message); + + return default_profile; +} + +static void __netconfig_get_default_connection_info(const char *profile) +{ + DBusMessage *message = NULL; + DBusMessageIter iter, array; + + message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, profile, + CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL); + if (message == NULL) { + ERR("Failed to get service properties"); + return; + } + + if (dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_ERROR) { + const char *ptr = dbus_message_get_error_name(message); + ERR("Error!!! Error message received [%s]", ptr); + goto done; + } + + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &array); + + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, variant, string, iter1, iter2, iter3; + const char *key = NULL, *value = NULL; + + dbus_message_iter_recurse(&array, &entry); + dbus_message_iter_get_basic(&entry, &key); + + if (g_str_equal(key, "Name") == TRUE && + netconfig_is_wifi_profile(profile) == TRUE) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &string); + + if (dbus_message_iter_get_arg_type(&string) == DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&string, &value); + + netconfig_default_connection_info.essid = g_strdup(value); + } + } else if (g_str_equal(key, "Ethernet") == TRUE) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &variant); + dbus_message_iter_recurse(&variant, &iter1); + + while (dbus_message_iter_get_arg_type(&iter1) + == DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&iter1, &iter2); + dbus_message_iter_get_basic(&iter2, &key); + + if (g_str_equal(key, "Interface") == TRUE) { + dbus_message_iter_next(&iter2); + dbus_message_iter_recurse(&iter2, &iter3); + dbus_message_iter_get_basic(&iter3, &value); + + netconfig_default_connection_info.ifname = g_strdup(value); + } + + dbus_message_iter_next(&iter1); + } + } else if (g_str_equal(key, "IPv4") == TRUE) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &variant); + dbus_message_iter_recurse(&variant, &iter1); + + while (dbus_message_iter_get_arg_type(&iter1) + == DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&iter1, &iter2); + dbus_message_iter_get_basic(&iter2, &key); + + if (g_str_equal(key, "Address") == TRUE) { + dbus_message_iter_next(&iter2); + dbus_message_iter_recurse(&iter2, &iter3); + dbus_message_iter_get_basic(&iter3, &value); + + netconfig_default_connection_info.ipaddress = g_strdup(value); + } + + dbus_message_iter_next(&iter1); + } + } else if (g_str_equal(key, "IPv6") == TRUE) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &variant); + dbus_message_iter_recurse(&variant, &iter1); + + while (dbus_message_iter_get_arg_type(&iter1) + == DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&iter1, &iter2); + dbus_message_iter_get_basic(&iter2, &key); + + if (g_str_equal(key, "Address") == TRUE) { + dbus_message_iter_next(&iter2); + dbus_message_iter_recurse(&iter2, &iter3); + dbus_message_iter_get_basic(&iter3, &value); + + netconfig_default_connection_info.ipaddress = g_strdup(value); + } + + dbus_message_iter_next(&iter1); + } + } else if (g_str_equal(key, "Proxy") == TRUE) { + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &variant); + dbus_message_iter_recurse(&variant, &iter1); + + while (dbus_message_iter_get_arg_type(&iter1) + == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter iter4; + + dbus_message_iter_recurse(&iter1, &iter2); + dbus_message_iter_get_basic(&iter2, &key); + + if (g_str_equal(key, "Servers") == TRUE) { + dbus_message_iter_next(&iter2); + dbus_message_iter_recurse(&iter2, &iter3); + if (dbus_message_iter_get_arg_type(&iter3) + != DBUS_TYPE_ARRAY) + break; + + dbus_message_iter_recurse(&iter3, &iter4); + if (dbus_message_iter_get_arg_type(&iter4) + != DBUS_TYPE_STRING) + break; + + dbus_message_iter_get_basic(&iter4, &value); + if (value != NULL && (strlen(value) > 0)) + netconfig_default_connection_info.proxy = g_strdup(value); + + } else if (g_str_equal(key, "Method") == TRUE) { + dbus_message_iter_next(&iter2); + dbus_message_iter_recurse(&iter2, &iter3); + if (dbus_message_iter_get_arg_type(&iter3) + != DBUS_TYPE_STRING) + break; + + dbus_message_iter_get_basic(&iter3, &value); + if (g_strcmp0(value, "direct") == 0) { + g_free(netconfig_default_connection_info.proxy); + netconfig_default_connection_info.proxy = NULL; + + break; + } + } + + dbus_message_iter_next(&iter1); + } + } + + dbus_message_iter_next(&array); + } + +done: + if (message != NULL) + dbus_message_unref(message); +} + +static void __netconfig_update_default_connection_info(void) +{ + int old_network_status = 0; + const char *profile = netconfig_get_default_profile(); + const char *ip_addr = netconfig_get_default_ipaddress(); + const char *proxy_addr = netconfig_get_default_proxy(); + + if (netconfig_emulator_is_emulated() == TRUE) + return; + + if (profile == NULL) + DBG("Reset network state configuration"); + else + DBG("%s: ip(%s) proxy(%s)", profile, ip_addr, proxy_addr); + + vconf_get_int(VCONFKEY_NETWORK_STATUS, &old_network_status); + + if (profile == NULL && old_network_status != VCONFKEY_NETWORK_OFF) { + vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF); + + vconf_set_str(VCONFKEY_NETWORK_IP, ""); + vconf_set_str(VCONFKEY_NETWORK_PROXY, ""); + + vconf_set_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 0); + + DBG("Successfully clear IP and PROXY up"); + } else if (profile != NULL) { + char *old_ip = vconf_get_str(VCONFKEY_NETWORK_IP); + char *old_proxy = vconf_get_str(VCONFKEY_NETWORK_PROXY); + + if (netconfig_is_wifi_profile(profile) == TRUE) { + vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_WIFI); + } else if (netconfig_is_cellular_profile(profile) == TRUE) { + vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_CELLULAR); + + if (old_network_status != VCONFKEY_NETWORK_CELLULAR) + __netconfig_pop_3g_alert_syspoppup(); + } else if (netconfig_is_ethernet_profile(profile) == TRUE) { + vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_ETHERNET); + } else if (netconfig_is_bluetooth_profile(profile) == TRUE) { + vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_BLUETOOTH); + } else { + vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_OFF); + } + + if (g_strcmp0(old_ip, ip_addr) != 0) { + if (ip_addr == NULL) + vconf_set_str(VCONFKEY_NETWORK_IP, ""); + else + vconf_set_str(VCONFKEY_NETWORK_IP, ip_addr); + } + + if (g_strcmp0(old_proxy, proxy_addr) != 0) { + if (proxy_addr == NULL) + vconf_set_str(VCONFKEY_NETWORK_PROXY, ""); + else + vconf_set_str(VCONFKEY_NETWORK_PROXY, proxy_addr); + } + + vconf_set_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 1); + + DBG("Successfully update default network configuration"); + } +} + +const char *netconfig_get_default_profile(void) +{ + return netconfig_default_connection_info.profile; +} + +const char *netconfig_get_default_ipaddress(void) +{ + return netconfig_default_connection_info.ipaddress; +} + +const char *netconfig_get_default_proxy(void) +{ + return netconfig_default_connection_info.proxy; +} + +const char *netconfig_wifi_get_connected_essid(const char *default_profile) +{ + if (default_profile == NULL) + return NULL; + + if (netconfig_is_wifi_profile(default_profile) != TRUE) + return NULL; + + if (g_str_equal(default_profile, netconfig_default_connection_info.profile) + != TRUE) + return NULL; + + return netconfig_default_connection_info.essid; +} + +void netconfig_set_default_profile(const char *profile) +{ + char *default_profile = NULL; + + /* It's automatically updated by signal-handler + * DO NOT update manually + * + * It is going to update default connection information + */ + if (netconfig_default_connection_info.profile != NULL) { + g_free(netconfig_default_connection_info.profile); + netconfig_default_connection_info.profile = NULL; + + g_free(netconfig_default_connection_info.ifname); + netconfig_default_connection_info.ifname = NULL; + + g_free(netconfig_default_connection_info.ipaddress); + netconfig_default_connection_info.ipaddress = NULL; + + g_free(netconfig_default_connection_info.proxy); + netconfig_default_connection_info.proxy = NULL; + + if (netconfig_wifi_state_get_service_state() + != NETCONFIG_WIFI_CONNECTED) { + g_free(netconfig_default_connection_info.essid); + netconfig_default_connection_info.essid = NULL; + } + } + + if (profile == NULL) { + default_profile = __netconfig_get_default_profile(); + if (default_profile == NULL) { + __netconfig_update_default_connection_info(); + return; + } + } + + if (profile != NULL) + netconfig_default_connection_info.profile = g_strdup(profile); + else + netconfig_default_connection_info.profile = default_profile; + + __netconfig_get_default_connection_info( + netconfig_default_connection_info.profile); + + __netconfig_update_default_connection_info(); +} + +gboolean netconfig_iface_network_state_add_route( + NetconfigNetworkState *master, + gchar *ip_addr, gchar *netmask, + gchar *interface, gboolean *result, GError **error) +{ + gboolean ret = FALSE; + gboolean rv = FALSE; + const char *path = ROUTE_EXEC_PATH; + char *const args[] = {"route", "add", + "-net", ip_addr, + "netmask", netmask, + "dev", interface, + 0}; + char *const envs[] = { NULL }; + + DBG("ip_addr(%s), netmask(%s), interface(%s)", ip_addr, netmask, interface); + + if (ip_addr == NULL || netmask == NULL || interface == NULL) { + DBG("Invalid parameter!"); + goto done; + } + + rv = netconfig_execute_file(path, args, envs); + if (rv != TRUE) { + DBG("Failed to add a new route"); + goto done; + } + + DBG("Successfully added a new route"); + ret = TRUE; + +done: + *result = ret; + return ret; +} + +gboolean netconfig_iface_network_state_remove_route( + NetconfigNetworkState *master, + gchar *ip_addr, gchar *netmask, + gchar *interface, gboolean *result, GError **error) +{ + gboolean ret = FALSE; + gboolean rv = FALSE; + const char *path = ROUTE_EXEC_PATH; + char *const args[] = {"route", "del", + "-net", ip_addr, + "netmask", netmask, + "dev", interface, + 0}; + char *const envs[] = { NULL }; + + DBG("ip_addr(%s), netmask(%s), interface(%s)", ip_addr, netmask, interface); + + if (ip_addr == NULL || netmask == NULL || interface == NULL) { + DBG("Invalid parameter!"); + goto done; + } + + rv = netconfig_execute_file(path, args, envs); + if (rv != TRUE) { + DBG("Failed to remove a new route"); + goto done; + } + + DBG("Successfully remove a new route"); + ret = TRUE; + +done: + *result = ret; + return ret; +} + +gpointer netconfig_network_state_create_and_init(DBusGConnection *conn) +{ + GObject *object; + + g_return_val_if_fail(conn != NULL, NULL); + + object = g_object_new(NETCONFIG_TYPE_NETWORK_STATE, "conn", conn, "path", + NETCONFIG_NETWORK_STATE_PATH, NULL); + + INFO("create network_state(%p)", object); + + dbus_g_connection_register_g_object(conn, NETCONFIG_NETWORK_STATE_PATH, object); + + INFO("network_state(%p) register DBus path(%s)", object, NETCONFIG_NETWORK_STATE_PATH); + + return object; +} diff --git a/src/network-statistics.c b/src/network-statistics.c new file mode 100644 index 0000000..cf9d3b2 --- /dev/null +++ b/src/network-statistics.c @@ -0,0 +1,452 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "wifi.h" +#include "log.h" +#include "util.h" +#include "netsupplicant.h" +#include "wifi-indicator.h" +#include "network-statistics.h" + +#include "netconfig-iface-network-statistics-glue.h" + +#define NETCONFIG_NETWORK_STATISTICS_PATH "/net/netconfig/network_statistics" + +#define NETCONFIG_PROCDEVFILE "/proc/net/dev" + +#define PROP_DEFAULT FALSE +#define PROP_DEFAULT_STR NULL + +enum { + PROP_O, + PROP_NETWORK_STATISTICS_CONN, + PROP_NETWORK_STATISTICS_PATH, +}; + +struct NetconfigNetworkStatisticsClass { + GObjectClass parent; +}; + +struct NetconfigNetworkStatistics { + GObject parent; + + DBusGConnection *conn; + gchar *path; +}; + +G_DEFINE_TYPE(NetconfigNetworkStatistics, netconfig_network_statistics, G_TYPE_OBJECT); + +static void __netconfig_network_statistics_gobject_get_property(GObject *object, + guint prop_id, GValue *value, GParamSpec *pspec) +{ + return; +} + +static void __netconfig_network_statistics_gobject_set_property(GObject *object, + guint prop_id, const GValue *value, GParamSpec *pspec) +{ + NetconfigNetworkStatistics *network_statistics = NETCONFIG_NETWORK_STATISTICS(object); + + switch (prop_id) { + case PROP_NETWORK_STATISTICS_CONN: + { + network_statistics->conn = g_value_get_boxed(value); + INFO("network_statistics(%p) set conn(%p)", network_statistics, network_statistics->conn); + break; + } + + case PROP_NETWORK_STATISTICS_PATH: + { + if (network_statistics->path) + g_free(network_statistics->path); + + network_statistics->path = g_value_dup_string(value); + INFO("network_statistics(%p) path(%s)", network_statistics, network_statistics->path); + + break; + } + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + +static void netconfig_network_statistics_init(NetconfigNetworkStatistics *network_statistics) +{ + DBG("network_statistics initialize"); + + network_statistics->conn = NULL; + network_statistics->path = g_strdup(PROP_DEFAULT_STR); +} + +static void netconfig_network_statistics_class_init(NetconfigNetworkStatisticsClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + DBG("class initialize"); + + object_class->get_property = __netconfig_network_statistics_gobject_get_property; + object_class->set_property = __netconfig_network_statistics_gobject_set_property; + + /* DBus register */ + dbus_g_object_type_install_info(NETCONFIG_TYPE_NETWORK_STATISTICS, + &dbus_glib_netconfig_iface_network_statistics_object_info); + + /* property */ + g_object_class_install_property(object_class, PROP_NETWORK_STATISTICS_CONN, + g_param_spec_boxed("conn", "CONNECTION", "DBus connection", + DBUS_TYPE_G_CONNECTION, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property(object_class, PROP_NETWORK_STATISTICS_PATH, + g_param_spec_string("path", "Path", "Object path", + PROP_DEFAULT_STR, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); +} + + +static gboolean __netconfig_wifi_get_bytes_statistics(guint64 *tx, guint64 *rx) +{ + gboolean ret = FALSE; + FILE *fp; + gchar buf[1024]; + gchar ifname[16] = { 0, }; + gchar *p_ifname = NULL, *p_entry = NULL; + gchar *ifname_ptr = &ifname[0]; + + *tx = 0; + *rx = 0; + + if (netconfig_wifi_get_ifname(&ifname_ptr) != TRUE) { + DBG("Fail to get Wi-Fi ifname from wpa_supplicant: %s", ifname_ptr); + return FALSE; + } + + fp = fopen(NETCONFIG_PROCDEVFILE, "r"); + if (fp == NULL) { + ERR("Failed to open file %s", NETCONFIG_PROCDEVFILE); + return FALSE; + } + + /* skip the first and second line */ + if (fgets(buf, sizeof(buf), fp) == NULL || + fgets(buf, sizeof(buf), fp) == NULL) + goto endline; + + while (fgets(buf, sizeof(buf), fp)) { + guint64 llval; + gulong lval; + + p_ifname = buf; + while (*p_ifname == ' ') p_ifname++; + p_entry = strchr(p_ifname, ':'); + *p_entry++ = '\0'; + + if (g_str_equal(p_ifname, ifname) != TRUE) + continue; + + /* read interface statistics */ + sscanf(p_entry, + "%llu %llu %lu %lu %lu %lu %lu %lu " + "%llu %llu %lu %lu %lu %lu %lu %lu", + rx, /* rx bytes */ + &llval, /* rx packet */ + &lval, /* rx errors */ + &lval, /* rx dropped */ + &lval, /* rx fifo errors */ + &lval, /* rx frame errors */ + &lval, /* rx compressed */ + &lval, /* rx multicast */ + + tx, /* tx bytes */ + &llval, /* tx packet */ + &lval, /* tx errors */ + &lval, /* tx dropped */ + &lval, /* tx fifo errors */ + &lval, /* collisions */ + &lval, /* tx carrier errors */ + &lval /* tx compressed */ + ); + + ret = TRUE; + break; + } + +endline: + fclose(fp); + return ret; +} + +gboolean netconfig_iface_network_statistics_get_wifi_total_tx_bytes(NetconfigNetworkStatistics *network_statistics, guint64 *total_bytes, GError **error) +{ + guint64 tx = 0, rx = 0; + guint64 tx_bytes = 0; + int val = 0; + + vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, &val); + tx_bytes = (guint64)val; + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) + *total_bytes = (guint64)tx + (guint64)tx_bytes; + else + *total_bytes = (guint64)tx_bytes; + + return TRUE; +} + +gboolean netconfig_iface_network_statistics_get_wifi_total_rx_bytes(NetconfigNetworkStatistics *network_statistics, guint64 *total_bytes, GError **error) +{ + guint64 tx = 0, rx = 0; + guint64 rx_bytes = 0; + int val = 0; + + vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, &val); + rx_bytes = (guint64)val; + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) + *total_bytes = (guint64)rx + (guint64)rx_bytes; + else + *total_bytes = (guint64)rx_bytes; + + return TRUE; +} + +gboolean netconfig_iface_network_statistics_get_wifi_last_tx_bytes(NetconfigNetworkStatistics *network_statistics, guint64 *last_bytes, GError **error) +{ + guint64 tx = 0, rx = 0; + guint64 tx_bytes = 0; + int val = 0; + + vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, &val); + tx_bytes = (guint64)val; + + if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) { + *last_bytes = (guint64)tx_bytes; + return TRUE; + } + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) + *last_bytes = (((guint64)tx - (guint64)tx_bytes) > (guint64)0) ? + ((guint64)tx - (guint64)tx_bytes) : (guint64)0; + else + *last_bytes = (guint64)tx_bytes; + + return TRUE; +} + +gboolean netconfig_iface_network_statistics_get_wifi_last_rx_bytes(NetconfigNetworkStatistics *network_statistics, guint64 *last_bytes, GError **error) +{ + guint64 tx = 0, rx = 0; + guint64 rx_bytes = 0; + int val = 0; + + vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, &val); + rx_bytes = (guint64)val; + + if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) { + *last_bytes = (guint64)rx_bytes; + return TRUE; + } + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) + *last_bytes = (((guint64)rx - (guint64)rx_bytes) > (guint64)0) ? + ((guint64)rx - (guint64)rx_bytes) : (guint64)0; + else + *last_bytes = (guint64)rx_bytes; + + return TRUE; +} + +gboolean netconfig_iface_network_statistics_reset_cellular_total_tx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error) +{ + vconf_set_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_SNT, 0); + return TRUE; +} + +gboolean netconfig_iface_network_statistics_reset_cellular_total_rx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error) +{ + vconf_set_int(VCONFKEY_NETWORK_CELLULAR_PKT_TOTAL_RCV, 0); + return TRUE; +} + +gboolean netconfig_iface_network_statistics_reset_cellular_last_tx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error) +{ + vconf_set_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_SNT, 0); + return TRUE; +} + +gboolean netconfig_iface_network_statistics_reset_cellular_last_rx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error) +{ + vconf_set_int(VCONFKEY_NETWORK_CELLULAR_PKT_LAST_RCV, 0); + return TRUE; +} + +gboolean netconfig_iface_network_statistics_reset_wifi_total_tx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error) +{ + guint64 tx = 0, rx = 0; + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, -(int)tx); + else + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, 0); + + return TRUE; +} + +gboolean netconfig_iface_network_statistics_reset_wifi_total_rx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error) +{ + guint64 tx = 0, rx = 0; + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, -(int)rx); + else + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, 0); + + return TRUE; +} + +gboolean netconfig_iface_network_statistics_reset_wifi_last_tx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error) +{ + guint64 tx = 0, rx = 0; + + if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) { + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, 0); + return TRUE; + } + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, (int)tx); + else + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, 0); + + return TRUE; +} + +gboolean netconfig_iface_network_statistics_reset_wifi_last_rx_bytes(NetconfigNetworkStatistics *network_statistics, GError **error) +{ + guint64 tx = 0, rx = 0; + + if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) { + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, 0); + return TRUE; + } + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) == TRUE) + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, (int)rx); + else + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, 0); + + return TRUE; +} + +void netconfig_wifi_statistics_update_powered_off(void) +{ + guint64 cur_tx = 0, cur_rx = 0; + guint64 prev_tx = 0, prev_rx = 0; + guint64 total_tx = 0, total_rx = 0; + int val = 0; + + if (__netconfig_wifi_get_bytes_statistics(&cur_tx, &cur_rx) != TRUE) + return; + + vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, &val); + prev_tx = (guint64)val; + + vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, &val); + prev_rx = (guint64)val; + + total_tx = prev_tx + cur_tx; + total_rx = prev_rx + cur_rx; + + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_SNT, (int)total_tx); + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_TOTAL_RCV, (int)total_rx); +} + +static void netconfig_wifi_statistics_update_state( + enum netconfig_wifi_service_state state, void *user_data) +{ + guint64 tx = 0, rx = 0; + guint64 last_tx = 0, last_rx = 0; + int val = 0; + static enum netconfig_wifi_service_state prev_state = NETCONFIG_WIFI_UNKNOWN; + + if (prev_state == NETCONFIG_WIFI_UNKNOWN) { + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, 0); + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, 0); + + prev_state = NETCONFIG_WIFI_IDLE; + return; + } + + if (__netconfig_wifi_get_bytes_statistics(&tx, &rx) != TRUE) + return; + + if (state == NETCONFIG_WIFI_CONNECTED) { + last_tx = tx; + last_rx = rx; + } else { + if (prev_state != NETCONFIG_WIFI_CONNECTED) + return; + + vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, &val); + last_tx = (guint64)val; + + vconf_get_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, &val); + last_rx = (guint64)val; + + last_tx = (((guint64)tx - (guint64)last_tx) > (guint64)0) ? + ((guint64)tx - (guint64)last_tx) : (guint64)0; + last_rx = (((guint64)rx - (guint64)last_rx) > (guint64)0) ? + ((guint64)rx - (guint64)last_rx) : (guint64)0; + } + + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_SNT, (int)last_tx); + vconf_set_int(VCONFKEY_NETWORK_WIFI_PKT_LAST_RCV, (int)last_rx); + + prev_state = state; +} + +static struct netconfig_wifi_state_notifier state_notifier = { + .netconfig_wifi_state_changed = netconfig_wifi_statistics_update_state, + .user_data = NULL, +}; + +gpointer netconfig_network_statistics_create_and_init(DBusGConnection *conn) +{ + GObject *object; + + g_return_val_if_fail(conn != NULL, NULL); + + object = g_object_new(NETCONFIG_TYPE_NETWORK_STATISTICS, "conn", conn, "path", + NETCONFIG_NETWORK_STATISTICS_PATH, NULL); + + INFO("create network_statistics(%p)", object); + + dbus_g_connection_register_g_object(conn, NETCONFIG_NETWORK_STATISTICS_PATH, object); + + INFO("network_statistics(%p) register DBus path(%s)", object, NETCONFIG_NETWORK_STATISTICS_PATH); + + netconfig_wifi_statistics_update_state(NETCONFIG_WIFI_IDLE, NULL); + netconfig_wifi_state_notifier_register(&state_notifier); + + return object; +} diff --git a/src/signal-handler.c b/src/signal-handler.c new file mode 100644 index 0000000..1aa7f10 --- /dev/null +++ b/src/signal-handler.c @@ -0,0 +1,394 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "util.h" +#include "netdbus.h" +#include "netsupplicant.h" +#include "wifi-state.h" +#include "wifi-indicator.h" +#include "wifi-ssid-scan.h" +#include "wifi-background-scan.h" +#include "network-state.h" +#include "neterror.h" +#include "wifi.h" + +#define SIGNAL_SCAN_DONE "ScanDone" +#define SIGNAL_BSS_ADDED "BSSAdded" +#define SIGNAL_PROPERTIES_CHANGED "PropertiesChanged" + +#define CONNMAN_SIGNAL_SERVICES_CHANGED "ServicesChanged" +#define CONNMAN_SIGNAL_PROPERTY_CHANGED "PropertyChanged" + +#define CONNMAN_MANAGER_SIGNAL_FILTER "type='signal',interface='net.connman.Manager'" +#define CONNMAN_TECHNOLOGY_SIGNAL_FILTER "type='signal',interface='net.connman.Technology'" +#define CONNMAN_SERVICE_SIGNAL_FILTER "type='signal',interface='net.connman.Service'" +#define SUPPLICANT_INTERFACE_SIGNAL_FILTER "type='signal',interface='fi.w1.wpa_supplicant1.Interface'" + + +static DBusConnection *signal_connection = NULL; + +static char *__netconfig_get_property(DBusMessage *msg, int *prop_value) +{ + DBusMessageIter args, variant; + char *property = NULL; + dbus_bool_t data; + + /** read these parameters */ + if (!dbus_message_iter_init(msg, &args)) { + ERR("Message does not have parameters"); + } else if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) { + ERR("Argument is not string"); + } else { + dbus_message_iter_get_basic(&args, &property); + dbus_message_iter_next(&args); + dbus_message_iter_recurse(&args, &variant); + /* Right now, checking for only 'Powered' property which has + * Boolean type values + */ + if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_BOOLEAN) { + dbus_message_iter_get_basic(&variant, &data); + if (data) + *prop_value = TRUE; + else + *prop_value = FALSE; + } else { + *prop_value = FALSE; + } + } + + return property; +} + +static void __netconfig_wifi_technology_state_signal_handler( + const char *property, int prop_value) +{ + static int previous_technology_state = FALSE; + GError **error = NULL; + + if (property == NULL || g_str_equal(property, "Powered") != TRUE) + return; + + if (previous_technology_state == prop_value) { + INFO("Same as previous state"); + return; + } + + previous_technology_state = prop_value; + + INFO("Technology property - [%s], prop_value - [%d]", + property, prop_value); + + if (prop_value == FALSE) { + enum netconfig_wifi_tech_state state = NETCONFIG_WIFI_TECH_OFF; + + state = netconfig_wifi_get_technology_state(); + INFO("Wi-Fi technology state: %d", state); + + if (NETCONFIG_WIFI_TECH_OFF == state || + NETCONFIG_WIFI_TECH_UNKNOWN == state) { + if (netconfig_wifi_remove_driver() == TRUE) { + netconfig_wifi_update_power_state(FALSE); + + netconfig_wifi_notify_power_completed(FALSE); + } else { + netconfig_error_wifi_driver_failed(error); + } + } + } else { + netconfig_wifi_update_power_state(TRUE); + netconfig_wifi_device_picker_service_start(); + + netconfig_wifi_notify_power_completed(TRUE); + } +} + +static void __netconfig_wifi_service_state_signal_handler(DBusMessage *msg) +{ + char *sigvalue = NULL; + char *property = NULL; + char *service_profile = NULL; + DBusMessageIter args, variant; + + service_profile = (char *)dbus_message_get_path(msg); + if (service_profile == NULL) + return; + + dbus_message_iter_init(msg, &args); + dbus_message_iter_get_basic(&args, &sigvalue); + if (sigvalue == NULL) + return; + + if (g_str_equal(sigvalue, "State") == TRUE) { + dbus_message_iter_next(&args); + dbus_message_iter_recurse(&args, &variant); + dbus_message_iter_get_basic(&variant, &property); + + DBG("[%s] %s", property, service_profile); + if (netconfig_is_wifi_profile(service_profile) == TRUE) { + int wifi_state = 0; + + vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); + if (wifi_state == VCONFKEY_WIFI_OFF) + return; + + if (g_str_equal(property, "ready") == TRUE || + g_str_equal(property, "online") == TRUE) { + if (wifi_state >= VCONFKEY_WIFI_CONNECTED) + return; + + netconfig_set_default_profile(service_profile); + + netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTED); + + } else if (g_str_equal(property, "failure") == TRUE || + g_str_equal(property, "disconnect") == TRUE || + g_str_equal(property, "idle") == TRUE) { + if (netconfig_get_default_profile() == NULL || + netconfig_is_wifi_profile(netconfig_get_default_profile()) + != TRUE) { + netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_IDLE); + return; + } + + if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE) + return; + + netconfig_set_default_profile(NULL); + + netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_IDLE); + + } else if (g_str_equal(property, "association") == TRUE || + g_str_equal(property, "configuration") == TRUE) { + if (netconfig_get_default_profile() == NULL || + netconfig_is_wifi_profile(netconfig_get_default_profile()) + != TRUE) { + netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTING); + return; + } + + if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE) + return; + + netconfig_set_default_profile(NULL); + + netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTING); + } + } else { + if (g_str_equal(property, "ready") == TRUE || + g_str_equal(property, "online") == TRUE) { + if (netconfig_get_default_profile() == NULL) + netconfig_set_default_profile(service_profile); + + } else if (g_str_equal(property, "failure") == TRUE || + g_str_equal(property, "disconnect") == TRUE || + g_str_equal(property, "idle") == TRUE) { + if (netconfig_get_default_profile() == NULL) + return; + + if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE) + return; + + netconfig_set_default_profile(NULL); + + } else if (g_str_equal(property, "association") == TRUE || + g_str_equal(property, "configuration") == TRUE) { + if (netconfig_get_default_profile() == NULL) + return; + + if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE) + return; + + netconfig_set_default_profile(NULL); + } + } + } +} + +static DBusHandlerResult __netconfig_signal_filter_handler( + DBusConnection *conn, DBusMessage *msg, void *user_data) +{ + char *sigvalue = NULL; + + if (msg == NULL) { + DBG("Invalid Message. Ignore"); + return DBUS_HANDLER_RESULT_HANDLED; + } + + if (dbus_message_is_signal(msg, CONNMAN_MANAGER_INTERFACE, + CONNMAN_SIGNAL_PROPERTY_CHANGED)) { + /* We have handled this message, don't pass it on */ + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal(msg, CONNMAN_TECHNOLOGY_INTERFACE, + CONNMAN_SIGNAL_PROPERTY_CHANGED)) { + int prop_value = FALSE; + char *technology_path = NULL; + + technology_path = (char *)dbus_message_get_path(msg); + INFO("Technology object path: %s", technology_path); + + if (g_str_has_prefix(technology_path, + CONNMAN_WIFI_TECHNOLOGY_PREFIX) == FALSE) { + return DBUS_HANDLER_RESULT_HANDLED; + } + + sigvalue = __netconfig_get_property(msg, &prop_value); + if (sigvalue == NULL) + return DBUS_HANDLER_RESULT_HANDLED; + + INFO("Technology Property - [%s], Value - [%d]", sigvalue, prop_value); + __netconfig_wifi_technology_state_signal_handler( + (const char *)sigvalue, prop_value); + + /* We have handled this message, don't pass it on */ + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal(msg, CONNMAN_SERVICE_INTERFACE, + CONNMAN_SIGNAL_PROPERTY_CHANGED)) { + __netconfig_wifi_service_state_signal_handler(msg); + + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal(msg, CONNMAN_MANAGER_INTERFACE, + CONNMAN_SIGNAL_SERVICES_CHANGED)) { + DBG("Received CONNMAN_SIGNAL_SERVICES_CHANGED message"); + netconfig_wifi_check_network_notification(msg); + + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface", + SIGNAL_PROPERTIES_CHANGED)) { + dbus_bool_t scanning = FALSE; + void *property = &scanning; + + if (netconfig_dbus_get_basic_params_array(msg, + &sigvalue, &property) != TRUE) + return DBUS_HANDLER_RESULT_HANDLED; + + if (sigvalue == NULL) + return DBUS_HANDLER_RESULT_HANDLED; + + if (scanning == TRUE) + netconfig_wifi_set_scanning(TRUE); + + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface", + SIGNAL_BSS_ADDED)) { + if (netconfig_wifi_get_ssid_scan_state() == TRUE) + netconfig_wifi_bss_added(msg); + + return DBUS_HANDLER_RESULT_HANDLED; + } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface", + SIGNAL_SCAN_DONE)) { + netconfig_wifi_set_scanning(FALSE); + + if (netconfig_wifi_get_bgscan_state() != TRUE) { + if (netconfig_wifi_get_ssid_scan_state() == TRUE) + netconfig_wifi_notify_ssid_scan_done(); + else + netconfig_wifi_ssid_scan(NULL); + } + + return DBUS_HANDLER_RESULT_HANDLED; + } + + return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; +} + +void netconfig_register_signal(void) +{ + DBusConnection *conn = NULL; + DBusError err; + + DBG("Register DBus signal filters"); + + dbus_error_init(&err); + conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (conn == NULL) { + ERR("Error! Failed to connect to the D-BUS daemon: [%s]", + err.message); + dbus_error_free(&err); + return; + } + + signal_connection = conn; + + dbus_connection_setup_with_g_main(conn, NULL); + + /* listening to messages from all objects as no path is specified */ + /* see signals from the given interface */ + dbus_bus_add_match(conn, CONNMAN_MANAGER_SIGNAL_FILTER, &err); + dbus_connection_flush(conn); + if (dbus_error_is_set(&err)) { + ERR("Error! Match Error (%s)", err.message); + dbus_error_free(&err); + return; + } + + dbus_bus_add_match(conn, CONNMAN_TECHNOLOGY_SIGNAL_FILTER, &err); + dbus_connection_flush(conn); + if (dbus_error_is_set(&err)) { + ERR("Error! Match Error (%s)", err.message); + dbus_error_free(&err); + return; + } + + dbus_bus_add_match(conn, CONNMAN_SERVICE_SIGNAL_FILTER, &err); + dbus_connection_flush(conn); + if (dbus_error_is_set(&err)) { + ERR("Error! Match Error (%s)", err.message); + dbus_error_free(&err); + return; + } + + dbus_bus_add_match(conn, SUPPLICANT_INTERFACE_SIGNAL_FILTER, &err); + dbus_connection_flush(conn); + if (dbus_error_is_set(&err)) { + ERR("Error! Match Error (%s)", err.message); + dbus_error_free(&err); + return; + } + + if (dbus_connection_add_filter(conn, + __netconfig_signal_filter_handler, NULL, NULL) == FALSE) { + ERR("Error! dbus_connection_add_filter() failed"); + return; + } + + INFO("Successfully register signal filters"); +} + +void netconfig_deregister_signal(void) +{ + if (signal_connection == NULL) { + ERR("Error! Already de-registered. Nothing to be done"); + return; + } + + dbus_connection_remove_filter(signal_connection, + __netconfig_signal_filter_handler, NULL); + INFO("Successfully remove DBus signal filters"); + + dbus_connection_unref(signal_connection); + signal_connection = NULL; +} diff --git a/src/utils/emulator.c b/src/utils/emulator.c new file mode 100644 index 0000000..f0b07da --- /dev/null +++ b/src/utils/emulator.c @@ -0,0 +1,118 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "emulator.h" + +static gboolean netconfig_is_emulated = FALSE; + +static gboolean __netconfig_emulator_test_emulation_env(void) +{ + struct utsname buf; + const char *EMUL_UTSNAME_MACHINE_SUFFIX = "emulated"; + + DBG("Test emulation environment"); + + uname(&buf); + + if (g_str_has_suffix(buf.machine, EMUL_UTSNAME_MACHINE_SUFFIX) == TRUE) + return TRUE; + + return FALSE; +} + +static void __netconfig_emulator_set_ip(void) +{ + const int BUF_LEN_MAX = 255; + const char EMUL_IFNAME[] = "eth0"; + char ip[BUF_LEN_MAX]; + int sockfd = 0; + struct ifreq ifr; + + if ((sockfd = socket(PF_INET, SOCK_DGRAM, 0)) < 0) { + ERR("Failed to open socket"); + return; + } + + memset(&ifr, 0, sizeof(struct ifreq)); + g_strlcpy((char*)&ifr.ifr_name, EMUL_IFNAME, sizeof(EMUL_IFNAME)); + + if (ioctl(sockfd, SIOCGIFADDR, &ifr) < 0) { + ERR("Error getting IP address"); + + close(sockfd); + return; + } + + g_strlcpy(ip, (char*)inet_ntoa(((struct sockaddr_in*)&ifr.ifr_addr)->sin_addr), BUF_LEN_MAX); + + vconf_set_str(VCONFKEY_NETWORK_IP, ip); + + close(sockfd); +} + +static void __netconfig_emulator_set_proxy(void) +{ + const char HTTP_PROXY[] = "http_proxy"; + char *proxy = NULL; + + proxy = getenv(HTTP_PROXY); + DBG("Get system proxy: %s", proxy); + + if(proxy != NULL) + vconf_set_str(VCONFKEY_NETWORK_PROXY, proxy); +} + +static void __netconfig_emulator_set_network_state(void) +{ + vconf_set_int(VCONFKEY_NETWORK_CONFIGURATION_CHANGE_IND, 1); + vconf_set_int(VCONFKEY_NETWORK_STATUS, VCONFKEY_NETWORK_ETHERNET); + vconf_set_int(VCONFKEY_DNET_STATE, VCONFKEY_DNET_OFF); +} + +static void __netconfig_emulator_config_emul_env(void) +{ + __netconfig_emulator_set_ip(); + __netconfig_emulator_set_proxy(); + __netconfig_emulator_set_network_state(); +} + +gboolean netconfig_emulator_is_emulated(void) +{ + return netconfig_is_emulated; +} + +void netconfig_emulator_test_and_start(void) +{ + netconfig_is_emulated = __netconfig_emulator_test_emulation_env(); + + DBG("Emulation environment tested: %s", netconfig_is_emulated ? "It's emulated" : "Not emulated"); + + if (netconfig_is_emulated == TRUE) + __netconfig_emulator_config_emul_env(); +} diff --git a/src/utils/mdm-private.c b/src/utils/mdm-private.c new file mode 100644 index 0000000..5277c6e --- /dev/null +++ b/src/utils/mdm-private.c @@ -0,0 +1,25 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "mdm-private.h" + +gboolean netconfig_is_wifi_allowed(void) +{ + return TRUE; +} diff --git a/src/utils/util.c b/src/utils/util.c new file mode 100644 index 0000000..07680a3 --- /dev/null +++ b/src/utils/util.c @@ -0,0 +1,429 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "util.h" +#include "neterror.h" +#include "wifi-state.h" + +#define WIFI_MAC_INFO_FILE "/opt/etc/.mac.info" +#define WIFI_MAC_INFO_LENGTH 17 + +GKeyFile *netconfig_keyfile_load(const char *pathname) +{ + GKeyFile *keyfile = NULL; + GError *error = NULL; + + keyfile = g_key_file_new(); + if (g_key_file_load_from_file(keyfile, pathname, 0, &error) != TRUE) { + DBG("Unable to open %s, error %s", pathname, error->message); + g_error_free(error); + + g_key_file_free(keyfile); + keyfile = NULL; + } + + return keyfile; +} + +void netconfig_keyfile_save(GKeyFile *keyfile, const char *pathname) +{ + gsize size = 0; + GError *error = NULL; + gchar *keydata = NULL; + gchar *needle = NULL, *directory = NULL; + + directory = g_strdup(pathname); + needle = g_strrstr(directory, "/"); + + if (needle != NULL) + *needle = '\0'; + + if (directory == NULL || (*directory) == '\0') { + g_free(directory); + return; + } + + if (g_file_test(directory, G_FILE_TEST_IS_DIR) != TRUE) { + if (g_mkdir_with_parents(directory, + S_IRUSR | S_IWUSR | S_IXUSR) != 0) { + g_free(directory); + return; + } + } + g_free(directory); + + keydata = g_key_file_to_data(keyfile, &size, &error); + if (g_file_set_contents(pathname, keydata, size, &error) != TRUE) { + DBG("Unable to save %s, error %s", pathname, error->message); + g_error_free(error); + } + + if (chmod(pathname, S_IRUSR | S_IWUSR) != 0) + DBG("Unable to change permission of %s", pathname); + + g_free(keydata); + + g_key_file_free(keyfile); +} + +void netconfig_start_timer_seconds(guint secs, + gboolean(*callback) (gpointer), void *user_data, guint *timer_id) +{ + guint t_id = 0; + + if (callback == NULL) { + ERR("callback function is NULL"); + return; + } + + if ((timer_id != NULL && *timer_id != 0)) { + ERR("timer already is registered"); + return; + } + + t_id = g_timeout_add_seconds(secs, callback, user_data); + + if (t_id == 0) { + ERR("Can't add timer"); + return; + } + + if (timer_id != NULL) + *timer_id = t_id; +} + +void netconfig_start_timer(guint msecs, + gboolean(*callback) (gpointer), void *user_data, guint *timer_id) +{ + guint t_id = 0; + + INFO("Register timer with callback pointer (%p)", callback); + + if (callback == NULL) { + ERR("callback function is NULL"); + return; + } + + if ((timer_id != NULL && *timer_id != 0)) { + ERR("timer already is registered"); + return; + } + + t_id = g_timeout_add(msecs, callback, user_data); + + if (t_id == 0) { + ERR("Can't add timer"); + return; + } + + if (timer_id != NULL) + *timer_id = t_id; +} + +void netconfig_stop_timer(guint *timer_id) +{ + if (timer_id == NULL) { + ERR("timer is NULL"); + return; + } + + if (*timer_id != 0) { + g_source_remove(*timer_id); + *timer_id = 0; + } +} + +static gboolean __netconfig_test_device_picker() +{ + char *favorite_wifi_service = NULL; + + favorite_wifi_service = netconfig_wifi_get_favorite_service(); + if (favorite_wifi_service != NULL) { + g_free(favorite_wifi_service); + return FALSE; + } + + return TRUE; +} + +static void __netconfig_pop_device_picker(void) +{ + int rv = 0; + bundle *b = NULL; + int wifi_ug_state = 0; + + vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state); + if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) + return; + + b = bundle_create(); + + DBG("Launch Wi-Fi device picker"); + rv = syspopup_launch("wifi-qs", b); + + bundle_free(b); +} + +static gboolean __netconfig_wifi_try_device_picker(gpointer data) +{ + if (__netconfig_test_device_picker() == TRUE) + __netconfig_pop_device_picker(); + + return FALSE; +} + +static guint __netconfig_wifi_device_picker_timer_id(gboolean is_set_method, + guint timer_id) +{ + static guint netconfig_wifi_device_picker_service_timer = 0; + + if (is_set_method != TRUE) + return netconfig_wifi_device_picker_service_timer; + + if (netconfig_wifi_device_picker_service_timer != timer_id) + netconfig_wifi_device_picker_service_timer = timer_id; + + return netconfig_wifi_device_picker_service_timer; +} + +static void __netconfig_wifi_device_picker_set_timer_id(guint timer_id) +{ + __netconfig_wifi_device_picker_timer_id(TRUE, timer_id); +} + +static guint __netconfig_wifi_device_picker_get_timer_id(void) +{ + return __netconfig_wifi_device_picker_timer_id(FALSE, -1); +} + +void netconfig_wifi_device_picker_service_start(void) +{ + int wifi_ug_state; + const int NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL = 700; + guint timer_id = 0; + + vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &wifi_ug_state); + if (wifi_ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) + return; + + DBG("Register device picker timer with %d milliseconds", + NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL); + + netconfig_start_timer(NETCONFIG_WIFI_DEVICE_PICKER_INTERVAL, + __netconfig_wifi_try_device_picker, NULL, &timer_id); + + __netconfig_wifi_device_picker_set_timer_id(timer_id); +} + +void netconfig_wifi_device_picker_service_stop(void) +{ + guint timer_id = 0; + + timer_id = __netconfig_wifi_device_picker_get_timer_id(); + if (timer_id == 0) + return; + + DBG("Clear device picker timer with timer_id %d", timer_id); + + netconfig_stop_timer(&timer_id); + + __netconfig_wifi_device_picker_set_timer_id(timer_id); +} + +gboolean netconfig_is_wifi_direct_on(void) +{ + int wifi_direct_state = 0; + + vconf_get_int(VCONFKEY_WIFI_DIRECT_STATE, &wifi_direct_state); + + DBG("Wi-Fi direct mode %d", wifi_direct_state); + return (wifi_direct_state != 0) ? TRUE : FALSE; +} + +gboolean netconfig_is_wifi_tethering_on(void) +{ + int wifi_tethering_state = 0; + + vconf_get_int(VCONFKEY_MOBILE_HOTSPOT_MODE, &wifi_tethering_state); + + DBG("Wi-Ti tethering mode %d", wifi_tethering_state); + if (wifi_tethering_state & VCONFKEY_MOBILE_HOTSPOT_MODE_WIFI) + return TRUE; + + return FALSE; +} + +/* args[] and env[] should be terminated with NULL pointer */ +gboolean netconfig_execute_file(const char *file_path, + char *const args[], char *const env[]) +{ + pid_t pid = 0; + int rv = 0; + errno = 0; + + if (!(pid = fork())) { + register unsigned int index = 0; + INFO("pid(%d), ppid (%d)", getpid(), getppid()); + INFO("Inside child, exec (%s) command", file_path); + + index = 0; + while (args[index] != NULL) { + INFO(" %s", args[index]); + index++; + } + + errno = 0; + if (execve(file_path, args, env) == -1) { + DBG("Fail to execute command...(%s)", + strerror(errno)); + return FALSE; + } + } else if (pid > 0) { + if (waitpid(pid, &rv, 0) == -1) { + DBG("wait pid (%u) rv (%d)", pid, rv); + + if (WIFEXITED(rv)) { + DBG("exited, rv=%d", WEXITSTATUS(rv)); + } else if (WIFSIGNALED(rv)) { + DBG("killed by signal %d", WTERMSIG(rv)); + } else if (WIFSTOPPED(rv)) { + DBG("stopped by signal %d", WSTOPSIG(rv)); + } else if (WIFCONTINUED(rv)) { + DBG("continued"); + } + } + return TRUE; + } + + DBG("failed to fork()...(%s)", strerror(errno)); + return FALSE; +} + +gboolean netconfig_iface_wifi_launch_direct(NetconfigWifi *wifi, GError **error) +{ + gboolean ret = TRUE; + + DBG("Launch Wi-Fi direct daemon"); + + const char *path = "/usr/bin/wifi-direct-server.sh"; + char *const args[] = { "wifi-direct-server.sh", "start", NULL}; + char *const env[] = { NULL }; + + ret = netconfig_execute_file(path, args, env); + + if (ret != TRUE) { + INFO("Failed to launch Wi-Fi direct daemon"); + + netconfig_error_wifi_direct_failed(error); + } + + return ret; +} + +void netconfig_add_wifi_found_notification(void) +{ + int ret; + bundle *b = bundle_create(); + + bundle_add(b, "_SYSPOPUP_TYPE_", "add_found_ap_noti"); + + ret = aul_launch_app("org.tizen.net-popup", b); + + bundle_free(b); + + if (ret >= 0) + DBG("Successfully added notification"); + else + ERR("Unable to launch noti-popup. Err = %d", ret); +} + +void netconfig_del_wifi_found_notification(void) +{ + int ret; + bundle *b = bundle_create(); + + bundle_add(b, "_SYSPOPUP_TYPE_", "del_found_ap_noti"); + + ret = aul_launch_app("org.tizen.net-popup", b); + + bundle_free(b); + + if (ret >= 0) + DBG("Successfully deleted notification"); + else + ERR("Unable to launch noti-popup. Err = %d", ret); +} + + +void netconfig_set_wifi_mac_address(void) +{ + FILE *fp; + char buf[WIFI_MAC_INFO_LENGTH + 1]; + char *mac_info; + + mac_info = vconf_get_str(VCONFKEY_WIFI_BSSID_ADDRESS); + if (mac_info == NULL) { + ERR("Failed to open vconf key %s", VCONFKEY_WIFI_BSSID_ADDRESS); + return; + } + + INFO("%s : %s", VCONFKEY_WIFI_BSSID_ADDRESS, mac_info); + + fp = fopen(WIFI_MAC_INFO_FILE, "r"); + if (fp == NULL) { + ERR("Failed to open file %s", WIFI_MAC_INFO_FILE); + g_free(mac_info); + return; + } + + if (fgets(buf, sizeof(buf), fp) == NULL) { + ERR("Failed to get MAC info from %s", WIFI_MAC_INFO_FILE); + goto done; + } + + INFO("%s : %s", WIFI_MAC_INFO_FILE, buf); + + if (strlen(buf) < WIFI_MAC_INFO_LENGTH) { + ERR("Failed to get MAC info from %s", WIFI_MAC_INFO_FILE); + goto done; + } + + buf[WIFI_MAC_INFO_LENGTH] = '\0'; + + if (g_str_equal(mac_info, buf) == TRUE) + goto done; + + if (vconf_set_str(VCONFKEY_WIFI_BSSID_ADDRESS, buf) != 0) + ERR("Failed to set MAC info to %s", VCONFKEY_WIFI_BSSID_ADDRESS); + +done: + g_free(mac_info); + fclose(fp); +} diff --git a/src/wifi-agent.c b/src/wifi-agent.c new file mode 100644 index 0000000..84a1644 --- /dev/null +++ b/src/wifi-agent.c @@ -0,0 +1,193 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "wifi-agent.h" +#include "log.h" +#include "wifi.h" +#include "netdbus.h" + +static NetconfigWifiAgentFields agent; + +static void _netconfig_agent_clear_fields(void) +{ + DBG("_netconfig_agent_clear_fields"); + + g_free(agent.passphrase); + g_free(agent.name); + g_free(agent.identity); +} + +gboolean netconfig_agent_register(void) +{ + DBG("netconfig_agent_register"); + + DBusMessage *reply = NULL; + char param1[64] = ""; + char *param_array[] = {NULL, NULL}; + + snprintf(param1, 64, "objpath:%s", NETCONFIG_WIFI_PATH); + param_array[0] = param1; + + reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, + "RegisterAgent", param_array); + + if (reply == NULL) { + ERR("Error! Request failed"); + return FALSE; + } + + dbus_message_unref(reply); + + return TRUE; +} + +gboolean netconfig_agent_unregister(void) +{ + DBG("netconfig_agent_unregister"); + + DBusMessage *reply = NULL; + char param1[64] = ""; + char *param_array[] = {NULL, NULL}; + + snprintf(param1, 64, "objpath:%s", NETCONFIG_WIFI_PATH); + param_array[0] = param1; + + reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, + "UnregisterAgent", param_array); + + if (reply == NULL) { + ERR("Error! Request failed"); + return FALSE; + } + + dbus_message_unref(reply); + + /* Clearing the agent fields */ + _netconfig_agent_clear_fields(); + + return TRUE; +} + +gboolean netconfig_iface_wifi_set_field(NetconfigWifi *wifi, + GHashTable *fields, GError **error) +{ + DBG("netconfig_iface_wifi_set_field"); + g_return_val_if_fail(wifi != NULL, FALSE); + + GHashTableIter iter; + gpointer field, value; + + g_hash_table_iter_init(&iter, fields); + while (g_hash_table_iter_next(&iter, &field, &value)) { + DBG("Field - [%s]", field); + if (!strcmp(field, NETCONFIG_AGENT_FIELD_PASSPHRASE)) { + if (NULL != agent.passphrase) { + g_free(agent.passphrase); + } + + if (NULL != value) { + agent.passphrase = g_strdup(value); + DBG("Set the agent field[%s] - [%s]", field, + agent.passphrase); + } + } else if (!strcmp(field, NETCONFIG_AGENT_FIELD_NAME)) { + if (NULL != agent.name) { + g_free(agent.name); + } + + if (NULL != value) { + agent.name = g_strdup(value); + DBG("Set the agent field[%s] - [%s]", + field, agent.name); + } + } else if (!strcmp(field, NETCONFIG_AGENT_FIELD_IDENTITY)) { + if (NULL != agent.identity) { + g_free(agent.identity); + } + + if (NULL != value) { + agent.identity = g_strdup(value); + DBG("Set the agent field[%s] - [%s]", + field, agent.identity); + } + } + } + + return TRUE; +} + +gboolean netconfig_iface_wifi_request_input(NetconfigWifi *wifi, + gchar *service, GHashTable *fields, + DBusGMethodInvocation *context) +{ + DBG("netconfig_iface_wifi_request_input"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + GHashTableIter iter; + gpointer field, value; + GHashTable *out_table = NULL; + GValue *ret_value = NULL; + + if (NULL == service) + return FALSE; + + DBG("Service - [%s]", service); + + out_table = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, + g_free); + if (NULL == out_table) + return FALSE; + + g_hash_table_iter_init(&iter, fields); + while (g_hash_table_iter_next(&iter, &field, &value)) { + DBG("Field - [%s]", field); + if (!strcmp(field, NETCONFIG_AGENT_FIELD_PASSPHRASE)) { + DBG("Adding the field-value in table"); + ret_value = g_slice_new0(GValue); + g_value_init(ret_value, G_TYPE_STRING); + g_value_set_string(ret_value, agent.passphrase); + g_hash_table_insert(out_table, g_strdup(field), + ret_value); + } else if (!strcmp(field, NETCONFIG_AGENT_FIELD_NAME)) { + DBG("Adding the field-value in table"); + ret_value = g_slice_new0(GValue); + g_value_init(ret_value, G_TYPE_STRING); + g_value_set_string(ret_value, agent.name); + g_hash_table_insert(out_table, g_strdup(field), + ret_value); + } else if (!strcmp(field, NETCONFIG_AGENT_FIELD_IDENTITY)) { + DBG("Adding the field-value in table"); + ret_value = g_slice_new0(GValue); + g_value_init(ret_value, G_TYPE_STRING); + g_value_set_string(ret_value, agent.identity); + g_hash_table_insert(out_table, g_strdup(field), + ret_value); + } + } + + dbus_g_method_return(context, out_table); + + return TRUE; +} diff --git a/src/wifi-background-scan.c b/src/wifi-background-scan.c new file mode 100644 index 0000000..224c184 --- /dev/null +++ b/src/wifi-background-scan.c @@ -0,0 +1,234 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "util.h" +#include "wifi.h" +#include "netdbus.h" +#include "wifi-state.h" +#include "wifi-background-scan.h" + +#define SCAN_PERIODIC_DELAY 10 +#define SCAN_EXPONENTIAL_MIN 4 +#define SCAN_EXPONENTIAL_MAX 128 + +enum { + WIFI_BGSCAN_MODE_EXPONENTIAL = 0x00, + WIFI_BGSCAN_MODE_PERIODIC, + WIFI_BGSCAN_MODE_MAX, +}; + +struct bgscan_timer_data { + guint time; + guint mode; + guint timer_id; +}; + +static gboolean netconfig_wifi_scanning = FALSE; + +static struct bgscan_timer_data *__netconfig_wifi_bgscan_get_bgscan_data(void) +{ + static struct bgscan_timer_data timer_data = {SCAN_EXPONENTIAL_MIN, WIFI_BGSCAN_MODE_EXPONENTIAL, 0}; + + return &timer_data; +} + +static guint __netconfig_wifi_bgscan_mode(gboolean is_set_mode, guint mode) +{ + static guint bgscan_mode = WIFI_BGSCAN_MODE_EXPONENTIAL; + + if (is_set_mode != TRUE) + return bgscan_mode; + + if (mode < WIFI_BGSCAN_MODE_MAX) + bgscan_mode = mode; + + DBG("Wi-Fi background scan mode set %d", bgscan_mode); + + return bgscan_mode; +} + +static void __netconfig_wifi_bgscan_set_mode(guint mode) +{ + __netconfig_wifi_bgscan_mode(TRUE, mode); +} + +static guint __netconfig_wifi_bgscan_get_mode(void) +{ + return __netconfig_wifi_bgscan_mode(FALSE, -1); +} + +static gboolean __netconfig_wifi_bgscan_request_connman_scan(void) +{ + DBusMessage *reply = NULL; + + if (netconfig_wifi_state_get_service_state() == NETCONFIG_WIFI_CONNECTED) + if (__netconfig_wifi_bgscan_get_mode() == WIFI_BGSCAN_MODE_EXPONENTIAL) + return FALSE; + + if (netconfig_wifi_state_get_service_state() == NETCONFIG_WIFI_CONNECTING) + return FALSE; + + netconfig_wifi_set_scanning(TRUE); + + reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE, CONNMAN_WIFI_TECHNOLOGY_PREFIX, + CONNMAN_TECHNOLOGY_INTERFACE, "Scan", NULL); + + if (reply == NULL) { + ERR("Error! Request failed"); + return FALSE; + } + + dbus_message_unref(reply); + + return TRUE; +} + +static gboolean __netconfig_wifi_bgscan_request_scan(gpointer data); + +static void __netconfig_wifi_bgscan_start_timer(struct bgscan_timer_data *data) +{ + if (data == NULL) + return; + + netconfig_stop_timer(&(data->timer_id)); + + data->mode = __netconfig_wifi_bgscan_get_mode(); + + switch (data->mode) { + case WIFI_BGSCAN_MODE_EXPONENTIAL: + if (data->time == 0) + data->time = SCAN_EXPONENTIAL_MIN; + else if ((data->time >= SCAN_EXPONENTIAL_MAX) || + (data->time > SCAN_EXPONENTIAL_MAX / 2)) + data->time = SCAN_EXPONENTIAL_MAX; + else + data->time = data->time * 2; + + break; + case WIFI_BGSCAN_MODE_PERIODIC: + data->time = SCAN_PERIODIC_DELAY; + + break; + default: + DBG("Error! Wi-Fi background scan mode [%d]", data->mode); + return; + } + + DBG("Register background scan timer with %d seconds", data->time); + + netconfig_start_timer_seconds(data->time, + __netconfig_wifi_bgscan_request_scan, data, &(data->timer_id)); +} + +static void __netconfig_wifi_bgscan_stop_timer(struct bgscan_timer_data *data) +{ + if (data == NULL) + return; + + netconfig_stop_timer(&(data->timer_id)); +} + +static gboolean __netconfig_wifi_bgscan_request_scan(gpointer data) +{ + struct bgscan_timer_data *timer = (struct bgscan_timer_data *)data; + int pm_state = VCONFKEY_PM_STATE_NORMAL; + + if (timer == NULL) + return FALSE; + + /* In case of LCD off, we don't need Wi-Fi scan */ + vconf_get_int(VCONFKEY_PM_STATE, &pm_state); + if (pm_state >= VCONFKEY_PM_STATE_LCDOFF) + return TRUE; + + __netconfig_wifi_bgscan_stop_timer(timer); + + DBG("Request Wi-Fi scan to ConnMan"); + __netconfig_wifi_bgscan_request_connman_scan(); + + __netconfig_wifi_bgscan_start_timer(timer); + + return FALSE; +} + +void netconfig_wifi_bgscan_start(void) +{ + struct bgscan_timer_data *timer_data = + __netconfig_wifi_bgscan_get_bgscan_data(); + + if (timer_data == NULL) + return; + + DBG("Wi-Fi background scan start"); + + __netconfig_wifi_bgscan_start_timer(timer_data); +} + +void netconfig_wifi_bgscan_stop(void) +{ + struct bgscan_timer_data *timer_data = + __netconfig_wifi_bgscan_get_bgscan_data(); + + if (timer_data == NULL) + return; + + DBG("Wi-Fi background scan stop"); + + timer_data->time = SCAN_EXPONENTIAL_MIN; + + __netconfig_wifi_bgscan_stop_timer(timer_data); +} + +gboolean netconfig_wifi_get_bgscan_state(void) +{ + struct bgscan_timer_data *timer_data = + __netconfig_wifi_bgscan_get_bgscan_data(); + + return ((timer_data->timer_id > (guint)0) ? TRUE : FALSE); +} + +gboolean netconfig_wifi_get_scanning(void) +{ + return netconfig_wifi_scanning; +} + +void netconfig_wifi_set_scanning(gboolean scanning) +{ + if (netconfig_wifi_scanning != scanning) + netconfig_wifi_scanning = scanning; +} + +gboolean netconfig_iface_wifi_set_bgscan(NetconfigWifi *wifi, guint scan_mode, GError **error) +{ + struct bgscan_timer_data *timer_data = __netconfig_wifi_bgscan_get_bgscan_data(); + + __netconfig_wifi_bgscan_set_mode(scan_mode); + + if (timer_data->timer_id != 0) + netconfig_wifi_bgscan_stop(); + + netconfig_wifi_bgscan_start(); + + return TRUE; +} diff --git a/src/wifi-eap-config.c b/src/wifi-eap-config.c new file mode 100644 index 0000000..1a47507 --- /dev/null +++ b/src/wifi-eap-config.c @@ -0,0 +1,216 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "wifi-eap-config.h" +#include "log.h" +#include "wifi.h" + +static char *__get_ssid(const char *name) +{ + char *buf = NULL; + char buf_tmp[32] = {0,}; + int i = 0; + int len = 0; + + if (NULL == name) + return NULL; + + len = strlen(name); + + buf = g_try_malloc0(len * 2 + 1); + if (buf == NULL) + return NULL; + + for (i = 0; i < len; i++) { + snprintf(buf_tmp, 3, "%02x", name[i]); + strcat(buf, buf_tmp); + } + + DBG("SSID - [%s]\n", buf); + + return buf; +} + +static gboolean __config_save(GKeyFile *keyfile, char *file_name) +{ + gchar *data = NULL; + gsize length = 0; + FILE *file = NULL; + int ret = TRUE; + + data = g_key_file_to_data(keyfile, &length, NULL); + DBG("Data lenght-[%d]", length); + + file = fopen(file_name, "w"); + if (NULL == file) { + DBG("fopen() fails!"); + ret = FALSE; + } else { + fputs(data, file); + fclose(file); + DBG("Wrote data successfully to [%s] file!", file_name); + } + + g_free(data); + + return ret; +} + +static gboolean __config_delete(const char *ssid) +{ + gchar *config_file = NULL; + gboolean ret = FALSE; + + config_file = g_strdup_printf("%s/%s.config", CONNMAN_STORAGEDIR, + ssid); + if(config_file == NULL) + return FALSE; + + if (g_file_test(config_file, G_FILE_TEST_EXISTS) == FALSE) { + ret = TRUE; + } else if (g_file_test(config_file, G_FILE_TEST_IS_REGULAR) == TRUE) { + unlink(config_file); + ret = TRUE; + } + + g_free(config_file); + + return ret; +} + +gboolean netconfig_iface_wifi_create_config(NetconfigWifi *wifi, + GHashTable *fields, GError **error) +{ + DBG("netconfig_iface_wifi_create_config"); + g_return_val_if_fail(wifi != NULL, FALSE); + + gboolean ret = TRUE; + GKeyFile *keyfile = NULL; + GHashTableIter iter; + gpointer field, value; + gchar *file_name = NULL; + gchar *ssid_hex = NULL; + gchar *grp_name = NULL; + + g_hash_table_iter_init(&iter, fields); + while (g_hash_table_iter_next(&iter, &field, &value)) { + if (NULL != value) { + if (!strcmp(field, CONNMAN_CONFIG_FIELD_NAME)) { + ssid_hex = __get_ssid(value); + break; + } else if (!strcmp(field, CONNMAN_CONFIG_FIELD_SSID)) { + ssid_hex = g_strdup_printf("%s", + (gchar *)value); + break; + } + } + } + + if (NULL == ssid_hex) { + DBG("Fail! Could not fetch the ssid"); + return FALSE; + } + + /* Create unique service group name */ + grp_name = g_strdup_printf("service_%s", ssid_hex); + if(NULL == grp_name) { + DBG("Fail! Could not create the service group name"); + g_free(ssid_hex); + return FALSE; + } + + keyfile = g_key_file_new(); + if (NULL == keyfile) { + DBG("g_key_file_new() fails!"); + g_free(grp_name); + g_free(ssid_hex); + return FALSE; + } + + g_hash_table_iter_init(&iter, fields); + while (g_hash_table_iter_next(&iter, &field, &value)) { + DBG("Field - [%s] Value - [%s]", field, value); + + if (NULL != value) + g_key_file_set_string(keyfile, grp_name, field, value); + } + + file_name = g_strdup_printf("%s/%s.config", CONNMAN_STORAGEDIR, + ssid_hex); + if(NULL == file_name) { + DBG("g_strdup_printf() fails. Could not save config!"); + g_key_file_free(keyfile); + g_free(grp_name); + g_free(ssid_hex); + return FALSE; + } + + ret = __config_save(keyfile, file_name); + if (FALSE == ret) + DBG("Could not save config!"); + else + DBG("Saved config in [%s] successfully", file_name); + + g_key_file_free(keyfile); + g_free(file_name); + g_free(grp_name); + g_free(ssid_hex); + + return ret; +} + +gboolean netconfig_iface_wifi_delete_config(NetconfigWifi *wifi, + gchar *profile, GError **error) +{ + DBG("netconfig_iface_wifi_delete_config"); + g_return_val_if_fail(wifi != NULL, FALSE); + + gboolean ret = TRUE; + char *str1 = NULL; + char *str2 = NULL; + char *str3 = NULL; + char ssid[512] = ""; + int ssid_len = 0; + + str1 = strstr(profile, "wifi_"); + if (NULL != str1) { + str2 = strchr(str1 + 5, '_'); + if (NULL != str2) { + str3 = strchr(str2 + 1, '_'); + ssid_len = str3 - str2 - 1; + strncpy(ssid, str2 + 1, ssid_len); + DBG("ssid_len - [%d] SSID - [%s]", ssid_len, ssid); + + ret = __config_delete(ssid); + if (TRUE == ret) + DBG("Deleted the config file successfully"); + else + DBG("Deletion of config file failed"); + } else { + DBG("Fetching of SSID fails"); + } + } else { + DBG("Fetching of SSID fails"); + } + + return ret; +} diff --git a/src/wifi-eap.c b/src/wifi-eap.c new file mode 100644 index 0000000..9e3a4de --- /dev/null +++ b/src/wifi-eap.c @@ -0,0 +1,471 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "util.h" +#include "netdbus.h" +#include "neterror.h" + +#define SIM_RAND_DATA_LEN 16 +#define SIM_AUTH_MAX_RESP_DATA_LEN 128 +#define SIM_AUTH_SRES_LEN 4 +#define SIM_AUTH_KC_LEN 8 + +#define AKA_RAND_DATA_LEN 16 +#define AKA_AUTN_DATA_LEN 16 +#define AKA_AUTH_RES_MAX_LEN 16 +#define AKA_AUTH_RES_MIN_LEN 4 +#define AKA_AUTH_CK_LEN 16 +#define AKA_AUTH_IK_LEN 16 + +struct wifii_authentication_data { + int auth_result; + int resp_length; + int authentication_key_length; + int cipher_length; + int integrity_length; + char *resp_data; + char *authentication_key; + char *cipher_data; + char *integrity_data; +}; + +TapiHandle *tapi_handle = NULL; +static struct wifii_authentication_data *wifi_authdata; + +static void *__netconfig_wifi_free_wifi_authdata(struct wifii_authentication_data *data) +{ + if (data) { + if (data->resp_data) + g_free(data->resp_data); + if (data->authentication_key) + g_free(data->authentication_key); + if (data->cipher_data) + g_free(data->cipher_data); + if (data->integrity_data) + g_free(data->integrity_data); + + g_free(data); + data = NULL; + } + + return NULL; +} + +static void __netconfig_tapi_init() +{ + tapi_handle = tel_init(NULL); +} + +static void __netconfig_tapi_deinit() +{ + tel_deinit(tapi_handle); + tapi_handle = NULL; + + wifi_authdata = __netconfig_wifi_free_wifi_authdata(wifi_authdata); +} + +static gboolean __netconfig_wifi_get_sim_imsi(DBusGMethodInvocation *context) +{ + DBG(" "); + + int ret; + GError *error = NULL; + TelSimImsiInfo_t imsi_info; + char *imsi; + + if (tapi_handle == NULL) + __netconfig_tapi_init(); + + ret = tel_get_sim_imsi(tapi_handle, &imsi_info); + if (ret != TAPI_API_SUCCESS) { + ERR("Failed tel_get_sim_imsi() : [%d]", ret); + netconfig_error_fail_get_imsi(&error); + dbus_g_method_return_error(context, error); + return FALSE; + } + + imsi = g_strdup_printf("%s%s%s", imsi_info.szMcc, imsi_info.szMnc, imsi_info.szMsin); + + dbus_g_method_return(context, imsi); + g_free(imsi); + + return TRUE; +} + +void __netconfig_response_sim_authentication(TapiHandle *handle, int result, void *data, void *user_data) +{ + DBG(" "); + + if (wifi_authdata != NULL) + wifi_authdata = __netconfig_wifi_free_wifi_authdata(wifi_authdata); + + wifi_authdata = g_try_new0(struct wifii_authentication_data, 1); + + TelSimAuthenticationResponse_t *auth_resp = (TelSimAuthenticationResponse_t *) data; + if (auth_resp == NULL) { + ERR("the auth response is NULL"); + wifi_authdata->auth_result = -1; + return; + } else { + wifi_authdata->auth_result = auth_resp->auth_result; + } + + if (auth_resp->auth_result == TAPI_SIM_AUTH_NO_ERROR) { + wifi_authdata->resp_length = auth_resp->resp_length; + wifi_authdata->authentication_key_length = auth_resp->authentication_key_length; + + if (wifi_authdata->resp_data != NULL) + g_free(wifi_authdata->resp_data); + wifi_authdata->resp_data = g_strdup(auth_resp->resp_data); + + if (wifi_authdata->authentication_key != NULL) + g_free(wifi_authdata->authentication_key); + wifi_authdata->authentication_key = g_strdup(auth_resp->authentication_key); + } else { + ERR("the result error for sim auth : [%d]", auth_resp->auth_result); + wifi_authdata->resp_length = 0; + wifi_authdata->authentication_key_length = 0; + } +} + +void __netconfig_response_aka_authentication(TapiHandle *handle, int result, void *data, void *user_data) +{ + DBG(" "); + + if (wifi_authdata != NULL) + wifi_authdata = __netconfig_wifi_free_wifi_authdata(wifi_authdata); + + wifi_authdata = g_try_new0(struct wifii_authentication_data, 1); + + TelSimAuthenticationResponse_t *auth_resp = (TelSimAuthenticationResponse_t *) data; + if (auth_resp == NULL) { + ERR("the auth response is NULL"); + wifi_authdata->auth_result = -1; + return; + } else { + wifi_authdata->auth_result = auth_resp->auth_result; + } + + if (auth_resp->auth_result == TAPI_SIM_AUTH_NO_ERROR) { + wifi_authdata->resp_length = auth_resp->resp_length; + wifi_authdata->cipher_length = auth_resp->cipher_length; + wifi_authdata->integrity_length = auth_resp->integrity_length; + + if (wifi_authdata->resp_data != NULL) + g_free(wifi_authdata->resp_data); + wifi_authdata->resp_data = g_strdup(auth_resp->resp_data); + + if (wifi_authdata->cipher_data != NULL) + g_free(wifi_authdata->cipher_data); + wifi_authdata->cipher_data = g_strdup(auth_resp->cipher_data); + + if (wifi_authdata->integrity_data != NULL) + g_free(wifi_authdata->integrity_data); + wifi_authdata->integrity_data = g_strdup(auth_resp->integrity_data); + } else { + ERR("the result error for aka auth : [%d]", auth_resp->auth_result); + if (auth_resp->auth_result == TAPI_SIM_AUTH_SQN_FAILURE || + auth_resp->auth_result == TAPI_SIM_AUTH_SYNCH_FAILURE) { + wifi_authdata->resp_length = auth_resp->resp_length; + + if (wifi_authdata->resp_data != NULL) + g_free(wifi_authdata->resp_data); + wifi_authdata->resp_data = g_strdup(auth_resp->resp_data); + } + } +} + +static gboolean __netconfig_wifi_req_sim_auth(GArray *rand_data, GError **error) +{ + DBG(" "); + + int i; + int ret; + TelSimAuthenticationData_t auth_data; + + if (rand_data->len != SIM_RAND_DATA_LEN) { + ERR("wrong rand data len : [%d]", rand_data->len); + netconfig_error_fail_req_sim_auth_wrong_param(error); + return FALSE; + } + + if ((ret = g_array_get_element_size(rand_data)) != 1) { + ERR("wrong rand data size : [%d]", ret); + netconfig_error_fail_req_sim_auth_wrong_param(error); + return FALSE; + } + + memset(&auth_data, 0, sizeof(auth_data)); + auth_data.auth_type = TAPI_SIM_AUTH_TYPE_GSM; + auth_data.rand_length = SIM_RAND_DATA_LEN; + for (i=0; ilen; i++) + auth_data.rand_data[i] = g_array_index(rand_data, guint8, i); + + if (tapi_handle == NULL) + __netconfig_tapi_init(); + + ret = tel_req_sim_authentication(tapi_handle, &auth_data, __netconfig_response_sim_authentication, NULL); + if (ret != TAPI_API_SUCCESS) { + ERR("Failed tel_req_sim_authentication() : [%d]", ret); + netconfig_error_fail_req_sim_auth(error); + return FALSE; + } + + return TRUE; +} + +static gboolean __netconfig_wifi_req_aka_auth(GArray *rand_data, GArray *autn_data, GError **error) +{ + DBG(" "); + + int i; + int ret; + TelSimAuthenticationData_t auth_data; + + if (rand_data->len != AKA_RAND_DATA_LEN) { + ERR("wrong rand data len : [%d]", rand_data->len); + netconfig_error_fail_req_sim_auth_wrong_param(error); + return FALSE; + } + + if (autn_data->len != AKA_AUTN_DATA_LEN) { + ERR("wrong autn data len : [%d]", autn_data->len); + netconfig_error_fail_req_sim_auth_wrong_param(error); + return FALSE; + } + + if ((ret = g_array_get_element_size(rand_data)) != 1) { + ERR("wrong rand data size : [%d]", ret); + netconfig_error_fail_req_sim_auth_wrong_param(error); + return FALSE; + } + + if ((ret = g_array_get_element_size(autn_data)) != 1) { + ERR("wrong autn data size : [%d]", ret); + netconfig_error_fail_req_sim_auth_wrong_param(error); + return FALSE; + } + + memset(&auth_data, 0, sizeof(auth_data)); + auth_data.auth_type = TAPI_SIM_AUTH_TYPE_3G; + auth_data.rand_length = AKA_RAND_DATA_LEN; + auth_data.autn_length = AKA_AUTN_DATA_LEN; + for (i=0; ilen; i++) + auth_data.rand_data[i] = g_array_index(rand_data, guint8, i); + for (i=0; ilen; i++) + auth_data.autn_data[i] = g_array_index(autn_data, guint8, i); + + if (tapi_handle == NULL) + __netconfig_tapi_init(); + + ret = tel_req_sim_authentication(tapi_handle, &auth_data, __netconfig_response_aka_authentication, NULL); + if (ret != TAPI_API_SUCCESS) { + ERR("Failed tel_req_sim_authentication() : [%d]", ret); + netconfig_error_fail_req_sim_auth(error); + return FALSE; + } + + return TRUE; +} + +static gboolean __netconfig_wifi_get_sim_authdata(DBusGMethodInvocation *context) +{ + DBG(" "); + + GArray *array = NULL; + GError *error = NULL; + + if (wifi_authdata == NULL) { + DBG("the status error : no response yet"); + netconfig_error_fail_get_sim_auth_delay(&error); + dbus_g_method_return_error(context, error); + return FALSE; + } + + if (wifi_authdata->auth_result == TAPI_SIM_AUTH_NO_ERROR) { + if (wifi_authdata->resp_length == SIM_AUTH_SRES_LEN && + wifi_authdata->authentication_key_length == SIM_AUTH_KC_LEN) { + array = g_array_sized_new(FALSE, FALSE, sizeof(guchar), SIM_AUTH_SRES_LEN+SIM_AUTH_KC_LEN); + g_array_append_vals(array, wifi_authdata->resp_data, SIM_AUTH_SRES_LEN); + g_array_append_vals(array, wifi_authdata->authentication_key, SIM_AUTH_KC_LEN); + dbus_g_method_return(context, array); + g_array_free (array, TRUE); + } else { + ERR("auth data length is wrong, SRES = [%d], Kc = [%d]", + wifi_authdata->resp_length, wifi_authdata->authentication_key_length); + + netconfig_error_fail_get_sim_auth_wrong_data(&error); + dbus_g_method_return_error(context, error); + __netconfig_tapi_deinit(); + return FALSE; + } + } else { + ERR("failed auth result = [%d]", wifi_authdata->auth_result); + netconfig_error_fail_get_sim_auth_wrong_data(&error); + dbus_g_method_return_error(context, error); + __netconfig_tapi_deinit(); + return FALSE; + } + + __netconfig_tapi_deinit(); + return TRUE; +} + +static gboolean __netconfig_wifi_get_aka_authdata(DBusGMethodInvocation *context) +{ + DBG(" "); + + GArray *array = NULL; + GError *error = NULL; + guchar res_len; + + if (wifi_authdata == NULL) { + DBG("the status error : no response yet"); + netconfig_error_fail_get_sim_auth_delay(&error); + dbus_g_method_return_error(context, error); + return FALSE; + } + + switch (wifi_authdata->auth_result) { + case TAPI_SIM_AUTH_NO_ERROR: + break; + + case TAPI_SIM_AUTH_SQN_FAILURE: + case TAPI_SIM_AUTH_SYNCH_FAILURE: + array = g_array_sized_new(FALSE, FALSE, sizeof(guchar), wifi_authdata->resp_length+1); + res_len = (guchar)((wifi_authdata->resp_length-1) & 0xff); + + g_array_append_vals(array, &res_len, 1); + g_array_append_vals(array, wifi_authdata->resp_data, wifi_authdata->resp_length); + + dbus_g_method_return(context, array); + g_array_free (array, TRUE); + + g_free(wifi_authdata->resp_data); + g_free(wifi_authdata); + wifi_authdata = NULL; + + return TRUE; + + default: + netconfig_error_fail_get_sim_auth_wrong_data(&error); + dbus_g_method_return_error(context, error); + __netconfig_tapi_deinit(); + return FALSE; + } + + if ((wifi_authdata->resp_length >= AKA_AUTH_RES_MIN_LEN || + wifi_authdata->resp_length <= AKA_AUTH_RES_MAX_LEN) && + wifi_authdata->cipher_length == AKA_AUTH_CK_LEN && + wifi_authdata->integrity_length == AKA_AUTH_IK_LEN) { + array = g_array_sized_new(FALSE, FALSE, sizeof(guchar), wifi_authdata->resp_length+AKA_AUTH_CK_LEN+AKA_AUTH_IK_LEN+1); + + res_len = (guchar)((wifi_authdata->resp_length-1) & 0xff); + g_array_append_vals(array, &res_len, 1); + g_array_append_vals(array, wifi_authdata->resp_data, wifi_authdata->resp_length); + g_array_append_vals(array, wifi_authdata->cipher_data, AKA_AUTH_CK_LEN); + g_array_append_vals(array, wifi_authdata->integrity_data, AKA_AUTH_IK_LEN); + + dbus_g_method_return(context, array); + g_array_free (array, TRUE); + } else { + ERR("auth data length is wrong, res = [%d], Kc = [%d], Ki = [%d]", + wifi_authdata->resp_length, wifi_authdata->cipher_length, wifi_authdata->integrity_length); + + netconfig_error_fail_get_sim_auth_wrong_data(&error); + dbus_g_method_return_error(context, error); + __netconfig_tapi_deinit(); + return FALSE; + } + + __netconfig_tapi_deinit(); + return TRUE; +} + +gboolean netconfig_iface_wifi_get_sim_imsi(NetconfigWifi *wifi, DBusGMethodInvocation *context) +{ + gboolean ret = TRUE; + + DBG("Get sim Imsi"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + ret = __netconfig_wifi_get_sim_imsi(context); + + return ret; +} + +gboolean netconfig_iface_wifi_req_sim_auth(NetconfigWifi *wifi, GArray *rand_data, gboolean *result, GError **error) +{ + gboolean ret = TRUE; + + DBG("Req sim Authentication"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + ret = __netconfig_wifi_req_sim_auth(rand_data, error); + + *result = ret; + return ret; +} + +gboolean netconfig_iface_wifi_req_aka_auth(NetconfigWifi *wifi, GArray *rand_data, GArray *autn_data, gboolean *result, GError **error) +{ + gboolean ret = TRUE; + + DBG("Req aka Authentication"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + ret = __netconfig_wifi_req_aka_auth(rand_data, autn_data, error); + + *result = ret; + return ret; +} + +gboolean netconfig_iface_wifi_get_sim_auth(NetconfigWifi *wifi, DBusGMethodInvocation *context) +{ + gboolean ret = TRUE; + + DBG("Get sim Authdata"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + ret = __netconfig_wifi_get_sim_authdata(context); + + return ret; +} + +gboolean netconfig_iface_wifi_get_aka_auth(NetconfigWifi *wifi, DBusGMethodInvocation *context) +{ + gboolean ret = TRUE; + + DBG("Get aka Authdata"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + ret = __netconfig_wifi_get_aka_authdata(context); + + return ret; +} diff --git a/src/wifi-indicator.c b/src/wifi-indicator.c new file mode 100644 index 0000000..5d7d03a --- /dev/null +++ b/src/wifi-indicator.c @@ -0,0 +1,255 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "util.h" +#include "netdbus.h" +#include "netsupplicant.h" +#include "wifi-indicator.h" + +#define VCONFKEY_WIFI_SNR_MIN -89 + +#define NETCONFIG_WIFI_INDICATOR_INTERVAL 3 + +static guint netconfig_wifi_indicator_timer = 0; + +#if defined NL80211 +static int __netconfig_wifi_get_signal(const char *object_path) +{ + DBusConnection *connection = NULL; + DBusMessage *message = NULL; + DBusMessageIter iter; + int rssi_dbm = 0; + int MessageType = 0; + + if (object_path == NULL) { + ERR("Error!!! path is NULL"); + goto error; + } + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) { + ERR("Error!!! Failed to get system DBus"); + goto error; + } + + message = netconfig_supplicant_invoke_dbus_method( + SUPPLICANT_SERVICE, connection, object_path, + SUPPLICANT_INTERFACE ".Interface", "GetLinkSignal", + NULL); + + if (message == NULL) { + ERR("Error!!! Failed to get service properties"); + goto error; + } + + MessageType = dbus_message_get_type(message); + + if (MessageType == DBUS_MESSAGE_TYPE_ERROR) { + const char *err_msg = dbus_message_get_error_name(message); + ERR("Error!!! Error message received [%s]", err_msg); + goto error; + } + + dbus_message_iter_init(message, &iter); + + if ((MessageType = dbus_message_iter_get_arg_type(&iter)) == DBUS_TYPE_INT32) + dbus_message_iter_get_basic(&iter, &rssi_dbm); + else + goto error; + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return rssi_dbm; + +error: + if (message != NULL) + dbus_message_unref(message); + + if (connection != NULL) + dbus_connection_unref(connection); + + return VCONFKEY_WIFI_SNR_MIN; +} + +static int __netconfig_wifi_get_rssi_from_supplicant(void) +{ + int rssi_dbm =0; + + char object_path[DBUS_PATH_MAX_BUFLEN] = { 0, }; + char *path_ptr = &object_path[0]; + + if (netconfig_wifi_get_supplicant_interface(&path_ptr) != TRUE) { + DBG("Fail to get wpa_supplicant DBus path"); + return VCONFKEY_WIFI_SNR_MIN; + } + + rssi_dbm = __netconfig_wifi_get_signal((const char *)path_ptr); + + return rssi_dbm; +} +#endif /* #if defined NL80211 */ + +#if !defined NL80211 +static int __netconfig_wifi_get_rssi_from_system(void) +{ + int rssi_dbm = 0; + char ifname[16] = { 0, }; + char *ifname_ptr = &ifname[0]; + + int fd = -1; + struct iwreq wifi_req; + struct iw_statistics stats; + unsigned int iw_stats_len = sizeof(struct iw_statistics); + + if (netconfig_wifi_get_ifname(&ifname_ptr) != TRUE) { + DBG("Fail to get Wi-Fi ifname from wpa_supplicant: %s", ifname_ptr); + return VCONFKEY_WIFI_SNR_MIN; + } + + /* Set device name */ + memset(wifi_req.ifr_name, 0, sizeof(wifi_req.ifr_name)); + strncpy(wifi_req.ifr_name, ifname, sizeof(wifi_req.ifr_name) - 1); + wifi_req.ifr_name[sizeof(wifi_req.ifr_name) - 1] = '\0'; + + wifi_req.u.data.pointer = (caddr_t) &stats; + wifi_req.u.data.length = iw_stats_len; + wifi_req.u.data.flags = 1; /* Clear updated flag */ + + if ((fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) { + DBG("Fail to open socket to get rssi"); + return VCONFKEY_WIFI_SNR_MIN; + } + + memset(&stats, 0, iw_stats_len); + + if (ioctl(fd, SIOCGIWSTATS, &wifi_req) < 0) { + DBG("Fail to execute ioctl for SIOCGIWSTATS"); + close(fd); + + return VCONFKEY_WIFI_SNR_MIN; + } + close(fd); + + rssi_dbm = stats.qual.level - 255; /** signed integer, so 255 */ + + return rssi_dbm; +} +#endif /* #if !defined NL80211 */ + +int netconfig_wifi_get_rssi(void) +{ + int rssi_dbm = 0; + + /* There are two ways to get Wi-Fi RSSI: + * - WEXT interface, get DBus path of wpa_supplicant, + * and get Wi-Fi interface name e.g. wlan0 from wpa_supplicant. + * IOCTL with ifname will return RSSI dB. + * - NL80211 interface, get DBus path of wpa_supplicant, + * and get RSSI from wpa_supplicant directly. + * However, in this case wpa_supplicant needs some modification + * to get RSSI from DBus interface. */ + +#if defined NL80211 + rssi_dbm = __netconfig_wifi_get_rssi_from_supplicant(); +#else + rssi_dbm = __netconfig_wifi_get_rssi_from_system(); +#endif + + return rssi_dbm; +} + +static void __netconfig_wifi_set_rssi_level(int rssi_dbm) +{ + int snr_level = 0; + static int last_snr_level = 0; + + /* Wi-Fi Signal Strength Display + * + * Excellent : -63 ~ + * Good: -74 ~ -64 + * Weak: -82 ~ -75 + * Very weak: ~ -83 + */ + if (rssi_dbm >= -63) + snr_level = 4; + else if (rssi_dbm >= -74) + snr_level = 3; + else if (rssi_dbm >= -82) + snr_level = 2; + else + snr_level = 1; + + if (snr_level != last_snr_level) { + INFO("Wi-Fi RSSI: %d dB, %d level", rssi_dbm, snr_level); + + vconf_set_int(VCONFKEY_WIFI_STRENGTH, snr_level); + + last_snr_level = snr_level; + } +} + +static gboolean __netconfig_wifi_indicator_monitor(gpointer data) +{ + int rssi_dbm = 0; + int pm_state = VCONFKEY_PM_STATE_NORMAL; + + /* In case of LCD off, we don't need to update Wi-Fi indicator */ + vconf_get_int(VCONFKEY_PM_STATE, &pm_state); + if (pm_state >= VCONFKEY_PM_STATE_LCDOFF) + return TRUE; + + rssi_dbm = netconfig_wifi_get_rssi(); + + __netconfig_wifi_set_rssi_level(rssi_dbm); + + return TRUE; +} + +void netconfig_wifi_indicator_start(void) +{ + INFO("Start Wi-Fi indicator"); + + vconf_set_int(VCONFKEY_WIFI_STRENGTH, VCONFKEY_WIFI_STRENGTH_MAX); + + netconfig_start_timer_seconds( + NETCONFIG_WIFI_INDICATOR_INTERVAL, + __netconfig_wifi_indicator_monitor, + NULL, + &netconfig_wifi_indicator_timer); +} + +void netconfig_wifi_indicator_stop(void) +{ + INFO("Stop Wi-Fi indicator"); + + vconf_set_int(VCONFKEY_WIFI_STRENGTH, VCONFKEY_WIFI_STRENGTH_MAX); + + netconfig_stop_timer(&netconfig_wifi_indicator_timer); +} diff --git a/src/wifi-power.c b/src/wifi-power.c new file mode 100644 index 0000000..7017793 --- /dev/null +++ b/src/wifi-power.c @@ -0,0 +1,379 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "wifi.h" +#include "log.h" +#include "wifi.h" +#include "util.h" +#include "netdbus.h" +#include "neterror.h" +#include "netconfig.h" +#include "emulator.h" +#include "network-statistics.h" +#include "wifi-background-scan.h" +#include "wifi-power.h" +#include "wifi-state.h" +#include "mdm-private.h" +#include "wifi-agent.h" +#include "wifi-eap-config.h" + + +#define WLAN_DRIVER_SCRIPT "/usr/bin/wlan.sh" + + +static gboolean __netconfig_wifi_enable_technology(void) +{ + DBusMessage *reply = NULL; + char param1[] = "string:Powered"; + char param2[] = "variant:boolean:true"; + char *param_array[] = {NULL, NULL, NULL}; + + param_array[0] = param1; + param_array[1] = param2; + + reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE, CONNMAN_WIFI_TECHNOLOGY_PREFIX, + CONNMAN_TECHNOLOGY_INTERFACE, "SetProperty", param_array); + + if (reply == NULL) { + ERR("Error! Request failed"); + return FALSE; + } + + dbus_message_unref(reply); + + return TRUE; +} + +static gboolean __netconfig_wifi_disable_technology(void) +{ + DBusMessage *reply = NULL; + char param1[] = "string:Powered"; + char param2[] = "variant:boolean:false"; + char *param_array[] = {NULL, NULL, NULL}; + + param_array[0] = param1; + param_array[1] = param2; + + reply = netconfig_invoke_dbus_method(CONNMAN_SERVICE, CONNMAN_WIFI_TECHNOLOGY_PREFIX, + CONNMAN_TECHNOLOGY_INTERFACE, "SetProperty", param_array); + + if (reply == NULL) { + ERR("Error! Request failed"); + return FALSE; + } + + dbus_message_unref(reply); + + return TRUE; +} + +static gboolean __netconfig_wifi_load_driver(void) +{ + gboolean rv = FALSE; + const char *path = WLAN_DRIVER_SCRIPT; + char *const args[] = { "wlan.sh", "start", NULL }; + char *const envs[] = { NULL }; + + if (netconfig_emulator_is_emulated() == TRUE) + return rv; + + rv = netconfig_execute_file(path, args, envs); + if (rv != TRUE) { + DBG("Failed to load wireless device driver"); + return FALSE; + } + + DBG("Successfully loaded wireless device driver"); + return TRUE; +} + +gboolean netconfig_wifi_remove_driver(void) +{ + gboolean rv = FALSE; + const char *path = WLAN_DRIVER_SCRIPT; + char *const args[] = { "wlan.sh", "stop", NULL }; + char *const env[] = { NULL }; + + if (netconfig_emulator_is_emulated() == TRUE) + return rv; + + rv = netconfig_execute_file(path, args, env); + if (rv != TRUE) { + DBG("Failed to remove wireless device driver"); + return FALSE; + } + + DBG("Successfully removed wireless device driver"); + return TRUE; +} + +static int __netconfig_wifi_try_to_load_driver(void); +static gboolean __netconfig_wifi_try_to_remove_driver(void); + +void netconfig_wifi_notify_power_completed(gboolean power_on) +{ + DBusMessage *signal; + DBusConnection *connection; + DBusError error; + char *sig_name; + + if (power_on) + sig_name = "PowerOnCompleted"; + else + sig_name = "PowerOffCompleted"; + + dbus_error_init(&error); + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + ERR("Error!!! Failed to get system DBus, error [%s]", error.message); + dbus_error_free(&error); + return; + } + + signal = dbus_message_new_signal(NETCONFIG_WIFI_PATH, + NETCONFIG_WIFI_INTERFACE, sig_name); + if (signal == NULL) + return; + + dbus_connection_send(connection, signal, NULL); + + dbus_message_unref(signal); + dbus_connection_unref(connection); + + INFO("(%s)", sig_name); +} + +static void __netconfig_wifi_direct_state_cb(int error_code, + wifi_direct_device_state_e device_state, void *user_data) +{ + wifi_direct_unset_device_state_changed_cb(); + wifi_direct_deinitialize(); + + if (device_state == WIFI_DIRECT_DEVICE_STATE_DEACTIVATED) { + if (__netconfig_wifi_try_to_load_driver() < 0) { + + /* TODO: error report */ + + return; + } + + netconfig_wifi_notify_power_completed(TRUE); + } +} + +static gboolean __netconfig_wifi_direct_power_off(void) +{ + DBG("Wi-Fi direct is turning off"); + + if (wifi_direct_initialize() < 0) + return FALSE; + + if (wifi_direct_set_device_state_changed_cb( + __netconfig_wifi_direct_state_cb, NULL) < 0) + return FALSE; + + if (wifi_direct_deactivate() < 0) + return FALSE; + + return TRUE; +} + +static int __netconfig_wifi_try_to_load_driver(void) +{ + if (netconfig_is_wifi_allowed() != TRUE) + return -EPERM; + + if (netconfig_is_wifi_tethering_on() == TRUE) { + /* TODO: Wi-Fi tethering turns off here */ + /* return TRUE; */ + return -EBUSY; + } + + if (netconfig_is_wifi_direct_on() == TRUE) { + if (__netconfig_wifi_direct_power_off() == TRUE) + return -EINPROGRESS; + else + return -EBUSY; + } + + if (__netconfig_wifi_load_driver() != TRUE) { + netconfig_wifi_remove_driver(); + + return -EIO; + } + + __netconfig_wifi_enable_technology(); + + return 0; +} + +static gboolean __netconfig_wifi_try_to_remove_driver(void) +{ + netconfig_wifi_device_picker_service_stop(); + + netconfig_wifi_statistics_update_powered_off(); + + __netconfig_wifi_disable_technology(); + + return TRUE; +} + +static void __netconfig_wifi_airplane_mode(keynode_t* node, + void* user_data) +{ + int value = 0; + int wifi_state = 0; + static gboolean powered_off_by_flightmode = FALSE; + + vconf_get_bool(VCONFKEY_TELEPHONY_FLIGHT_MODE, &value); + vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); + + DBG("flight mode %s", value > 0 ? "ON" : "OFF"); + DBG("Wi-Fi state %d, Wi-Fi was off by flight mode %s", + wifi_state, powered_off_by_flightmode == TRUE ? "Yes" : "No"); + + if (value > 0) { + /* flight mode enabled */ + if (wifi_state == VCONFKEY_WIFI_OFF) + return; + + DBG("Turning Wi-Fi off"); + + __netconfig_wifi_try_to_remove_driver(); + + powered_off_by_flightmode = TRUE; + } else if (value == 0) { + /* flight mode disabled */ + if (wifi_state > VCONFKEY_WIFI_OFF) + return; + + if (powered_off_by_flightmode != TRUE) + return; + + __netconfig_wifi_try_to_load_driver(); + + powered_off_by_flightmode = FALSE; + } else + DBG("Invalid value (%d)", value); +} + +static void __netconfig_wifi_pm_state_mode(keynode_t* node, + void* user_data) +{ + int value = -1; + int wifi_state = 0; + static int prev_state = VCONFKEY_PM_STATE_NORMAL; + + /*** vconf-keys.h *** + * VCONFKEY_PM_STATE_NORMAL = 1, + * VCONFKEY_PM_STATE_LCDDIM, + * VCONFKEY_PM_STATE_LCDOFF, + * VCONFKEY_PM_STATE_SLEEP + */ + + if(vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state) == 0) { + DBG("wifi state : %d (0 off / 1 on / 2 connected)", wifi_state); + if(wifi_state <= VCONFKEY_WIFI_OFF) + return; + } + + if(vconf_get_int(VCONFKEY_PM_STATE, &value) < 0) { + ERR("VCONFKEY_PM_STATE get failed"); + return; + } + + DBG("Old state: %d, current: %d", prev_state, value); + + if((value == VCONFKEY_PM_STATE_NORMAL) && (prev_state >= VCONFKEY_PM_STATE_LCDOFF)) { + DBG("PM state : Wake UP!"); + + netconfig_wifi_bgscan_stop(); + netconfig_wifi_bgscan_start(); + } + + prev_state = value; +} + +void netconfig_wifi_power_configuration(void) +{ + int wifi_last_power_state = 0; + + vconf_notify_key_changed(VCONFKEY_TELEPHONY_FLIGHT_MODE, + __netconfig_wifi_airplane_mode, NULL); + + vconf_notify_key_changed(VCONFKEY_PM_STATE, + __netconfig_wifi_pm_state_mode, NULL); + + vconf_get_int(VCONF_WIFI_LAST_POWER_STATE, &wifi_last_power_state); + + if (wifi_last_power_state == WIFI_POWER_ON) { + DBG("Turn Wi-Fi on automatically"); + + __netconfig_wifi_try_to_load_driver(); + } +} + +gboolean netconfig_iface_wifi_load_driver(NetconfigWifi *wifi, GError **error) +{ + DBG("Wi-Fi power on requested"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + int err; + + if (netconfig_is_wifi_allowed() != TRUE) { + netconfig_error_security_restricted(error); + + return FALSE; + } + + err = __netconfig_wifi_try_to_load_driver(); + if (err < 0) { + if (err == -EINPROGRESS) + netconfig_error_wifi_load_inprogress(error); + else + netconfig_error_wifi_driver_failed(error); + + return FALSE; + } + + return TRUE; +} + +gboolean netconfig_iface_wifi_remove_driver(NetconfigWifi *wifi, GError **error) +{ + DBG("Wi-Fi power off requested"); + + g_return_val_if_fail(wifi != NULL, FALSE); + + if (__netconfig_wifi_try_to_remove_driver() != TRUE) { + netconfig_error_wifi_driver_failed(error); + + return FALSE; + } + + return TRUE; +} diff --git a/src/wifi-ssid-scan.c b/src/wifi-ssid-scan.c new file mode 100644 index 0000000..3f49101 --- /dev/null +++ b/src/wifi-ssid-scan.c @@ -0,0 +1,496 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "util.h" +#include "neterror.h" +#include "netdbus.h" +#include "netsupplicant.h" +#include "wifi-ssid-scan.h" +#include "wifi-background-scan.h" + +struct bss_info_t { + unsigned char ssid[32]; + enum netconfig_wifi_security security; + dbus_bool_t privacy; + dbus_bool_t wps; +}; + +static gboolean wifi_ssid_scan_state = FALSE; +static GSList *wifi_bss_info_list = NULL; +static guint netconfig_wifi_ssid_scan_timer = 0; + +static gboolean __netconfig_wifi_ssid_scan_timeout(gpointer data) +{ + netconfig_wifi_notify_ssid_scan_done(); + + return FALSE; +} + +static void __netconfig_wifi_ssid_scan_started(void) +{ + INFO("Wi-Fi SSID scan started"); + wifi_ssid_scan_state = TRUE; + + netconfig_start_timer_seconds( + 5, + __netconfig_wifi_ssid_scan_timeout, + NULL, + &netconfig_wifi_ssid_scan_timer); +} + +static void __netconfig_wifi_ssid_scan_finished(void) +{ + INFO("Wi-Fi SSID scan finished"); + wifi_ssid_scan_state = FALSE; + + netconfig_stop_timer(&netconfig_wifi_ssid_scan_timer); +} + +static gboolean __netconfig_wifi_invoke_ssid_scan( + const char *object_path, const char *ssid) +{ + /* TODO: Revise following code */ + +#define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000) + + DBusConnection *connection = NULL; + DBusMessage *message = NULL; + DBusMessage *reply = NULL; + DBusMessageIter iter, dict, entry; + DBusMessageIter value, array, array2; + DBusError error; + int MessageType = 0; + const char *key1 = "Type"; + const char *val1 = "active"; + const char *key2 = "SSIDs"; + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) { + ERR("Error!!! Failed to get system DBus"); + goto error; + } + + message = dbus_message_new_method_call(SUPPLICANT_SERVICE, + object_path, SUPPLICANT_INTERFACE ".Interface", "Scan"); + if (message == NULL) { + ERR("Error!!! DBus method call fail"); + goto error; + } + + dbus_message_iter_init_append(message, &iter); + dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, + DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING + DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING + DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); + + dbus_message_iter_open_container(&dict, + DBUS_TYPE_DICT_ENTRY, NULL, &entry); + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key1); + + dbus_message_iter_open_container(&entry, + DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &value); + dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &val1); + + dbus_message_iter_close_container(&entry, &value); + dbus_message_iter_close_container(&dict, &entry); + + dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, NULL, &entry); + dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key2); + + dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT, + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_BYTE_AS_STRING, + &value); + dbus_message_iter_open_container(&value, DBUS_TYPE_ARRAY, + DBUS_TYPE_ARRAY_AS_STRING + DBUS_TYPE_BYTE_AS_STRING, + &array); + dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE_AS_STRING, &array2); + + dbus_message_iter_append_fixed_array(&array2, DBUS_TYPE_BYTE, &ssid, strlen(ssid)); + + dbus_message_iter_close_container(&array, &array2); + dbus_message_iter_close_container(&value, &array); + dbus_message_iter_close_container(&entry, &value); + dbus_message_iter_close_container(&dict, &entry); + dbus_message_iter_close_container(&iter, &dict); + + dbus_error_init(&error); + + reply = dbus_connection_send_with_reply_and_block(connection, message, + NETCONFIG_DBUS_REPLY_TIMEOUT, &error); + + if (reply == NULL) { + if (dbus_error_is_set(&error) == TRUE) { + ERR("Error!!! dbus_connection_send_with_reply_and_block() failed. " + "DBus error [%s: %s]", error.name, error.message); + + dbus_error_free(&error); + return FALSE; + } else + ERR("Error!!! Failed to get properties"); + + goto error; + } + + MessageType = dbus_message_get_type(reply); + if (MessageType == DBUS_MESSAGE_TYPE_ERROR) { + const char *err_msg = dbus_message_get_error_name(reply); + ERR("Error!!! Error message received %s", err_msg); + goto error; + } + + dbus_message_unref(message); + dbus_message_unref(reply); + dbus_connection_unref(connection); + + return TRUE; + +error: + if (message != NULL) + dbus_message_unref(message); + + if (reply != NULL) + dbus_message_unref(reply); + + if (connection != NULL) + dbus_connection_unref(connection); + + return FALSE; +} + +static void __netconfig_wifi_notify_ssid_scan_done(void) +{ + DBusMessage *signal; + DBusConnection *connection = NULL; + DBusMessageIter dict, type, array, value; + DBusError error; + char *prop_ssid = "ssid"; + char *prop_security = "security"; + const char *sig_name = "SpecificScanCompleted"; + + dbus_error_init(&error); + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, &error); + if (connection == NULL) { + /* TODO: If this occurs then UG should be informed abt SCAN fail. CHECK THIS. */ + ERR("Error!!! Failed to get system DBus, error [%s]", error.message); + dbus_error_free(&error); + + g_slist_free_full(wifi_bss_info_list, g_free); + wifi_bss_info_list = NULL; + + return; + } + + signal = dbus_message_new_signal(NETCONFIG_WIFI_PATH, NETCONFIG_WIFI_INTERFACE, sig_name); + if (signal == NULL) { + /* TODO: If this occurs then UG should be informed abt SCAN fail. CHECK THIS. */ + dbus_connection_unref(connection); + + g_slist_free_full(wifi_bss_info_list, g_free); + wifi_bss_info_list = NULL; + + return; + } + + dbus_message_iter_init_append(signal, &array); + dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY, "{sv}", &dict); + GSList* list = wifi_bss_info_list; + while (list) { + struct bss_info_t *bss_info = (struct bss_info_t *)g_slist_nth_data(list, 0); + + if (bss_info) { + char *ssid = (char *)&(bss_info->ssid[0]); + dbus_int16_t security = bss_info->security; + DBG("Bss found. SSID: %s; Sec mode: %d;", ssid, security); + + /* Lets pack the SSID */ + dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, 0, &type); + dbus_message_iter_append_basic(&type, DBUS_TYPE_STRING, &prop_ssid); + dbus_message_iter_open_container(&type, DBUS_TYPE_VARIANT, DBUS_TYPE_STRING_AS_STRING, &value); + + dbus_message_iter_append_basic(&value, DBUS_TYPE_STRING, &ssid); + dbus_message_iter_close_container(&type, &value); + dbus_message_iter_close_container(&dict, &type); + + /* Lets pack the Security */ + dbus_message_iter_open_container(&dict, DBUS_TYPE_DICT_ENTRY, 0, &type); + dbus_message_iter_append_basic(&type, DBUS_TYPE_STRING, &prop_security); + dbus_message_iter_open_container(&type, DBUS_TYPE_VARIANT, DBUS_TYPE_INT16_AS_STRING, &value); + + dbus_message_iter_append_basic(&value, DBUS_TYPE_INT16, &security); + dbus_message_iter_close_container(&type, &value); + dbus_message_iter_close_container(&dict, &type); + } + list = g_slist_next(list); + } + + dbus_message_iter_close_container(&array, &dict); + + dbus_error_init(&error); + dbus_connection_send(connection, signal, NULL); + + dbus_message_unref(signal); + dbus_connection_unref(connection); + + g_slist_free_full(wifi_bss_info_list, g_free); + wifi_bss_info_list = NULL; + + INFO("(%s)", sig_name); +} + +static void __netconfig_wifi_check_security(const char *str_keymgmt, struct bss_info_t *bss_data) +{ + INFO("keymgmt : %s", str_keymgmt); + + if (strcmp(str_keymgmt, "ieee8021x") == 0) { + bss_data->security = WIFI_SECURITY_IEEE8021X; + } else if (strcmp(str_keymgmt, "wpa-psk") == 0) { + bss_data->security = WIFI_SECURITY_PSK; + } else if (strcmp(str_keymgmt, "wpa-psk-sha256") == 0) { + bss_data->security = WIFI_SECURITY_PSK; + } else if (strcmp(str_keymgmt, "wpa-ft-psk") == 0) { + bss_data->security = WIFI_SECURITY_PSK; + } else if (strcmp(str_keymgmt, "wpa-ft-eap") == 0) { + bss_data->security = WIFI_SECURITY_IEEE8021X; + } else if (strcmp(str_keymgmt, "wpa-eap") == 0) { + bss_data->security = WIFI_SECURITY_IEEE8021X; + } else if (strcmp(str_keymgmt, "wpa-eap-sha256") == 0) { + bss_data->security = WIFI_SECURITY_IEEE8021X; + } else if (strcmp(str_keymgmt, "wps") == 0) { + bss_data->wps = TRUE; + } +} + +static void __netconfig_wifi_parse_keymgmt_message(DBusMessageIter *iter, struct bss_info_t *bss_data) +{ + DBusMessageIter dict, entry, array, value; + const char *key; + + if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY) + return; + + dbus_message_iter_recurse(iter, &dict); + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict, &entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) + return; + + dbus_message_iter_get_basic(&entry, &key); + if (g_strcmp0(key, "KeyMgmt") == 0) { + dbus_message_iter_next(&entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) + return; + + dbus_message_iter_recurse(&entry, &array); + if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_ARRAY) + return; + + dbus_message_iter_recurse(&array, &value); + while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_STRING) { + const char *str = NULL; + + dbus_message_iter_get_basic(&value, &str); + if (str == NULL) + return; + + __netconfig_wifi_check_security(str, bss_data); + dbus_message_iter_next(&value); + } + } + + dbus_message_iter_next(&dict); + } +} + +gboolean netconfig_wifi_get_ssid_scan_state(void) +{ + return wifi_ssid_scan_state; +} + +void netconfig_wifi_notify_ssid_scan_done(void) +{ + if (netconfig_wifi_get_ssid_scan_state() != TRUE) + return; + + __netconfig_wifi_ssid_scan_finished(); + + __netconfig_wifi_notify_ssid_scan_done(); + + netconfig_wifi_bgscan_start(); +} + +void netconfig_wifi_bss_added(DBusMessage *message) +{ + DBusMessageIter iter, dict, entry; + DBusMessageIter value, array; + const char *key; + struct bss_info_t *bss_info; + + if (netconfig_wifi_get_ssid_scan_state() != TRUE) + return; + + INFO("NEW BSS added"); + + if (!dbus_message_iter_init(message, &iter)) { + DBG("Message does not have parameters"); + return; + } + + dbus_message_iter_next(&iter); + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY) { + DBG("Invalid message type"); + return; + } + + bss_info = g_try_new0(struct bss_info_t, 1); + if (bss_info == NULL) { + DBG("Out of memory"); + return; + } + + dbus_message_iter_recurse(&iter, &dict); + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { + dbus_message_iter_recurse(&dict, &entry); + + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_STRING) + goto error; + + dbus_message_iter_get_basic(&entry, &key); + if (key == NULL) + goto error; + + dbus_message_iter_next(&entry); + if (dbus_message_iter_get_arg_type(&entry) != DBUS_TYPE_VARIANT) + goto error; + + dbus_message_iter_recurse(&entry, &value); + + if (g_strcmp0(key, "SSID") == 0) { + unsigned char *ssid; + int ssid_len; + + dbus_message_iter_recurse(&value, &array); + dbus_message_iter_get_fixed_array(&array, &ssid, &ssid_len); + + if (ssid_len > 0 && ssid_len < 33) + memcpy(bss_info->ssid, ssid, ssid_len); + else + memset(bss_info->ssid, 0, sizeof(bss_info->ssid)); + } else if (g_strcmp0(key, "Privacy") == 0) { + dbus_bool_t privacy = FALSE; + + dbus_message_iter_get_basic(&value, &privacy); + bss_info->privacy = privacy; + } else if ((g_strcmp0(key, "RSN") == 0) || (g_strcmp0(key, "WPA") == 0)) { + + __netconfig_wifi_parse_keymgmt_message(&value, bss_info); + } else if (g_strcmp0(key, "IEs") == 0) { + unsigned char *ie; + int ie_len; + + dbus_message_iter_recurse(&value, &array); + dbus_message_iter_get_fixed_array(&array, &ie, &ie_len); + } + + dbus_message_iter_next(&dict); + } + + if (bss_info->ssid[0] == 0) + goto error; + + if (bss_info->security == WIFI_SECURITY_UNKNOWN) { + if (bss_info->privacy == TRUE) + bss_info->security = WIFI_SECURITY_WEP; + else + bss_info->security = WIFI_SECURITY_NONE; + } + + wifi_bss_info_list = g_slist_append(wifi_bss_info_list, bss_info); + return; + +error: + g_free(bss_info); +} + +gboolean netconfig_wifi_ssid_scan(const char *ssid) +{ + char object_path[DBUS_PATH_MAX_BUFLEN] = { 0, }; + char *path_ptr = &object_path[0]; + static char *scan_ssid = NULL; + + netconfig_wifi_bgscan_stop(); + + if (ssid != NULL) { + g_free(scan_ssid); + scan_ssid = g_strdup(ssid); + } + + if (scan_ssid == NULL) { + netconfig_wifi_bgscan_start(); + return FALSE; + } + + if (netconfig_wifi_get_scanning() == TRUE) { + DBG("Wi-Fi scan is in progress! SSID %s scan will be delayed", + scan_ssid); + return FALSE; + } + + INFO("Start SSID Scan with %s", scan_ssid); + + if (wifi_bss_info_list) { + g_slist_free_full(wifi_bss_info_list, g_free); + wifi_bss_info_list = NULL; + } + + if (netconfig_wifi_get_supplicant_interface(&path_ptr) != TRUE) { + DBG("Fail to get wpa_supplicant DBus path"); + return FALSE; + } + + if (__netconfig_wifi_invoke_ssid_scan( + (const char *)object_path, (const char *)scan_ssid) == TRUE) { + __netconfig_wifi_ssid_scan_started(); + + g_free(scan_ssid); + scan_ssid = NULL; + + return TRUE; + } + + return FALSE; +} + +gboolean netconfig_iface_wifi_request_specific_scan(NetconfigWifi *wifi, + gchar *ssid, GError **error) +{ + g_return_val_if_fail(wifi != NULL, FALSE); + g_return_val_if_fail(ssid != NULL, FALSE); + + netconfig_wifi_ssid_scan((const char *)ssid); + + return TRUE; +} diff --git a/src/wifi-state.c b/src/wifi-state.c new file mode 100644 index 0000000..6293f13 --- /dev/null +++ b/src/wifi-state.c @@ -0,0 +1,445 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "util.h" +#include "netdbus.h" +#include "network-state.h" +#include "network-statistics.h" +#include "wifi-state.h" +#include "wifi-indicator.h" +#include "wifi-background-scan.h" + +static int profiles_count = 0; + +static enum netconfig_wifi_service_state + wifi_service_state = NETCONFIG_WIFI_UNKNOWN; + +static GSList *notifier_list = NULL; + + +static void __netconfig_wifi_set_profiles_count(const int count) +{ + profiles_count = count; +} + +static int __netconfig_wifi_get_profiles_count(void) +{ + return profiles_count; +} + +static void __netconfig_wifi_set_essid(void) +{ + const char *essid_name = NULL; + const char *wifi_profile = netconfig_get_default_profile(); + + if (netconfig_wifi_state_get_service_state() != NETCONFIG_WIFI_CONNECTED) + return; + + if (wifi_profile == NULL || + netconfig_is_wifi_profile(wifi_profile) != TRUE) { + ERR("Can't get Wi-Fi profile"); + return; + } + + essid_name = netconfig_wifi_get_connected_essid(wifi_profile); + if (essid_name == NULL) { + ERR("Can't get Wi-Fi name"); + return; + } + + vconf_set_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, essid_name); +} + +static void __netconfig_wifi_unset_essid(void) +{ + vconf_set_str(VCONFKEY_WIFI_CONNECTED_AP_NAME, ""); +} + +static GSList *__netconfig_wifi_state_get_service_profiles(DBusMessage *message) +{ + GSList *service_profiles = NULL; + DBusMessageIter iter, dict; + + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &dict); + + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_STRUCT) { + DBusMessageIter entry; + const char *object_path = NULL; + + dbus_message_iter_recurse(&dict, &entry); + dbus_message_iter_get_basic(&entry, &object_path); + + if (object_path == NULL) { + dbus_message_iter_next(&dict); + continue; + } + + if (netconfig_is_wifi_profile(object_path) == TRUE) + service_profiles = g_slist_append(service_profiles, + g_strdup(object_path)); + + dbus_message_iter_next(&dict); + } + + return service_profiles; +} + +static char *__netconfig_wifi_get_connman_favorite_service(void) +{ + char *favorite_service = NULL; + DBusMessage *message = NULL; + GSList *service_profiles = NULL; + GSList *list = NULL; + + message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, + "GetServices", NULL); + if (message == NULL) { + ERR("Failed to get service list"); + return NULL; + } + + /* Get service profiles from ConnMan Manager */ + service_profiles = __netconfig_wifi_state_get_service_profiles(message); + dbus_message_unref(message); + + for (list = service_profiles; list != NULL; list = list->next) { + char *profile_path = list->data; + DBusMessageIter iter, array; + + if (favorite_service != NULL) + break; + + message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, + profile_path, CONNMAN_SERVICE_INTERFACE, "GetProperties", NULL); + + if (message == NULL) { + ERR("Failed to get service information of %s", profile_path); + continue; + } + + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &array); + + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry, variant; + const char *key = NULL; + dbus_bool_t value; + + dbus_message_iter_recurse(&array, &entry); + dbus_message_iter_get_basic(&entry, &key); + + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &variant); + + if (g_str_equal(key, "Favorite") != TRUE) { + dbus_message_iter_next(&array); + continue; + } + + dbus_message_iter_get_basic(&variant, &value); + + if (value) + favorite_service = g_strdup(profile_path); + + break; + } + + dbus_message_unref(message); + } + + g_slist_free(service_profiles); + + return favorite_service; +} + +static void __netconfig_wifi_state_changed( + enum netconfig_wifi_service_state state) +{ + GSList *list; + + for (list = notifier_list; list; list = list->next) { + struct netconfig_wifi_state_notifier *notifier = list->data; + + if (notifier->netconfig_wifi_state_changed != NULL) + notifier->netconfig_wifi_state_changed(state, notifier->user_data); + } +} + +void netconfig_wifi_state_set_service_state( + enum netconfig_wifi_service_state new_state) +{ + enum netconfig_wifi_service_state old_state = wifi_service_state; + + if (old_state == new_state) + return; + + wifi_service_state = new_state; + DBG("Wi-Fi state %d ==> %d", old_state, new_state); + + if (new_state == NETCONFIG_WIFI_CONNECTED) { + netconfig_del_wifi_found_notification(); + + vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_CONNECTED); + vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_CONNECTED); + + __netconfig_wifi_set_essid(); + + netconfig_wifi_indicator_start(); + } else if (old_state == NETCONFIG_WIFI_CONNECTED) { + vconf_set_int (VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED); + vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED); + + __netconfig_wifi_unset_essid(); + + netconfig_wifi_indicator_stop(); + } + + __netconfig_wifi_state_changed(new_state); +} + +enum netconfig_wifi_service_state +netconfig_wifi_state_get_service_state(void) +{ + return wifi_service_state; +} + +enum netconfig_wifi_tech_state netconfig_wifi_get_technology_state(void) +{ + DBusMessage *message = NULL; + DBusMessageIter iter, array; + enum netconfig_wifi_tech_state ret = NETCONFIG_WIFI_TECH_OFF; + gboolean wifi_tech_powered = FALSE; + gboolean wifi_tech_connected = FALSE; + + message = netconfig_invoke_dbus_method(CONNMAN_SERVICE, + CONNMAN_MANAGER_PATH, CONNMAN_MANAGER_INTERFACE, + "GetTechnologies", NULL); + if (message == NULL) { + ERR("Failed to get Wi-Fi technology state"); + return NETCONFIG_WIFI_TECH_UNKNOWN; + } + + dbus_message_iter_init(message, &iter); + dbus_message_iter_recurse(&iter, &array); + + while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_STRUCT) { + DBusMessageIter entry, dict; + const char *path; + + dbus_message_iter_recurse(&array, &entry); + dbus_message_iter_get_basic(&entry, &path); + + dbus_message_iter_next(&entry); + dbus_message_iter_recurse(&entry, &dict); + + if (path == NULL || + g_str_equal(path, CONNMAN_WIFI_TECHNOLOGY_PREFIX) == FALSE) { + dbus_message_iter_next(&array); + continue; + } + + while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) { + DBusMessageIter entry1, value1; + const char *key, *sdata; + dbus_bool_t data; + + dbus_message_iter_recurse(&dict, &entry1); + dbus_message_iter_get_basic(&entry1, &key); + + dbus_message_iter_next(&entry1); + dbus_message_iter_recurse(&entry1, &value1); + + if (dbus_message_iter_get_arg_type(&value1) == + DBUS_TYPE_BOOLEAN) { + dbus_message_iter_get_basic(&value1, &data); + DBG("key-[%s] - %s", key, data ? "True" : "False"); + + if (strcmp(key, "Powered") == 0 && data) { + wifi_tech_powered = TRUE; + } else if (strcmp(key, "Connected") == 0 && data) { + wifi_tech_connected = TRUE; + } else if (strcmp(key, "Tethering") == 0 && data) { + /* For further use */ + } + } else if (dbus_message_iter_get_arg_type(&value1) == + DBUS_TYPE_STRING) { + dbus_message_iter_get_basic(&value1, &sdata); + DBG("%s", sdata); + } + dbus_message_iter_next(&dict); + } + + dbus_message_iter_next(&array); + } + + dbus_message_unref(message); + + if (wifi_tech_powered) + ret = NETCONFIG_WIFI_TECH_POWERED; + + if (wifi_tech_connected) + ret = NETCONFIG_WIFI_TECH_CONNECTED; + + return ret; +} + +void netconfig_wifi_update_power_state(gboolean powered) +{ + int wifi_state = 0; + + vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state); + + if (powered == TRUE) { + if (wifi_state == VCONFKEY_WIFI_OFF && + netconfig_is_wifi_direct_on() != TRUE && + netconfig_is_wifi_tethering_on() != TRUE) { + DBG("Wi-Fi successfully turned on"); + + vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_NOT_CONNECTED); + + vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_ON); + + vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_UNCONNECTED); + + netconfig_wifi_bgscan_start(); + } + } else { + if (wifi_state != VCONFKEY_WIFI_OFF) { + DBG("Wi-Fi successfully turned off"); + + netconfig_del_wifi_found_notification(); + + netconfig_wifi_bgscan_stop(); + + __netconfig_wifi_set_profiles_count(0); + + vconf_set_int(VCONFKEY_NETWORK_WIFI_STATE, VCONFKEY_NETWORK_WIFI_OFF); + + vconf_set_int(VCONF_WIFI_LAST_POWER_STATE, WIFI_POWER_OFF); + + vconf_set_int(VCONFKEY_WIFI_STATE, VCONFKEY_WIFI_OFF); + } + } +} + +char *netconfig_wifi_get_favorite_service(void) +{ + return __netconfig_wifi_get_connman_favorite_service(); +} + +void netconfig_wifi_check_network_notification(DBusMessage *message) +{ + DBusMessageIter iter; + int profiles_count = 0; + int qs_enable, ug_state; + + if (netconfig_wifi_state_get_service_state() == NETCONFIG_WIFI_CONNECTED) { + DBG("Service state is connected"); + return; + } + + if (vconf_get_int(VCONFKEY_WIFI_ENABLE_QS, &qs_enable) == -1) { + DBG("Fail to get %s", VCONFKEY_WIFI_ENABLE_QS); + return; + } + + if (qs_enable != VCONFKEY_WIFI_QS_ENABLE) { + DBG("qs_enable != VCONFKEY_WIFI_QS_ENABLE"); + return; + } + + if (vconf_get_int(VCONFKEY_WIFI_UG_RUN_STATE, &ug_state) == -1) { + DBG("Fail to get %s", VCONFKEY_WIFI_UG_RUN_STATE); + return; + } + + if (ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND) { + DBG("ug_state == VCONFKEY_WIFI_UG_RUN_STATE_ON_FOREGROUND"); + return; + } + + if (message == NULL) { + ERR("Failed to get service list"); + return; + } + + dbus_message_iter_init(message, &iter); + DBusMessageIter array, value; + dbus_message_iter_recurse(&iter, &array); + if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRUCT) { + DBG("Array not found. type %d", dbus_message_iter_get_arg_type(&array)); + return; + } + + dbus_message_iter_recurse(&array, &value); + while (dbus_message_iter_get_arg_type(&value) == DBUS_TYPE_OBJECT_PATH) { + const char *object_path = NULL; + + dbus_message_iter_get_basic(&value, &object_path); + + DBG("found a profile: %s", object_path); + if (netconfig_is_wifi_profile(object_path) == TRUE) { + profiles_count++; + DBG("Total wifi profile cnt = %d", profiles_count); + } + + dbus_message_iter_next(&array); + if (dbus_message_iter_get_arg_type(&array) != DBUS_TYPE_STRUCT) { + DBG("Not a structure entry. Arg type = %d", dbus_message_iter_get_arg_type(&array)); + break; + } + dbus_message_iter_recurse(&array, &value); + } + + if (__netconfig_wifi_get_profiles_count() != profiles_count) { + DBG("profiles prev_count (%d) - profiles count (%d)", + __netconfig_wifi_get_profiles_count(), profiles_count); + + netconfig_add_wifi_found_notification(); + __netconfig_wifi_set_profiles_count(profiles_count); + } else + DBG("No change in profile count[%d]", profiles_count); +} + +void netconfig_wifi_state_notifier_cleanup(void) +{ + g_slist_free_full(notifier_list, NULL); +} + +void netconfig_wifi_state_notifier_register( + struct netconfig_wifi_state_notifier *notifier) +{ + DBG("register notifier"); + + notifier_list = g_slist_append(notifier_list, notifier); +} + +void netconfig_wifi_state_notifier_unregister( + struct netconfig_wifi_state_notifier *notifier) +{ + DBG("un-register notifier"); + + notifier_list = g_slist_remove_all(notifier_list, notifier); +} diff --git a/src/wifi.c b/src/wifi.c new file mode 100644 index 0000000..baf3e12 --- /dev/null +++ b/src/wifi.c @@ -0,0 +1,172 @@ +/* + * Network Configuration Module + * + * Copyright (c) 2012-2013 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 "log.h" +#include "wifi.h" +#include "util.h" +#include "netdbus.h" +#include "neterror.h" +#include "netconfig.h" +#include "wifi-power.h" +#include "wifi-state.h" +#include "wifi-ssid-scan.h" +#include "wifi-eap.h" +#include "wifi-eap-config.h" +#include "wifi-background-scan.h" +#include "wifi-agent.h" + +#include "netconfig-iface-wifi-glue.h" + + +#define PROP_DEFAULT FALSE +#define PROP_DEFAULT_STR NULL + +enum { + PROP_O, + PROP_WIFI_CONN, + PROP_WIFI_PATH, +}; + +enum { + SIG_WIFI_DRIVER, + SIG_LAST +}; + +struct NetconfigWifiClass { + GObjectClass parent; + + /* method and signals */ + void (*driver_loaded) (NetconfigWifi *wifi, gchar *mac); +}; + +struct NetconfigWifi { + GObject parent; + + /* member variable */ + DBusGConnection *conn; + gchar *path; +}; + +static guint32 signals[SIG_LAST] = { 0, }; + +G_DEFINE_TYPE(NetconfigWifi, netconfig_wifi, G_TYPE_OBJECT); + + +static void __netconfig_wifi_gobject_get_property(GObject *object, guint prop_id, + GValue *value, GParamSpec *pspec) +{ + return; +} + +static void __netconfig_wifi_gobject_set_property(GObject *object, guint prop_id, + const GValue *value, GParamSpec *pspec) +{ + NetconfigWifi *wifi = NETCONFIG_WIFI(object); + + switch (prop_id) { + case PROP_WIFI_CONN: + { + wifi->conn = g_value_get_boxed(value); + INFO("wifi(%p) set conn(%p)", wifi, wifi->conn); + break; + } + + case PROP_WIFI_PATH: + { + if (wifi->path) + g_free(wifi->path); + + wifi->path = g_value_dup_string(value); + INFO("wifi(%p) path(%s)", wifi, wifi->path); + + break; + } + + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec); + } +} + +static void netconfig_wifi_init(NetconfigWifi *wifi) +{ + DBG("wifi initialize"); + + wifi->conn = NULL; + wifi->path = g_strdup(PROP_DEFAULT_STR); +} + +static void netconfig_wifi_class_init(NetconfigWifiClass *klass) +{ + GObjectClass *object_class = G_OBJECT_CLASS(klass); + + DBG("class initialize"); + + object_class->get_property = __netconfig_wifi_gobject_get_property; + object_class->set_property = __netconfig_wifi_gobject_set_property; + + /* DBus register */ + dbus_g_object_type_install_info(NETCONFIG_TYPE_WIFI, + &dbus_glib_netconfig_iface_wifi_object_info); + + /* property */ + g_object_class_install_property(object_class, PROP_WIFI_CONN, + g_param_spec_boxed("conn", "CONNECTION", "DBus connection", + DBUS_TYPE_G_CONNECTION, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + g_object_class_install_property(object_class, PROP_WIFI_PATH, + g_param_spec_string("path", "PATH", "Object Path", + PROP_DEFAULT_STR, + G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); + + /* signal */ + signals[SIG_WIFI_DRIVER] = g_signal_new("driver-loaded", + G_OBJECT_CLASS_TYPE(klass), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET(NetconfigWifiClass, + driver_loaded), + NULL, NULL, + g_cclosure_marshal_VOID__STRING, + G_TYPE_NONE, 1, G_TYPE_STRING); +} + +gpointer netconfig_wifi_create_and_init(DBusGConnection *conn) +{ + GObject *object; + + g_return_val_if_fail(conn != NULL, NULL); + + object = g_object_new(NETCONFIG_TYPE_WIFI, "conn", conn, "path", + NETCONFIG_WIFI_PATH, NULL); + + INFO("create wifi(%p)", object); + + dbus_g_connection_register_g_object(conn, NETCONFIG_WIFI_PATH, object); + + INFO("wifi(%p) register DBus path(%s)", object, NETCONFIG_WIFI_PATH); + + netconfig_wifi_power_configuration(); + + return object; +} -- 2.34.1