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 static void device_free(void *data)
58 struct connman_iface *iface = data;
60 DBG("iface %p", iface);
62 if (iface->driver && iface->driver->remove)
63 iface->driver->remove(iface);
71 static int probe_device(LibHalContext *ctx,
72 struct connman_iface_driver *driver, const char *udi)
75 struct connman_iface *iface;
79 DBG("ctx %p driver %p udi %s", ctx, driver, udi);
84 iface = g_try_new0(struct connman_iface, 1);
88 temp = g_path_get_basename(udi);
89 iface->path = g_strdup_printf("%s/%s", CONNMAN_IFACE_BASEPATH, temp);
92 iface->udi = g_strdup(udi);
94 DBG("path %s", iface->path);
96 sysfs = libhal_device_get_property_string(ctx, udi,
97 "linux.sysfs_path", NULL);
99 iface->sysfs = g_strdup(sysfs);
101 iface->type = CONNMAN_IFACE_TYPE_UNKNOWN;
104 DBG("iface %p", iface);
106 err = driver->probe(iface);
112 iface->driver = driver;
114 conn = libhal_ctx_get_dbus_connection(ctx);
116 g_dbus_register_object(conn, iface->path, iface, device_free);
118 interfaces = g_slist_append(interfaces, iface);
120 if ((iface->flags & CONNMAN_IFACE_FLAG_IPV4) &&
122 driver->get_ipv4(iface, &iface->ipv4);
124 DBG("address %s", inet_ntoa(iface->ipv4.address));
130 static void device_added(LibHalContext *ctx, const char *udi)
134 DBG("ctx %p udi %s", ctx, udi);
136 for (list = drivers; list; list = list->next) {
137 struct connman_iface_driver *driver = list->data;
139 if (driver->capability == NULL)
142 if (libhal_device_query_capability(ctx, udi,
143 driver->capability, NULL) == TRUE) {
144 if (probe_device(ctx, driver, udi) == 0)
150 static void device_removed(LibHalContext *ctx, const char *udi)
152 DBusConnection *conn;
155 DBG("ctx %p udi %s", ctx, udi);
157 conn = libhal_ctx_get_dbus_connection(ctx);
159 for (list = interfaces; list; list = list->next) {
160 struct connman_iface *iface = list->data;
162 if (strcmp(udi, iface->udi) == 0) {
163 interfaces = g_slist_remove(interfaces, iface);
164 g_dbus_unregister_object(conn, iface->path);
170 static void probe_driver(LibHalContext *ctx,
171 struct connman_iface_driver *driver)
176 DBG("ctx %p driver %p", ctx, driver);
178 list = libhal_find_device_by_capability(ctx,
179 driver->capability, &num, NULL);
184 probe_device(ctx, driver, *tmp);
188 libhal_free_string_array(list);
192 static void find_devices(LibHalContext *ctx)
198 for (list = drivers; list; list = list->next) {
199 struct connman_iface_driver *driver = list->data;
201 DBG("driver %p", driver);
203 if (driver->capability == NULL)
206 probe_driver(ctx, driver);
210 static LibHalContext *hal_ctx = NULL;
212 static void hal_init(void *data)
214 DBusConnection *conn = data;
216 DBG("conn %p", conn);
221 hal_ctx = libhal_ctx_new();
225 if (libhal_ctx_set_dbus_connection(hal_ctx, conn) == FALSE) {
226 libhal_ctx_free(hal_ctx);
230 if (libhal_ctx_init(hal_ctx, NULL) == FALSE) {
231 libhal_ctx_free(hal_ctx);
235 libhal_ctx_set_device_added(hal_ctx, device_added);
236 libhal_ctx_set_device_removed(hal_ctx, device_removed);
238 //libhal_ctx_set_device_new_capability(hal_ctx, new_capability);
239 //libhal_ctx_set_device_lost_capability(hal_ctx, lost_capability);
241 find_devices(hal_ctx);
244 static void hal_cleanup(void *data)
246 DBusConnection *conn = data;
249 DBG("conn %p", conn);
254 for (list = interfaces; list; list = list->next) {
255 struct connman_iface *iface = list->data;
257 DBG("path %s", iface->path);
259 g_dbus_unregister_object(conn, iface->path);
262 g_slist_free(interfaces);
266 libhal_ctx_shutdown(hal_ctx, NULL);
268 libhal_ctx_free(hal_ctx);
273 static DBusConnection *connection = NULL;
274 static guint hal_watch = 0;
276 int __connman_iface_init(DBusConnection *conn)
278 DBG("conn %p", conn);
280 connection = dbus_connection_ref(conn);
281 if (connection == NULL)
284 hal_init(connection);
286 hal_watch = g_dbus_add_watch(connection, "org.freedesktop.Hal",
287 hal_init, hal_cleanup, connection, NULL);
292 void __connman_iface_cleanup(void)
294 DBG("conn %p", connection);
296 g_dbus_remove_watch(connection, hal_watch);
298 hal_cleanup(connection);
300 dbus_connection_unref(connection);