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
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
36 #include <net/route.h>
38 #include <linux/netlink.h>
39 #include <linux/rtnetlink.h>
44 #include <hal/libhal.h>
48 static DBusConnection *connection = NULL;
50 static GSList *drivers = NULL;
52 int connman_iface_register(struct connman_iface_driver *driver)
54 DBG("driver %p", driver);
56 drivers = g_slist_append(drivers, driver);
61 void connman_iface_unregister(struct connman_iface_driver *driver)
63 DBG("driver %p", driver);
65 drivers = g_slist_remove(drivers, driver);
68 static GSList *interfaces = NULL;
70 struct connman_iface *__connman_iface_find(int index)
74 for (list = interfaces; list; list = list->next) {
75 struct connman_iface *iface = list->data;
77 if (iface->index == index)
84 void __connman_iface_list(DBusMessageIter *iter)
90 for (list = interfaces; list; list = list->next) {
91 struct connman_iface *iface = list->data;
93 dbus_message_iter_append_basic(iter,
94 DBUS_TYPE_OBJECT_PATH, &iface->path);
98 int connman_iface_update(struct connman_iface *iface,
99 enum connman_iface_state state)
101 const char *str = NULL;
104 case CONNMAN_IFACE_STATE_ENABLED:
106 if (iface->type == CONNMAN_IFACE_TYPE_80211) {
107 if (iface->driver->connect)
108 iface->driver->connect(iface, NULL);
112 case CONNMAN_IFACE_STATE_CARRIER:
114 __connman_dhcp_request(iface);
117 case CONNMAN_IFACE_STATE_READY:
121 case CONNMAN_IFACE_STATE_SHUTDOWN:
128 iface->state = state;
131 g_dbus_emit_signal(connection, iface->path,
132 CONNMAN_IFACE_INTERFACE, "StateChanged",
133 DBUS_TYPE_STRING, &str, DBUS_TYPE_INVALID);
139 void connman_iface_indicate_carrier(struct connman_iface *iface, int carrier)
141 DBG("iface %p carrier %d", iface, carrier);
144 int connman_iface_get_ipv4(struct connman_iface *iface,
145 struct connman_ipv4 *ipv4)
152 if ((iface->flags & CONNMAN_IFACE_FLAG_RTNL) == 0)
155 DBG("iface %p ipv4 %p", iface, ipv4);
157 memset(&req, 0, sizeof(req));
158 req.hdr.nlmsg_len = sizeof(req.hdr) + sizeof(req.msg);
159 req.hdr.nlmsg_type = RTM_GETADDR;
160 req.hdr.nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP;
161 req.hdr.nlmsg_pid = 0;
162 req.hdr.nlmsg_seq = 4711;
163 req.msg.rtgen_family = AF_INET;
165 __connman_rtnl_send(&req, sizeof(req));
170 int connman_iface_set_ipv4(struct connman_iface *iface,
171 struct connman_ipv4 *ipv4)
175 struct sockaddr_in *addr;
179 if ((iface->flags & CONNMAN_IFACE_FLAG_RTNL) == 0)
182 DBG("iface %p ipv4 %p", iface, ipv4);
184 sk = socket(PF_INET, SOCK_DGRAM, 0);
188 memset(&ifr, 0, sizeof(ifr));
189 ifr.ifr_ifindex = iface->index;
191 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
196 DBG("ifname %s", ifr.ifr_name);
198 addr = (struct sockaddr_in *) &ifr.ifr_addr;
199 addr->sin_family = AF_INET;
200 addr->sin_addr = ipv4->address;
202 err = ioctl(sk, SIOCSIFADDR, &ifr);
205 DBG("address setting failed (%s)", strerror(errno));
207 addr = (struct sockaddr_in *) &ifr.ifr_netmask;
208 addr->sin_family = AF_INET;
209 addr->sin_addr = ipv4->netmask;
211 err = ioctl(sk, SIOCSIFNETMASK, &ifr);
214 DBG("netmask setting failed (%s)", strerror(errno));
216 addr = (struct sockaddr_in *) &ifr.ifr_broadaddr;
217 addr->sin_family = AF_INET;
218 addr->sin_addr = ipv4->broadcast;
220 err = ioctl(sk, SIOCSIFBRDADDR, &ifr);
223 DBG("broadcast setting failed (%s)", strerror(errno));
225 memset(&rt, 0, sizeof(rt));
226 rt.rt_flags = RTF_UP | RTF_GATEWAY;
228 addr = (struct sockaddr_in *) &rt.rt_dst;
229 addr->sin_family = AF_INET;
230 addr->sin_addr.s_addr = INADDR_ANY;
232 addr = (struct sockaddr_in *) &rt.rt_gateway;
233 addr->sin_family = AF_INET;
234 addr->sin_addr = ipv4->gateway;
236 addr = (struct sockaddr_in *) &rt.rt_genmask;
237 addr->sin_family = AF_INET;
238 addr->sin_addr.s_addr = INADDR_ANY;
240 err = ioctl(sk, SIOCADDRT, &rt);
245 DBG("default route failed (%s)", strerror(errno));
249 sprintf(cmd, "echo \"nameserver %s\" | resolvconf -a %s",
250 inet_ntoa(ipv4->nameserver), ifr.ifr_name);
259 int connman_iface_clear_ipv4(struct connman_iface *iface)
262 struct sockaddr_in *addr;
266 if ((iface->flags & CONNMAN_IFACE_FLAG_RTNL) == 0)
269 DBG("iface %p", iface);
271 sk = socket(PF_INET, SOCK_DGRAM, 0);
275 memset(&ifr, 0, sizeof(ifr));
276 ifr.ifr_ifindex = iface->index;
278 if (ioctl(sk, SIOCGIFNAME, &ifr) < 0) {
283 DBG("ifname %s", ifr.ifr_name);
285 addr = (struct sockaddr_in *) &ifr.ifr_addr;
286 addr->sin_family = AF_INET;
287 addr->sin_addr.s_addr = INADDR_ANY;
289 //err = ioctl(sk, SIOCDIFADDR, &ifr);
290 err = ioctl(sk, SIOCSIFADDR, &ifr);
294 if (err < 0 && errno != EADDRNOTAVAIL) {
295 DBG("address removal failed (%s)", strerror(errno));
299 sprintf(cmd, "resolvconf -d %s", ifr.ifr_name);
308 static DBusMessage *scan_iface(DBusConnection *conn,
309 DBusMessage *msg, void *data)
311 struct connman_iface *iface = data;
312 struct connman_iface_driver *driver = iface->driver;
315 DBG("conn %p", conn);
317 reply = dbus_message_new_method_return(msg);
324 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
329 static void append_entry(DBusMessageIter *dict,
330 const char *key, int type, void *val)
332 DBusMessageIter entry, value;
333 const char *signature;
335 dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY,
338 dbus_message_iter_append_basic(&entry, DBUS_TYPE_STRING, &key);
341 case DBUS_TYPE_STRING:
342 signature = DBUS_TYPE_STRING_AS_STRING;
344 case DBUS_TYPE_UINT16:
345 signature = DBUS_TYPE_UINT16_AS_STRING;
348 signature = DBUS_TYPE_VARIANT_AS_STRING;
352 dbus_message_iter_open_container(&entry, DBUS_TYPE_VARIANT,
354 dbus_message_iter_append_basic(&value, type, val);
355 dbus_message_iter_close_container(&entry, &value);
357 dbus_message_iter_close_container(dict, &entry);
360 static DBusMessage *get_properties(DBusConnection *conn,
361 DBusMessage *msg, void *data)
363 struct connman_iface *iface = data;
365 DBusMessageIter array, dict;
368 DBG("conn %p", conn);
370 reply = dbus_message_new_method_return(msg);
374 dbus_message_iter_init_append(reply, &array);
376 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
377 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
378 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
379 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
381 str = __connman_iface_type2string(iface->type);
382 append_entry(&dict, "Type", DBUS_TYPE_STRING, &str);
384 str = __connman_iface_state2string(iface->state);
385 append_entry(&dict, "State", DBUS_TYPE_STRING, &str);
387 if (iface->type == CONNMAN_IFACE_TYPE_80211) {
388 dbus_uint16_t signal = 75;
389 append_entry(&dict, "Signal", DBUS_TYPE_UINT16, &signal);
392 str = __connman_iface_policy2string(iface->policy);
393 append_entry(&dict, "Policy", DBUS_TYPE_STRING, &str);
395 if (iface->device.driver != NULL)
396 append_entry(&dict, "Driver",
397 DBUS_TYPE_STRING, &iface->device.driver);
399 if (iface->device.vendor != NULL)
400 append_entry(&dict, "Vendor",
401 DBUS_TYPE_STRING, &iface->device.vendor);
403 if (iface->device.product != NULL)
404 append_entry(&dict, "Product",
405 DBUS_TYPE_STRING, &iface->device.product);
407 dbus_message_iter_close_container(&array, &dict);
412 static DBusMessage *get_state(DBusConnection *conn,
413 DBusMessage *msg, void *data)
415 struct connman_iface *iface = data;
419 DBG("conn %p", conn);
421 reply = dbus_message_new_method_return(msg);
425 state = __connman_iface_state2string(iface->state);
427 dbus_message_append_args(reply, DBUS_TYPE_STRING, &state,
433 static DBusMessage *get_signal(DBusConnection *conn,
434 DBusMessage *msg, void *data)
436 struct connman_iface *iface = data;
438 dbus_uint16_t signal;
440 DBG("conn %p", conn);
442 reply = dbus_message_new_method_return(msg);
446 if (iface->type == CONNMAN_IFACE_TYPE_80211)
451 dbus_message_append_args(reply, DBUS_TYPE_UINT16, &signal,
457 static DBusMessage *get_policy(DBusConnection *conn,
458 DBusMessage *msg, void *data)
460 struct connman_iface *iface = data;
464 DBG("conn %p", conn);
466 reply = dbus_message_new_method_return(msg);
470 policy = __connman_iface_policy2string(iface->policy);
472 dbus_message_append_args(reply, DBUS_TYPE_STRING, &policy,
478 static DBusMessage *set_policy(DBusConnection *conn,
479 DBusMessage *msg, void *data)
481 struct connman_iface *iface = data;
483 enum connman_iface_policy new_policy;
484 const char *path, *policy;
486 DBG("conn %p", conn);
488 dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &policy,
491 new_policy = __connman_iface_string2policy(policy);
493 reply = dbus_message_new_method_return(msg);
497 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
499 if (iface->policy != new_policy) {
500 path = dbus_message_get_path(msg);
502 iface->policy = new_policy;
503 __connman_iface_store(iface);
505 if (new_policy == CONNMAN_IFACE_POLICY_AUTO) {
506 if (iface->driver->activate)
507 iface->driver->activate(iface);
509 if (iface->driver->shutdown)
510 iface->driver->shutdown(iface);
513 g_dbus_emit_signal(conn, path, CONNMAN_IFACE_INTERFACE,
514 "PolicyChanged", DBUS_TYPE_STRING, &policy,
521 static void append_ipv4(DBusMessage *reply, struct connman_iface *iface)
523 DBusMessageIter array, dict;
526 dbus_message_iter_init_append(reply, &array);
528 dbus_message_iter_open_container(&array, DBUS_TYPE_ARRAY,
529 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
530 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
531 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
533 str = __connman_ipv4_method2string(iface->ipv4.method);
534 append_entry(&dict, "Method", DBUS_TYPE_STRING, &str);
536 if (iface->ipv4.address.s_addr != INADDR_ANY) {
537 str = inet_ntoa(iface->ipv4.address);
538 append_entry(&dict, "Address", DBUS_TYPE_STRING, &str);
541 if (iface->ipv4.netmask.s_addr != INADDR_ANY) {
542 str = inet_ntoa(iface->ipv4.netmask);
543 append_entry(&dict, "Netmask", DBUS_TYPE_STRING, &str);
546 if (iface->ipv4.gateway.s_addr != INADDR_ANY) {
547 str = inet_ntoa(iface->ipv4.gateway);
548 append_entry(&dict, "Gateway", DBUS_TYPE_STRING, &str);
551 dbus_message_iter_close_container(&array, &dict);
554 static DBusMessage *get_ipv4(DBusConnection *conn,
555 DBusMessage *msg, void *data)
557 struct connman_iface *iface = data;
560 DBG("conn %p", conn);
562 reply = dbus_message_new_method_return(msg);
566 append_ipv4(reply, iface);
571 static DBusMessage *set_ipv4(DBusConnection *conn,
572 DBusMessage *msg, void *data)
574 struct connman_iface *iface = data;
575 DBusMessage *reply, *signal;
576 DBusMessageIter array, dict;
578 gboolean changed = FALSE;
580 DBG("conn %p", conn);
582 dbus_message_iter_init(msg, &array);
584 dbus_message_iter_recurse(&array, &dict);
586 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
587 DBusMessageIter entry, value;
588 const char *key, *val;
589 enum connman_ipv4_method method;
592 dbus_message_iter_recurse(&dict, &entry);
593 dbus_message_iter_get_basic(&entry, &key);
595 dbus_message_iter_next(&entry);
597 dbus_message_iter_recurse(&entry, &value);
599 //type = dbus_message_iter_get_arg_type(&value);
600 dbus_message_iter_get_basic(&value, &val);
602 if (g_strcasecmp(key, "Method") == 0) {
603 method = __connman_ipv4_string2method(val);
604 if (iface->ipv4.method != method) {
605 iface->ipv4.method = method;
610 if (g_strcasecmp(key, "Address") == 0) {
611 addr = inet_addr(val);
612 if (iface->ipv4.address.s_addr != addr) {
613 iface->ipv4.address.s_addr = addr;
618 if (g_strcasecmp(key, "Netmask") == 0) {
619 addr = inet_addr(val);
620 if (iface->ipv4.netmask.s_addr != addr) {
621 iface->ipv4.netmask.s_addr = addr;
626 if (g_strcasecmp(key, "Gateway") == 0) {
627 addr = inet_addr(val);
628 if (iface->ipv4.gateway.s_addr != addr) {
629 iface->ipv4.gateway.s_addr = addr;
634 dbus_message_iter_next(&dict);
637 reply = dbus_message_new_method_return(msg);
641 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
643 path = dbus_message_get_path(msg);
645 if (changed == TRUE) {
646 __connman_iface_store(iface);
648 signal = dbus_message_new_signal(path,
649 CONNMAN_IFACE_INTERFACE, "IPv4Changed");
650 if (signal != NULL) {
651 append_ipv4(signal, iface);
652 dbus_connection_send(conn, signal, NULL);
653 dbus_message_unref(signal);
660 static DBusMessage *set_network(DBusConnection *conn,
661 DBusMessage *msg, void *data)
663 struct connman_iface *iface = data;
665 DBusMessageIter array, dict;
667 DBG("conn %p", conn);
669 dbus_message_iter_init(msg, &array);
671 dbus_message_iter_recurse(&array, &dict);
673 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
674 DBusMessageIter entry, value;
675 const char *key, *val;
677 dbus_message_iter_recurse(&dict, &entry);
678 dbus_message_iter_get_basic(&entry, &key);
680 dbus_message_iter_next(&entry);
682 dbus_message_iter_recurse(&entry, &value);
684 //type = dbus_message_iter_get_arg_type(&value);
685 dbus_message_iter_get_basic(&value, &val);
687 if (g_strcasecmp(key, "ESSID") == 0) {
688 if (iface->driver->set_network)
689 iface->driver->set_network(iface, val);
692 if (g_strcasecmp(key, "PSK") == 0) {
693 if (iface->driver->set_network)
694 iface->driver->set_passphrase(iface, val);
697 dbus_message_iter_next(&dict);
700 reply = dbus_message_new_method_return(msg);
704 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
709 static GDBusMethodTable iface_methods[] = {
710 { "Scan", "", "", scan_iface },
711 { "GetProperties", "", "a{sv}", get_properties },
712 { "GetState", "", "s", get_state },
713 { "GetSignal", "", "q", get_signal },
714 { "GetPolicy", "", "s", get_policy },
715 { "SetPolicy", "s", "", set_policy },
716 { "GetIPv4", "", "a{sv}", get_ipv4 },
717 { "SetIPv4", "a{sv}", "", set_ipv4 },
718 { "SetNetwork", "a{sv}", "", set_network },
722 static GDBusSignalTable iface_signals[] = {
723 { "StateChanged", "s" },
724 { "SignalChanged", "q" },
725 { "PolicyChanged", "s" },
726 { "IPv4Changed", "a{sv}" },
727 { "NetworkChanged", "a{sv}" },
731 static void device_free(void *data)
733 struct connman_iface *iface = data;
735 DBG("iface %p", iface);
737 connman_iface_clear_ipv4(iface);
739 if (iface->driver && iface->driver->remove)
740 iface->driver->remove(iface);
744 g_free(iface->sysfs);
745 g_free(iface->identifier);
746 g_free(iface->device.driver);
747 g_free(iface->device.vendor);
748 g_free(iface->device.product);
752 static void detect_device_info(LibHalContext *ctx, struct connman_iface *iface)
754 char *parent, *subsys, *value;
756 parent = libhal_device_get_property_string(ctx, iface->udi,
757 "info.parent", NULL);
759 subsys = libhal_device_get_property_string(ctx, iface->udi,
760 "linux.subsystem", NULL);
762 value = libhal_device_get_property_string(ctx, iface->udi,
763 "info.linux.driver", NULL);
765 value = libhal_device_get_property_string(ctx, parent,
766 "info.linux.driver", NULL);
768 iface->device.driver = g_strdup(value);
771 if (strcmp(subsys, "net") == 0) {
772 value = libhal_device_get_property_string(ctx, parent,
773 "info.vendor", NULL);
775 iface->device.vendor = g_strdup(value);
777 value = libhal_device_get_property_string(ctx, parent,
778 "info.product", NULL);
780 iface->device.product = g_strdup(value);
784 static int probe_device(LibHalContext *ctx,
785 struct connman_iface_driver *driver, const char *udi)
787 DBusConnection *conn;
788 struct connman_iface *iface;
792 DBG("ctx %p driver %p udi %s", ctx, driver, udi);
797 iface = g_try_new0(struct connman_iface, 1);
801 temp = g_path_get_basename(udi);
802 iface->path = g_strdup_printf("%s/%s", CONNMAN_IFACE_BASEPATH, temp);
805 iface->udi = g_strdup(udi);
807 DBG("iface %p path %s", iface, iface->path);
809 sysfs = libhal_device_get_property_string(ctx, udi,
810 "linux.sysfs_path", NULL);
812 iface->sysfs = g_strdup(sysfs);
814 detect_device_info(ctx, iface);
818 if (g_str_has_prefix(driver->capability, "net") == TRUE)
819 iface->index = libhal_device_get_property_int(ctx, udi,
820 "net.linux.ifindex", NULL);
822 iface->type = CONNMAN_IFACE_TYPE_UNKNOWN;
824 iface->state = CONNMAN_IFACE_STATE_UNKNOWN;
825 iface->policy = CONNMAN_IFACE_POLICY_UNKNOWN;
827 err = driver->probe(iface);
833 __connman_iface_create_identifier(iface);
835 __connman_iface_init_via_inet(iface);
837 __connman_iface_load(iface);
839 iface->driver = driver;
841 conn = libhal_ctx_get_dbus_connection(ctx);
843 g_dbus_register_object(conn, iface->path, iface, device_free);
845 interfaces = g_slist_append(interfaces, iface);
847 if (iface->flags & CONNMAN_IFACE_FLAG_IPV4) {
848 if (driver->get_ipv4)
849 driver->get_ipv4(iface, &iface->ipv4);
851 connman_iface_get_ipv4(iface, &iface->ipv4);
853 DBG("address %s", inet_ntoa(iface->ipv4.address));
856 g_dbus_register_interface(conn, iface->path,
857 CONNMAN_IFACE_INTERFACE,
858 iface_methods, iface_signals, NULL);
860 DBG("iface %p identifier %s", iface, iface->identifier);
862 g_dbus_emit_signal(conn, CONNMAN_MANAGER_PATH,
863 CONNMAN_MANAGER_INTERFACE,
865 DBUS_TYPE_OBJECT_PATH, &iface->path,
868 if (iface->policy == CONNMAN_IFACE_POLICY_AUTO) {
869 if (driver->activate)
870 driver->activate(iface);
876 static void device_added(LibHalContext *ctx, const char *udi)
880 DBG("ctx %p udi %s", ctx, udi);
882 for (list = drivers; list; list = list->next) {
883 struct connman_iface_driver *driver = list->data;
885 if (driver->capability == NULL)
888 if (libhal_device_query_capability(ctx, udi,
889 driver->capability, NULL) == TRUE) {
890 if (probe_device(ctx, driver, udi) == 0)
896 static void device_removed(LibHalContext *ctx, const char *udi)
898 DBusConnection *conn;
901 DBG("ctx %p udi %s", ctx, udi);
903 conn = libhal_ctx_get_dbus_connection(ctx);
905 for (list = interfaces; list; list = list->next) {
906 struct connman_iface *iface = list->data;
908 if (strcmp(udi, iface->udi) == 0) {
909 g_dbus_emit_signal(conn, CONNMAN_MANAGER_PATH,
910 CONNMAN_MANAGER_INTERFACE,
912 DBUS_TYPE_OBJECT_PATH, &iface->path,
914 interfaces = g_slist_remove(interfaces, iface);
915 g_dbus_unregister_interface(conn, iface->path,
916 CONNMAN_IFACE_INTERFACE);
917 g_dbus_unregister_object(conn, iface->path);
923 static void probe_driver(LibHalContext *ctx,
924 struct connman_iface_driver *driver)
929 DBG("ctx %p driver %p", ctx, driver);
931 list = libhal_find_device_by_capability(ctx,
932 driver->capability, &num, NULL);
937 probe_device(ctx, driver, *tmp);
941 libhal_free_string_array(list);
945 static void find_devices(LibHalContext *ctx)
951 for (list = drivers; list; list = list->next) {
952 struct connman_iface_driver *driver = list->data;
954 DBG("driver %p", driver);
956 if (driver->capability == NULL)
959 probe_driver(ctx, driver);
963 static LibHalContext *hal_ctx = NULL;
965 static void hal_init(void *data)
967 DBusConnection *conn = data;
969 DBG("conn %p", conn);
974 hal_ctx = libhal_ctx_new();
978 if (libhal_ctx_set_dbus_connection(hal_ctx, conn) == FALSE) {
979 libhal_ctx_free(hal_ctx);
983 if (libhal_ctx_init(hal_ctx, NULL) == FALSE) {
984 libhal_ctx_free(hal_ctx);
988 libhal_ctx_set_device_added(hal_ctx, device_added);
989 libhal_ctx_set_device_removed(hal_ctx, device_removed);
991 //libhal_ctx_set_device_new_capability(hal_ctx, new_capability);
992 //libhal_ctx_set_device_lost_capability(hal_ctx, lost_capability);
994 find_devices(hal_ctx);
997 static void hal_cleanup(void *data)
999 DBusConnection *conn = data;
1002 DBG("conn %p", conn);
1004 if (hal_ctx == NULL)
1007 for (list = interfaces; list; list = list->next) {
1008 struct connman_iface *iface = list->data;
1010 DBG("path %s", iface->path);
1012 g_dbus_emit_signal(conn, CONNMAN_MANAGER_PATH,
1013 CONNMAN_MANAGER_INTERFACE,
1015 DBUS_TYPE_OBJECT_PATH, &iface->path,
1018 g_dbus_unregister_interface(conn, iface->path,
1019 CONNMAN_IFACE_INTERFACE);
1021 g_dbus_unregister_object(conn, iface->path);
1024 g_slist_free(interfaces);
1028 libhal_ctx_shutdown(hal_ctx, NULL);
1030 libhal_ctx_free(hal_ctx);
1035 static guint hal_watch = 0;
1037 int __connman_iface_init(DBusConnection *conn)
1039 DBG("conn %p", conn);
1041 connection = dbus_connection_ref(conn);
1042 if (connection == NULL)
1045 hal_init(connection);
1047 hal_watch = g_dbus_add_watch(connection, "org.freedesktop.Hal",
1048 hal_init, hal_cleanup, connection, NULL);
1053 void __connman_iface_cleanup(void)
1055 DBG("conn %p", connection);
1057 g_dbus_remove_watch(connection, hal_watch);
1059 hal_cleanup(connection);
1061 dbus_connection_unref(connection);