5 * Copyright (C) 2007-2008 Intel Corporation. All rights reserved.
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
27 #include <dbus/dbus.h>
29 #include <connman/plugin.h>
30 #include <connman/driver.h>
31 #include <connman/log.h>
33 #include "supplicant.h"
41 static int network_probe(struct connman_element *element)
43 DBG("element %p name %s", element, element->name);
48 static void network_remove(struct connman_element *element)
50 DBG("element %p name %s", element, element->name);
53 static int network_enable(struct connman_element *element)
55 char *identifier, *passphrase = NULL;
59 DBG("element %p name %s", element, element->name);
61 if (connman_element_get_static_property(element,
62 "Identifier", &identifier) == FALSE)
65 if (connman_element_get_static_array_property(element,
66 "SSID", &ssid, &ssid_len) == FALSE)
69 if (element->parent != NULL) {
70 struct wifi_data *data = connman_element_get_data(element->parent);
73 g_free(data->identifier);
74 data->identifier = g_strdup(identifier);
78 DBG("identifier %s passhprase %s", identifier, passphrase);
80 if (__supplicant_connect(element, ssid, ssid_len, passphrase) < 0)
81 connman_error("Failed to initiate connect");
86 static int network_disable(struct connman_element *element)
88 DBG("element %p name %s", element, element->name);
90 connman_element_unregister_children(element);
92 __supplicant_disconnect(element);
97 static struct connman_driver network_driver = {
98 .name = "wifi-network",
99 .type = CONNMAN_ELEMENT_TYPE_NETWORK,
100 .subtype = CONNMAN_ELEMENT_SUBTYPE_WIFI,
101 .probe = network_probe,
102 .remove = network_remove,
103 .enable = network_enable,
104 .disable = network_disable,
107 static struct connman_element *find_element(struct wifi_data *data,
108 const char *identifier)
112 for (list = data->list; list; list = list->next) {
113 struct connman_element *element = list->data;
115 if (connman_element_match_static_property(element,
116 "Identifier", &identifier) == TRUE)
123 static void state_change(struct connman_element *parent,
124 enum supplicant_state state)
126 struct wifi_data *data = connman_element_get_data(parent);
127 struct connman_element *element;
129 DBG("state %d", state);
131 if (data->identifier == NULL)
134 element = find_element(data, data->identifier);
138 if (state == STATE_COMPLETED) {
139 struct connman_element *dhcp;
141 dhcp = connman_element_create(NULL);
143 dhcp->type = CONNMAN_ELEMENT_TYPE_DHCP;
144 dhcp->index = element->index;
146 connman_element_register(dhcp, element);
150 static void scan_result(struct connman_element *parent,
151 struct supplicant_network *network)
153 struct wifi_data *data = connman_element_get_data(parent);
154 struct connman_element *element;
158 DBG("network %p identifier %s", network, network->identifier);
163 if (network->identifier == NULL)
166 if (network->identifier[0] == '\0')
169 temp = g_strdup(network->identifier);
171 for (i = 0; i < strlen(temp); i++) {
172 if (temp[i] == ' ' || temp[i] == '.' || temp[i] == '-')
174 if (temp[i] == '(' || temp[i] == ')')
176 if (g_ascii_isprint(temp[i]) == FALSE)
178 temp[i] = g_ascii_tolower(temp[i]);
181 g_static_mutex_lock(&data->mutex);
183 element = find_element(data, network->identifier);
184 if (element == NULL) {
185 element = connman_element_create(temp);
187 element->type = CONNMAN_ELEMENT_TYPE_NETWORK;
188 element->index = parent->index;
190 data->list = g_slist_append(data->list, element);
192 connman_element_add_static_property(element, "Identifier",
193 DBUS_TYPE_STRING, &network->identifier);
195 connman_element_add_static_array_property(element, "SSID",
196 DBUS_TYPE_BYTE, &network->ssid, network->ssid_len);
198 connman_element_register(element, parent);
201 g_static_mutex_unlock(&data->mutex);
206 static struct supplicant_callback wifi_callback = {
207 .state_change = state_change,
208 .scan_result = scan_result,
211 static int wifi_probe(struct connman_element *element)
213 struct wifi_data *data;
215 DBG("element %p name %s", element, element->name);
217 data = g_try_new0(struct wifi_data, 1);
221 g_static_mutex_init(&data->mutex);
223 connman_element_set_data(element, data);
228 static void wifi_remove(struct connman_element *element)
230 struct wifi_data *data = connman_element_get_data(element);
232 DBG("element %p name %s", element, element->name);
234 connman_element_set_data(element, NULL);
236 g_free(data->identifier);
240 static int wifi_update(struct connman_element *element)
242 DBG("element %p name %s", element, element->name);
244 __supplicant_scan(element);
249 static int wifi_enable(struct connman_element *element)
253 DBG("element %p name %s", element, element->name);
255 err = __supplicant_start(element, &wifi_callback);
259 __supplicant_scan(element);
264 static int wifi_disable(struct connman_element *element)
266 struct wifi_data *data = connman_element_get_data(element);
269 DBG("element %p name %s", element, element->name);
271 __supplicant_disconnect(element);
273 g_static_mutex_lock(&data->mutex);
275 for (list = data->list; list; list = list->next) {
276 struct connman_element *network = list->data;
278 connman_element_unref(network);
281 g_slist_free(data->list);
284 g_static_mutex_unlock(&data->mutex);
286 connman_element_unregister_children(element);
291 static struct connman_driver wifi_driver = {
292 .name = "wifi-device",
293 .type = CONNMAN_ELEMENT_TYPE_DEVICE,
294 .subtype = CONNMAN_ELEMENT_SUBTYPE_WIFI,
296 .remove = wifi_remove,
297 .update = wifi_update,
298 .enable = wifi_enable,
299 .disable = wifi_disable,
302 static int wifi_init(void)
306 err = __supplicant_init();
310 err = connman_driver_register(&network_driver);
316 err = connman_driver_register(&wifi_driver);
318 connman_driver_unregister(&network_driver);
326 static void wifi_exit(void)
328 connman_driver_unregister(&network_driver);
329 connman_driver_unregister(&wifi_driver);
334 CONNMAN_PLUGIN_DEFINE("wifi", "WiFi interface plugin", VERSION,
335 wifi_init, wifi_exit)