5 * Copyright (C) 2007 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 <arpa/inet.h>
32 #include <hal/libhal.h>
36 static GSList *drivers = NULL;
38 int connman_iface_register(struct connman_iface_driver *driver)
40 DBG("driver %p", driver);
42 drivers = g_slist_append(drivers, driver);
47 void connman_iface_unregister(struct connman_iface_driver *driver)
49 DBG("driver %p", driver);
51 drivers = g_slist_remove(drivers, driver);
54 static GSList *interfaces = NULL;
56 int connman_iface_update(struct connman_iface *iface,
57 enum connman_iface_state state)
60 case CONNMAN_IFACE_STATE_ACTIVE:
61 if (iface->type == CONNMAN_IFACE_TYPE_80211) {
62 if (iface->driver->scan)
63 iface->driver->scan(iface);
65 if (iface->driver->connect)
66 iface->driver->connect(iface, NULL);
70 case CONNMAN_IFACE_STATE_CONNECTED:
71 __connman_dhcp_request(iface);
83 static void device_free(void *data)
85 struct connman_iface *iface = data;
87 DBG("iface %p", iface);
89 if (iface->driver && iface->driver->remove)
90 iface->driver->remove(iface);
98 static int probe_device(LibHalContext *ctx,
99 struct connman_iface_driver *driver, const char *udi)
101 DBusConnection *conn;
102 struct connman_iface *iface;
106 DBG("ctx %p driver %p udi %s", ctx, driver, udi);
111 iface = g_try_new0(struct connman_iface, 1);
115 temp = g_path_get_basename(udi);
116 iface->path = g_strdup_printf("%s/%s", CONNMAN_IFACE_BASEPATH, temp);
119 iface->udi = g_strdup(udi);
121 DBG("path %s", iface->path);
123 sysfs = libhal_device_get_property_string(ctx, udi,
124 "linux.sysfs_path", NULL);
126 iface->sysfs = g_strdup(sysfs);
130 if (g_str_has_prefix(driver->capability, "net") == TRUE)
131 iface->index = libhal_device_get_property_int(ctx, udi,
132 "net.linux.ifindex", NULL);
134 iface->type = CONNMAN_IFACE_TYPE_UNKNOWN;
136 iface->state = CONNMAN_IFACE_STATE_UNKNOWN;
138 DBG("iface %p", iface);
140 err = driver->probe(iface);
146 iface->driver = driver;
148 conn = libhal_ctx_get_dbus_connection(ctx);
150 g_dbus_register_object(conn, iface->path, iface, device_free);
152 interfaces = g_slist_append(interfaces, iface);
154 if ((iface->flags & CONNMAN_IFACE_FLAG_IPV4) &&
156 driver->get_ipv4(iface, &iface->ipv4);
158 DBG("address %s", inet_ntoa(iface->ipv4.address));
161 if (driver->activate)
162 driver->activate(iface);
167 static void device_added(LibHalContext *ctx, const char *udi)
171 DBG("ctx %p udi %s", ctx, udi);
173 for (list = drivers; list; list = list->next) {
174 struct connman_iface_driver *driver = list->data;
176 if (driver->capability == NULL)
179 if (libhal_device_query_capability(ctx, udi,
180 driver->capability, NULL) == TRUE) {
181 if (probe_device(ctx, driver, udi) == 0)
187 static void device_removed(LibHalContext *ctx, const char *udi)
189 DBusConnection *conn;
192 DBG("ctx %p udi %s", ctx, udi);
194 conn = libhal_ctx_get_dbus_connection(ctx);
196 for (list = interfaces; list; list = list->next) {
197 struct connman_iface *iface = list->data;
199 if (strcmp(udi, iface->udi) == 0) {
200 interfaces = g_slist_remove(interfaces, iface);
201 g_dbus_unregister_object(conn, iface->path);
207 static void probe_driver(LibHalContext *ctx,
208 struct connman_iface_driver *driver)
213 DBG("ctx %p driver %p", ctx, driver);
215 list = libhal_find_device_by_capability(ctx,
216 driver->capability, &num, NULL);
221 probe_device(ctx, driver, *tmp);
225 libhal_free_string_array(list);
229 static void find_devices(LibHalContext *ctx)
235 for (list = drivers; list; list = list->next) {
236 struct connman_iface_driver *driver = list->data;
238 DBG("driver %p", driver);
240 if (driver->capability == NULL)
243 probe_driver(ctx, driver);
247 static LibHalContext *hal_ctx = NULL;
249 static void hal_init(void *data)
251 DBusConnection *conn = data;
253 DBG("conn %p", conn);
258 hal_ctx = libhal_ctx_new();
262 if (libhal_ctx_set_dbus_connection(hal_ctx, conn) == FALSE) {
263 libhal_ctx_free(hal_ctx);
267 if (libhal_ctx_init(hal_ctx, NULL) == FALSE) {
268 libhal_ctx_free(hal_ctx);
272 libhal_ctx_set_device_added(hal_ctx, device_added);
273 libhal_ctx_set_device_removed(hal_ctx, device_removed);
275 //libhal_ctx_set_device_new_capability(hal_ctx, new_capability);
276 //libhal_ctx_set_device_lost_capability(hal_ctx, lost_capability);
278 find_devices(hal_ctx);
281 static void hal_cleanup(void *data)
283 DBusConnection *conn = data;
286 DBG("conn %p", conn);
291 for (list = interfaces; list; list = list->next) {
292 struct connman_iface *iface = list->data;
294 DBG("path %s", iface->path);
296 g_dbus_unregister_object(conn, iface->path);
299 g_slist_free(interfaces);
303 libhal_ctx_shutdown(hal_ctx, NULL);
305 libhal_ctx_free(hal_ctx);
310 static DBusConnection *connection = NULL;
311 static guint hal_watch = 0;
313 int __connman_iface_init(DBusConnection *conn)
315 DBG("conn %p", conn);
317 connection = dbus_connection_ref(conn);
318 if (connection == NULL)
321 hal_init(connection);
323 hal_watch = g_dbus_add_watch(connection, "org.freedesktop.Hal",
324 hal_init, hal_cleanup, connection, NULL);
329 void __connman_iface_cleanup(void)
331 DBG("conn %p", connection);
333 g_dbus_remove_watch(connection, hal_watch);
335 hal_cleanup(connection);
337 dbus_connection_unref(connection);