From d4a0424540421ac311a201ad3f0ef2f37c055cc9 Mon Sep 17 00:00:00 2001 From: taesubkim Date: Thu, 10 Apr 2014 11:24:44 +0900 Subject: [PATCH] HS20: Enable to set/get Wi-Fi passpoint option Signed-off-by: Taesub Kim Change-Id: I9824a24d4ecea48af7ad8f9cd510ebde97e7ae24 --- CMakeLists.txt | 1 + include/netsupplicant.h | 17 ++ include/wifi-passpoint.h | 39 ++++ interfaces/netconfig-iface-wifi.xml | 6 + packaging/net-config.spec | 2 +- src/dbus/netsupplicant.c | 272 +++++++++++++++++++++++++++- src/wifi-passpoint.c | 111 ++++++++++++ src/wifi.c | 1 + 8 files changed, 438 insertions(+), 11 deletions(-) create mode 100644 include/wifi-passpoint.h create mode 100644 src/wifi-passpoint.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 26b1b0b..061d6fa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ SET(SRCS src/wifi-power.c src/wifi-state.c src/wifi-eap.c + src/wifi-passpoint.c src/network-clock.c src/network-state.c src/network-statistics.c diff --git a/include/netsupplicant.h b/include/netsupplicant.h index ea5ae37..30bcfd6 100644 --- a/include/netsupplicant.h +++ b/include/netsupplicant.h @@ -28,8 +28,11 @@ extern "C" { #include #include +#define WIFI_IFNAME "wlan0" + #define SUPPLICANT_SERVICE "fi.w1.wpa_supplicant1" #define SUPPLICANT_INTERFACE "fi.w1.wpa_supplicant1" +#define SUPPLICANT_IFACE_INTERFACE SUPPLICANT_INTERFACE ".Interface" #define SUPPLICANT_PATH "/fi/w1/wpa_supplicant1" #define SUPPLICANT_GLOBAL_INTERFACE "org.freedesktop.DBus.Properties" @@ -40,11 +43,25 @@ struct dbus_input_arguments { gboolean netconfig_wifi_get_ifname(char **ifname); gboolean netconfig_wifi_get_supplicant_interface(char **path); + +const char *netconfig_wifi_get_supplicant_interface_(void); + +GList *setup_input_args(GList *list, struct dbus_input_arguments *items); + DBusMessage *netconfig_supplicant_invoke_dbus_method(const char *dest, DBusConnection *connection, const char *path, const char *interface_name, const char *method, GList *args); +DBusMessage *netconfig_supplicant_invoke_dbus_method_(const char *dest, + const char *path, const char *interface_name, + const char *method, GList *args); + +DBusMessage *netconfig_supplicant_invoke_dbus_interface_property_get(const char *interface, + const char *key); +dbus_bool_t netconfig_supplicant_invoke_dbus_interface_property_set(const char *interface, + const char *key, const char *type, GList *args, + DBusPendingCallNotifyFunction notify_func); #ifdef __cplusplus } #endif diff --git a/include/wifi-passpoint.h b/include/wifi-passpoint.h new file mode 100644 index 0000000..9983877 --- /dev/null +++ b/include/wifi-passpoint.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_PASSPOINT_H__ +#define __NETCONFIG_WIFI_PASSPOINT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "wifi.h" + +gboolean netconfig_iface_wifi_get_passpoint(NetconfigWifi *wifi, + int *result, GError **error); +gboolean netconfig_iface_wifi_set_passpoint(NetconfigWifi *wifi, + int enable, GError **error); + +#ifdef __cplusplus +} +#endif + +#endif /* __NETCONFIG_WIFI_PASSPOINT_H__ */ + diff --git a/interfaces/netconfig-iface-wifi.xml b/interfaces/netconfig-iface-wifi.xml index d6f862e..8ca646c 100644 --- a/interfaces/netconfig-iface-wifi.xml +++ b/interfaces/netconfig-iface-wifi.xml @@ -13,6 +13,12 @@ + + + + + + diff --git a/packaging/net-config.spec b/packaging/net-config.spec index a39a659..7f5a2ff 100644 --- a/packaging/net-config.spec +++ b/packaging/net-config.spec @@ -1,6 +1,6 @@ Name: net-config Summary: TIZEN Network Configuration Module -Version: 0.1.90_29 +Version: 0.1.90_30 Release: 1 Group: System/Network License: Apache-2.0 diff --git a/src/dbus/netsupplicant.c b/src/dbus/netsupplicant.c index d3926d5..876e2be 100644 --- a/src/dbus/netsupplicant.c +++ b/src/dbus/netsupplicant.c @@ -21,23 +21,42 @@ #include "netdbus.h" #include "netsupplicant.h" -#define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000) +#define DBUS_OBJECT_PATH_MAX 150 +#define NETCONFIG_DBUS_REPLY_TIMEOUT (10 * 1000) static void setup_dbus_args(gpointer data, gpointer user_data) { - struct dbus_input_arguments *args; DBusMessageIter *iter; + struct dbus_input_arguments *args; - 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)); + if (data == NULL || user_data == NULL) + return; + + iter = (DBusMessageIter *) user_data; + args = (struct dbus_input_arguments *)data; + + if (args->data == NULL) + return; + + switch (args->type) { + case DBUS_TYPE_STRING: + case DBUS_TYPE_OBJECT_PATH: + DBG("parameter [%s]", args->data); + dbus_message_iter_append_basic(iter, args->type, &(args->data)); + break; + case DBUS_TYPE_BOOLEAN: + case DBUS_TYPE_UINT32: + case DBUS_TYPE_INT32: + DBG("parameter [%d]", args->data); + dbus_message_iter_append_basic(iter, args->type, args->data); + break; + case DBUS_TYPE_INVALID: + default: + return; } } -static GList *setup_input_args(GList *list, +GList *setup_input_args(GList *list, struct dbus_input_arguments *items) { struct dbus_input_arguments *iter = items; @@ -46,7 +65,7 @@ static GList *setup_input_args(GList *list, return NULL; while (iter->data) { - list = g_list_append(list, iter); + list = g_list_append(list, iter); //Adds a new element on to the end of the list iter++; } @@ -227,6 +246,54 @@ error: return FALSE; } +const char *netconfig_wifi_get_supplicant_interface_(void) +{ + GList *input_args = NULL; + DBusMessage *message = NULL; + struct dbus_input_arguments args[] = { + {DBUS_TYPE_STRING, WIFI_IFNAME}, + {DBUS_TYPE_INVALID, NULL} + }; + const char *path; + static char obj_path[DBUS_OBJECT_PATH_MAX] = { '\0', }; + + if (obj_path[0] != '\0') + return (const char *)obj_path; + + input_args = setup_input_args(input_args, args); + + message = netconfig_supplicant_invoke_dbus_method_( + SUPPLICANT_SERVICE, SUPPLICANT_PATH, + SUPPLICANT_INTERFACE, "GetInterface", input_args); + + g_list_free(input_args); + + if (message == NULL) + return NULL; + + if (dbus_message_get_type(message) == 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_get_args(message, NULL, DBUS_TYPE_OBJECT_PATH, &path, + DBUS_TYPE_INVALID); + + g_strlcpy(obj_path, path, DBUS_OBJECT_PATH_MAX); + + dbus_message_unref(message); + + return (const char *)obj_path; + +error: + if (message != NULL) + dbus_message_unref(message); + + return NULL; +} + + DBusMessage *netconfig_supplicant_invoke_dbus_method(const char *dest, DBusConnection *connection, const char *path, const char *interface_name, @@ -271,3 +338,188 @@ DBusMessage *netconfig_supplicant_invoke_dbus_method(const char *dest, return reply; } + +DBusMessage *netconfig_supplicant_invoke_dbus_method_(const char *dest, + const char *path, const char *interface_name, + const char *method, GList *args) +{ + DBusError error; + DBusMessageIter iter; + DBusMessage *reply = NULL; + DBusMessage *message = NULL; + DBusConnection *connection = NULL; + +// DBG("[DBUS Sync] %s %s %s", interface_name, method, path); + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) { + ERR("Failed to get system bus"); + return NULL; + } + + message = dbus_message_new_method_call(dest, path, interface_name, method); + if (message == NULL) { + ERR("Failed DBus method call"); + dbus_connection_unref(connection); + 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("dbus_connection_send_with_reply_and_block() failed. " + "DBus error [%s: %s]", error.name, error.message); + + dbus_error_free(&error); + } else + ERR("Failed to get properties"); + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return NULL; + } + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return reply; +} + +DBusMessage *netconfig_supplicant_invoke_dbus_interface_property_get(const char *interface, + const char *key) +{ + DBusError error; + DBusMessage *reply = NULL; + DBusMessage *message = NULL; + DBusConnection *connection = NULL; + const char *path; + + ERR("[DBUS] property_get : %s", key); + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) { + ERR("Failed to get system bus"); + return NULL; + } + + path = netconfig_wifi_get_supplicant_interface_(); + if (path == NULL) { + DBG("Failed to get wpa_supplicant DBus path"); + dbus_connection_unref(connection); + return NULL; + } + + message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path, + DBUS_INTERFACE_PROPERTIES, "Get"); + if (message == NULL) { + ERR("Failed DBus method call"); + dbus_connection_unref(connection); + return NULL; + } + + dbus_message_append_args(message, DBUS_TYPE_STRING, &interface, + DBUS_TYPE_STRING, &key, NULL); + + 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("dbus_connection_send_with_reply_and_block() failed. " + "DBus error [%s: %s]", error.name, error.message); + + dbus_error_free(&error); + } else + ERR("Failed to get properties"); + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return NULL; + } + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return reply; +} + +dbus_bool_t netconfig_supplicant_invoke_dbus_interface_property_set(const char *interface, + const char *key, const char *type, GList *args, + DBusPendingCallNotifyFunction notify_func) +{ + dbus_bool_t result = FALSE; + DBusPendingCall *call; + DBusMessage *message = NULL; + DBusConnection *connection = NULL; + DBusMessageIter iter, value; + const char *path; + + DBG("[DBUS] property_set : %s", key); + + connection = dbus_bus_get(DBUS_BUS_SYSTEM, NULL); + if (connection == NULL) { + ERR("Failed to get system bus"); + return result; + } + + path = netconfig_wifi_get_supplicant_interface_(); + if (path == NULL) { + ERR("Failed to get wpa_supplicant DBus path"); + dbus_connection_unref(connection); + return result; + } + + message = dbus_message_new_method_call(SUPPLICANT_SERVICE, path, + DBUS_INTERFACE_PROPERTIES, "Set"); + if (message == NULL) { + ERR("Failed DBus method call"); + dbus_connection_unref(connection); + return result; + } + + dbus_message_iter_init_append(message, &iter); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &interface); + dbus_message_iter_append_basic(&iter, DBUS_TYPE_STRING, &key); + + dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, + type, &value); + + if (args != NULL) + g_list_foreach(args, setup_dbus_args, (gpointer)&value); + + dbus_message_iter_close_container(&iter, &value); + + result = dbus_connection_send_with_reply(connection, message, &call, + NETCONFIG_DBUS_REPLY_TIMEOUT); + if (result == FALSE || call == NULL) { + ERR("dbus_connection_send_with_reply() failed"); + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return result; + } + + if (notify_func == NULL) + dbus_pending_call_cancel(call); + else + dbus_pending_call_set_notify(call, notify_func, NULL, NULL); + + dbus_message_unref(message); + dbus_connection_unref(connection); + + return result; +} + diff --git a/src/wifi-passpoint.c b/src/wifi-passpoint.c new file mode 100644 index 0000000..debb4d1 --- /dev/null +++ b/src/wifi-passpoint.c @@ -0,0 +1,111 @@ +/* + * 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 "util.h" +#include "neterror.h" +#include "netdbus.h" +#include "netsupplicant.h" +#include "wifi-passpoint.h" + + +static gboolean netconfig_wifi_get_passpoint(gint32 *enabled) +{ + DBusMessage *reply; + DBusMessageIter iter, variant; + dbus_bool_t value; + gboolean result = FALSE; + + reply = netconfig_supplicant_invoke_dbus_interface_property_get(SUPPLICANT_IFACE_INTERFACE, + "Passpoint"); + if (reply == NULL) { + ERR("Error!!! Failed to get passpoint property"); + return result; + } + + if (dbus_message_get_type(reply) == DBUS_MESSAGE_TYPE_ERROR) { + const char *err_msg = dbus_message_get_error_name(reply); + ERR("Error!!! Error message received [%s]", err_msg); + return result; + } + + dbus_message_iter_init(reply, &iter); + + if (dbus_message_iter_get_arg_type(&iter) == DBUS_TYPE_VARIANT) { + dbus_message_iter_recurse(&iter, &variant); + if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_INT32) { + dbus_message_iter_get_basic(&variant, &value); + if (value == TRUE) + *enabled = 1; + else + *enabled = 0; + + result = TRUE; + } + } + + dbus_message_unref(reply); + + return result; +} + +static gboolean netconfig_wifi_set_passpoint(gint32 enable) +{ + gint32 value = enable; + gboolean result = FALSE; + GList *input_args = NULL; + + struct dbus_input_arguments args_enable[2] = { + {DBUS_TYPE_INT32, &value}, + {DBUS_TYPE_INVALID, NULL} + }; + + input_args = setup_input_args(input_args, args_enable); + + result = netconfig_supplicant_invoke_dbus_interface_property_set(SUPPLICANT_IFACE_INTERFACE, + "Passpoint", DBUS_TYPE_INT32_AS_STRING, input_args, NULL); + if (result == FALSE) + ERR("Fail to set passpoint enable [%d]", enable); + + g_list_free(input_args); + + return result; +} + +gboolean netconfig_iface_wifi_get_passpoint(NetconfigWifi *wifi, + gint32 *result, GError **error) +{ + g_return_val_if_fail(wifi != NULL, FALSE); + + if (netconfig_wifi_get_passpoint(result)) + return TRUE; + + return FALSE; +} + +gboolean netconfig_iface_wifi_set_passpoint(NetconfigWifi *wifi, + gint32 enable, GError **error) +{ + g_return_val_if_fail(wifi != NULL, FALSE);//Verifies that the expression expr , usually representing a precondition, evaluates to TRUE. If the function does not return a value, use g_return_if_fail() instead + + return netconfig_wifi_set_passpoint(enable); +} + diff --git a/src/wifi.c b/src/wifi.c index e5e4ddb..835e8fc 100644 --- a/src/wifi.c +++ b/src/wifi.c @@ -32,6 +32,7 @@ #include "wifi-state.h" #include "wifi-ssid-scan.h" #include "wifi-eap.h" +#include "wifi-passpoint.h" #include "wifi-eap-config.h" #include "wifi-background-scan.h" #include "wifi-agent.h" -- 2.34.1