2 * Network Configuration Module
4 * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. All rights reserved.
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
22 #include <dbus/dbus-glib-lowlevel.h>
25 #include <vconf-keys.h>
30 #include "netsupplicant.h"
31 #include "wifi-state.h"
32 #include "wifi-indicator.h"
33 #include "wifi-ssid-scan.h"
34 #include "wifi-background-scan.h"
35 #include "network-state.h"
39 #define SIGNAL_SCAN_DONE "ScanDone"
40 #define SIGNAL_BSS_ADDED "BSSAdded"
41 #define SIGNAL_PROPERTIES_CHANGED "PropertiesChanged"
43 #define CONNMAN_SIGNAL_SERVICES_CHANGED "ServicesChanged"
44 #define CONNMAN_SIGNAL_PROPERTY_CHANGED "PropertyChanged"
46 #define CONNMAN_MANAGER_SIGNAL_FILTER "type='signal',interface='net.connman.Manager'"
47 #define CONNMAN_TECHNOLOGY_SIGNAL_FILTER "type='signal',interface='net.connman.Technology'"
48 #define CONNMAN_SERVICE_SIGNAL_FILTER "type='signal',interface='net.connman.Service'"
49 #define SUPPLICANT_INTERFACE_SIGNAL_FILTER "type='signal',interface='fi.w1.wpa_supplicant1.Interface'"
52 static DBusConnection *signal_connection = NULL;
54 static char *__netconfig_get_property(DBusMessage *msg, int *prop_value)
56 DBusMessageIter args, variant;
57 char *property = NULL;
60 /** read these parameters */
61 if (!dbus_message_iter_init(msg, &args)) {
62 ERR("Message does not have parameters");
63 } else if (dbus_message_iter_get_arg_type(&args) != DBUS_TYPE_STRING) {
64 ERR("Argument is not string");
66 dbus_message_iter_get_basic(&args, &property);
67 dbus_message_iter_next(&args);
68 dbus_message_iter_recurse(&args, &variant);
69 /* Right now, checking for only 'Powered' property which has
72 if (dbus_message_iter_get_arg_type(&variant) == DBUS_TYPE_BOOLEAN) {
73 dbus_message_iter_get_basic(&variant, &data);
86 static void __netconfig_wifi_technology_state_signal_handler(
87 const char *property, int prop_value)
89 static int previous_technology_state = FALSE;
90 GError **error = NULL;
92 if (property == NULL || g_str_equal(property, "Powered") != TRUE)
95 if (previous_technology_state == prop_value) {
96 INFO("Same as previous state");
100 previous_technology_state = prop_value;
102 INFO("Technology property - [%s], prop_value - [%d]",
103 property, prop_value);
105 if (prop_value == FALSE) {
106 enum netconfig_wifi_tech_state state = NETCONFIG_WIFI_TECH_OFF;
108 state = netconfig_wifi_get_technology_state();
109 INFO("Wi-Fi technology state: %d", state);
111 if (NETCONFIG_WIFI_TECH_OFF == state ||
112 NETCONFIG_WIFI_TECH_UNKNOWN == state) {
113 if (netconfig_wifi_remove_driver() == TRUE) {
114 netconfig_wifi_update_power_state(FALSE);
116 netconfig_wifi_notify_power_completed(FALSE);
118 netconfig_error_wifi_driver_failed(error);
122 netconfig_wifi_update_power_state(TRUE);
123 netconfig_wifi_device_picker_service_start();
125 netconfig_wifi_notify_power_completed(TRUE);
129 static void __netconfig_wifi_service_state_signal_handler(DBusMessage *msg)
131 char *sigvalue = NULL;
132 char *property = NULL;
133 char *service_profile = NULL;
134 DBusMessageIter args, variant;
136 service_profile = (char *)dbus_message_get_path(msg);
137 if (service_profile == NULL)
140 dbus_message_iter_init(msg, &args);
141 dbus_message_iter_get_basic(&args, &sigvalue);
142 if (sigvalue == NULL)
145 if (g_str_equal(sigvalue, "State") == TRUE) {
146 dbus_message_iter_next(&args);
147 dbus_message_iter_recurse(&args, &variant);
148 dbus_message_iter_get_basic(&variant, &property);
150 DBG("[%s] %s", property, service_profile);
151 if (netconfig_is_wifi_profile(service_profile) == TRUE) {
154 vconf_get_int(VCONFKEY_WIFI_STATE, &wifi_state);
155 if (wifi_state == VCONFKEY_WIFI_OFF)
158 if (g_str_equal(property, "ready") == TRUE ||
159 g_str_equal(property, "online") == TRUE) {
160 if (wifi_state >= VCONFKEY_WIFI_CONNECTED)
163 netconfig_set_default_profile(service_profile);
165 netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTED);
167 } else if (g_str_equal(property, "failure") == TRUE ||
168 g_str_equal(property, "disconnect") == TRUE ||
169 g_str_equal(property, "idle") == TRUE) {
170 if (netconfig_get_default_profile() == NULL ||
171 netconfig_is_wifi_profile(netconfig_get_default_profile())
173 netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_IDLE);
177 if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE)
180 netconfig_set_default_profile(NULL);
182 netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_IDLE);
184 } else if (g_str_equal(property, "association") == TRUE ||
185 g_str_equal(property, "configuration") == TRUE) {
186 if (netconfig_get_default_profile() == NULL ||
187 netconfig_is_wifi_profile(netconfig_get_default_profile())
189 netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTING);
193 if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE)
196 netconfig_set_default_profile(NULL);
198 netconfig_wifi_state_set_service_state(NETCONFIG_WIFI_CONNECTING);
201 if (g_str_equal(property, "ready") == TRUE ||
202 g_str_equal(property, "online") == TRUE) {
203 if (netconfig_get_default_profile() == NULL)
204 netconfig_set_default_profile(service_profile);
206 } else if (g_str_equal(property, "failure") == TRUE ||
207 g_str_equal(property, "disconnect") == TRUE ||
208 g_str_equal(property, "idle") == TRUE) {
209 if (netconfig_get_default_profile() == NULL)
212 if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE)
215 netconfig_set_default_profile(NULL);
217 } else if (g_str_equal(property, "association") == TRUE ||
218 g_str_equal(property, "configuration") == TRUE) {
219 if (netconfig_get_default_profile() == NULL)
222 if (g_str_equal(service_profile, netconfig_get_default_profile()) != TRUE)
225 netconfig_set_default_profile(NULL);
231 static DBusHandlerResult __netconfig_signal_filter_handler(
232 DBusConnection *conn, DBusMessage *msg, void *user_data)
234 char *sigvalue = NULL;
237 DBG("Invalid Message. Ignore");
238 return DBUS_HANDLER_RESULT_HANDLED;
241 if (dbus_message_is_signal(msg, CONNMAN_MANAGER_INTERFACE,
242 CONNMAN_SIGNAL_PROPERTY_CHANGED)) {
243 /* We have handled this message, don't pass it on */
244 return DBUS_HANDLER_RESULT_HANDLED;
245 } else if (dbus_message_is_signal(msg, CONNMAN_TECHNOLOGY_INTERFACE,
246 CONNMAN_SIGNAL_PROPERTY_CHANGED)) {
247 int prop_value = FALSE;
248 char *technology_path = NULL;
250 technology_path = (char *)dbus_message_get_path(msg);
251 INFO("Technology object path: %s", technology_path);
253 if (g_str_has_prefix(technology_path,
254 CONNMAN_WIFI_TECHNOLOGY_PREFIX) == FALSE) {
255 return DBUS_HANDLER_RESULT_HANDLED;
258 sigvalue = __netconfig_get_property(msg, &prop_value);
259 if (sigvalue == NULL)
260 return DBUS_HANDLER_RESULT_HANDLED;
262 INFO("Technology Property - [%s], Value - [%d]", sigvalue, prop_value);
263 __netconfig_wifi_technology_state_signal_handler(
264 (const char *)sigvalue, prop_value);
266 /* We have handled this message, don't pass it on */
267 return DBUS_HANDLER_RESULT_HANDLED;
268 } else if (dbus_message_is_signal(msg, CONNMAN_SERVICE_INTERFACE,
269 CONNMAN_SIGNAL_PROPERTY_CHANGED)) {
270 __netconfig_wifi_service_state_signal_handler(msg);
272 return DBUS_HANDLER_RESULT_HANDLED;
273 } else if (dbus_message_is_signal(msg, CONNMAN_MANAGER_INTERFACE,
274 CONNMAN_SIGNAL_SERVICES_CHANGED)) {
275 DBG("Received CONNMAN_SIGNAL_SERVICES_CHANGED message");
276 netconfig_wifi_check_network_notification(msg);
278 return DBUS_HANDLER_RESULT_HANDLED;
279 } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface",
280 SIGNAL_PROPERTIES_CHANGED)) {
281 dbus_bool_t scanning = FALSE;
282 void *property = &scanning;
284 if (netconfig_dbus_get_basic_params_array(msg,
285 &sigvalue, &property) != TRUE)
286 return DBUS_HANDLER_RESULT_HANDLED;
288 if (sigvalue == NULL)
289 return DBUS_HANDLER_RESULT_HANDLED;
291 if (scanning == TRUE)
292 netconfig_wifi_set_scanning(TRUE);
294 return DBUS_HANDLER_RESULT_HANDLED;
295 } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface",
297 if (netconfig_wifi_get_ssid_scan_state() == TRUE)
298 netconfig_wifi_bss_added(msg);
300 return DBUS_HANDLER_RESULT_HANDLED;
301 } else if (dbus_message_is_signal(msg, SUPPLICANT_INTERFACE ".Interface",
303 netconfig_wifi_set_scanning(FALSE);
305 if (netconfig_wifi_get_bgscan_state() != TRUE) {
306 if (netconfig_wifi_get_ssid_scan_state() == TRUE)
307 netconfig_wifi_notify_ssid_scan_done();
309 netconfig_wifi_ssid_scan(NULL);
312 return DBUS_HANDLER_RESULT_HANDLED;
315 return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
318 void netconfig_register_signal(void)
320 DBusConnection *conn = NULL;
323 DBG("Register DBus signal filters");
325 dbus_error_init(&err);
326 conn = dbus_bus_get(DBUS_BUS_SYSTEM, NULL);
328 ERR("Error! Failed to connect to the D-BUS daemon: [%s]",
330 dbus_error_free(&err);
334 signal_connection = conn;
336 dbus_connection_setup_with_g_main(conn, NULL);
338 /* listening to messages from all objects as no path is specified */
339 /* see signals from the given interface */
340 dbus_bus_add_match(conn, CONNMAN_MANAGER_SIGNAL_FILTER, &err);
341 dbus_connection_flush(conn);
342 if (dbus_error_is_set(&err)) {
343 ERR("Error! Match Error (%s)", err.message);
344 dbus_error_free(&err);
348 dbus_bus_add_match(conn, CONNMAN_TECHNOLOGY_SIGNAL_FILTER, &err);
349 dbus_connection_flush(conn);
350 if (dbus_error_is_set(&err)) {
351 ERR("Error! Match Error (%s)", err.message);
352 dbus_error_free(&err);
356 dbus_bus_add_match(conn, CONNMAN_SERVICE_SIGNAL_FILTER, &err);
357 dbus_connection_flush(conn);
358 if (dbus_error_is_set(&err)) {
359 ERR("Error! Match Error (%s)", err.message);
360 dbus_error_free(&err);
364 dbus_bus_add_match(conn, SUPPLICANT_INTERFACE_SIGNAL_FILTER, &err);
365 dbus_connection_flush(conn);
366 if (dbus_error_is_set(&err)) {
367 ERR("Error! Match Error (%s)", err.message);
368 dbus_error_free(&err);
372 if (dbus_connection_add_filter(conn,
373 __netconfig_signal_filter_handler, NULL, NULL) == FALSE) {
374 ERR("Error! dbus_connection_add_filter() failed");
378 INFO("Successfully register signal filters");
381 void netconfig_deregister_signal(void)
383 if (signal_connection == NULL) {
384 ERR("Error! Already de-registered. Nothing to be done");
388 dbus_connection_remove_filter(signal_connection,
389 __netconfig_signal_filter_handler, NULL);
390 INFO("Successfully remove DBus signal filters");
392 dbus_connection_unref(signal_connection);
393 signal_connection = NULL;