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;
666 gboolean changed = FALSE;
668 DBG("conn %p", conn);
670 dbus_message_iter_init(msg, &array);
672 dbus_message_iter_recurse(&array, &dict);
674 while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
675 DBusMessageIter entry, value;
676 const char *key, *val;
678 dbus_message_iter_recurse(&dict, &entry);
679 dbus_message_iter_get_basic(&entry, &key);
681 dbus_message_iter_next(&entry);
683 dbus_message_iter_recurse(&entry, &value);
685 //type = dbus_message_iter_get_arg_type(&value);
686 dbus_message_iter_get_basic(&value, &val);
688 if (g_strcasecmp(key, "ESSID") == 0) {
689 g_free(iface->network.essid);
690 iface->network.essid = g_strdup(val);
691 if (iface->driver->set_network)
692 iface->driver->set_network(iface, val);
696 if (g_strcasecmp(key, "PSK") == 0) {
697 if (iface->driver->set_network)
698 iface->driver->set_passphrase(iface, val);
701 dbus_message_iter_next(&dict);
704 reply = dbus_message_new_method_return(msg);
708 dbus_message_append_args(reply, DBUS_TYPE_INVALID);
711 __connman_iface_store(iface);
716 static GDBusMethodTable iface_methods[] = {
717 { "Scan", "", "", scan_iface },
718 { "GetProperties", "", "a{sv}", get_properties },
719 { "GetState", "", "s", get_state },
720 { "GetSignal", "", "q", get_signal },
721 { "GetPolicy", "", "s", get_policy },
722 { "SetPolicy", "s", "", set_policy },
723 { "GetIPv4", "", "a{sv}", get_ipv4 },
724 { "SetIPv4", "a{sv}", "", set_ipv4 },
725 { "SetNetwork", "a{sv}", "", set_network },
729 static GDBusSignalTable iface_signals[] = {
730 { "StateChanged", "s" },
731 { "SignalChanged", "q" },
732 { "PolicyChanged", "s" },
733 { "IPv4Changed", "a{sv}" },
734 { "NetworkChanged", "a{sv}" },
738 static void device_free(void *data)
740 struct connman_iface *iface = data;
742 DBG("iface %p", iface);
744 connman_iface_clear_ipv4(iface);
746 if (iface->driver && iface->driver->remove)
747 iface->driver->remove(iface);
751 g_free(iface->sysfs);
752 g_free(iface->identifier);
753 g_free(iface->network.essid);
754 g_free(iface->device.driver);
755 g_free(iface->device.vendor);
756 g_free(iface->device.product);
760 static void detect_device_info(LibHalContext *ctx, struct connman_iface *iface)
762 char *parent, *subsys, *value;
764 parent = libhal_device_get_property_string(ctx, iface->udi,
765 "info.parent", NULL);
767 subsys = libhal_device_get_property_string(ctx, iface->udi,
768 "linux.subsystem", NULL);
770 value = libhal_device_get_property_string(ctx, iface->udi,
771 "info.linux.driver", NULL);
773 value = libhal_device_get_property_string(ctx, parent,
774 "info.linux.driver", NULL);
776 iface->device.driver = g_strdup(value);
779 if (strcmp(subsys, "net") == 0) {
780 value = libhal_device_get_property_string(ctx, parent,
781 "info.vendor", NULL);
783 iface->device.vendor = g_strdup(value);
785 value = libhal_device_get_property_string(ctx, parent,
786 "info.product", NULL);
788 iface->device.product = g_strdup(value);
792 static int probe_device(LibHalContext *ctx,
793 struct connman_iface_driver *driver, const char *udi)
795 DBusConnection *conn;
796 struct connman_iface *iface;
800 DBG("ctx %p driver %p udi %s", ctx, driver, udi);
805 iface = g_try_new0(struct connman_iface, 1);
809 temp = g_path_get_basename(udi);
810 iface->path = g_strdup_printf("%s/%s", CONNMAN_IFACE_BASEPATH, temp);
813 iface->udi = g_strdup(udi);
815 DBG("iface %p path %s", iface, iface->path);
817 sysfs = libhal_device_get_property_string(ctx, udi,
818 "linux.sysfs_path", NULL);
820 iface->sysfs = g_strdup(sysfs);
822 detect_device_info(ctx, iface);
826 if (g_str_has_prefix(driver->capability, "net") == TRUE)
827 iface->index = libhal_device_get_property_int(ctx, udi,
828 "net.linux.ifindex", NULL);
830 iface->type = CONNMAN_IFACE_TYPE_UNKNOWN;
832 iface->state = CONNMAN_IFACE_STATE_UNKNOWN;
833 iface->policy = CONNMAN_IFACE_POLICY_UNKNOWN;
835 err = driver->probe(iface);
841 __connman_iface_create_identifier(iface);
843 __connman_iface_init_via_inet(iface);
845 iface->driver = driver;
847 __connman_iface_load(iface);
849 conn = libhal_ctx_get_dbus_connection(ctx);
851 g_dbus_register_object(conn, iface->path, iface, device_free);
853 interfaces = g_slist_append(interfaces, iface);
855 if (iface->flags & CONNMAN_IFACE_FLAG_IPV4) {
856 if (driver->get_ipv4)
857 driver->get_ipv4(iface, &iface->ipv4);
859 connman_iface_get_ipv4(iface, &iface->ipv4);
861 DBG("address %s", inet_ntoa(iface->ipv4.address));
864 g_dbus_register_interface(conn, iface->path,
865 CONNMAN_IFACE_INTERFACE,
866 iface_methods, iface_signals, NULL);
868 DBG("iface %p identifier %s", iface, iface->identifier);
870 g_dbus_emit_signal(conn, CONNMAN_MANAGER_PATH,
871 CONNMAN_MANAGER_INTERFACE,
873 DBUS_TYPE_OBJECT_PATH, &iface->path,
876 if (iface->policy == CONNMAN_IFACE_POLICY_AUTO) {
877 if (driver->activate)
878 driver->activate(iface);
884 static void device_added(LibHalContext *ctx, const char *udi)
888 DBG("ctx %p udi %s", ctx, udi);
890 for (list = drivers; list; list = list->next) {
891 struct connman_iface_driver *driver = list->data;
893 if (driver->capability == NULL)
896 if (libhal_device_query_capability(ctx, udi,
897 driver->capability, NULL) == TRUE) {
898 if (probe_device(ctx, driver, udi) == 0)
904 static void device_removed(LibHalContext *ctx, const char *udi)
906 DBusConnection *conn;
909 DBG("ctx %p udi %s", ctx, udi);
911 conn = libhal_ctx_get_dbus_connection(ctx);
913 for (list = interfaces; list; list = list->next) {
914 struct connman_iface *iface = list->data;
916 if (strcmp(udi, iface->udi) == 0) {
917 g_dbus_emit_signal(conn, CONNMAN_MANAGER_PATH,
918 CONNMAN_MANAGER_INTERFACE,
920 DBUS_TYPE_OBJECT_PATH, &iface->path,
922 interfaces = g_slist_remove(interfaces, iface);
923 g_dbus_unregister_interface(conn, iface->path,
924 CONNMAN_IFACE_INTERFACE);
925 g_dbus_unregister_object(conn, iface->path);
931 static void probe_driver(LibHalContext *ctx,
932 struct connman_iface_driver *driver)
937 DBG("ctx %p driver %p", ctx, driver);
939 list = libhal_find_device_by_capability(ctx,
940 driver->capability, &num, NULL);
945 probe_device(ctx, driver, *tmp);
949 libhal_free_string_array(list);
953 static void find_devices(LibHalContext *ctx)
959 for (list = drivers; list; list = list->next) {
960 struct connman_iface_driver *driver = list->data;
962 DBG("driver %p", driver);
964 if (driver->capability == NULL)
967 probe_driver(ctx, driver);
971 static LibHalContext *hal_ctx = NULL;
973 static void hal_init(void *data)
975 DBusConnection *conn = data;
977 DBG("conn %p", conn);
982 hal_ctx = libhal_ctx_new();
986 if (libhal_ctx_set_dbus_connection(hal_ctx, conn) == FALSE) {
987 libhal_ctx_free(hal_ctx);
991 if (libhal_ctx_init(hal_ctx, NULL) == FALSE) {
992 libhal_ctx_free(hal_ctx);
996 libhal_ctx_set_device_added(hal_ctx, device_added);
997 libhal_ctx_set_device_removed(hal_ctx, device_removed);
999 //libhal_ctx_set_device_new_capability(hal_ctx, new_capability);
1000 //libhal_ctx_set_device_lost_capability(hal_ctx, lost_capability);
1002 find_devices(hal_ctx);
1005 static void hal_cleanup(void *data)
1007 DBusConnection *conn = data;
1010 DBG("conn %p", conn);
1012 if (hal_ctx == NULL)
1015 for (list = interfaces; list; list = list->next) {
1016 struct connman_iface *iface = list->data;
1018 DBG("path %s", iface->path);
1020 g_dbus_emit_signal(conn, CONNMAN_MANAGER_PATH,
1021 CONNMAN_MANAGER_INTERFACE,
1023 DBUS_TYPE_OBJECT_PATH, &iface->path,
1026 g_dbus_unregister_interface(conn, iface->path,
1027 CONNMAN_IFACE_INTERFACE);
1029 g_dbus_unregister_object(conn, iface->path);
1032 g_slist_free(interfaces);
1036 libhal_ctx_shutdown(hal_ctx, NULL);
1038 libhal_ctx_free(hal_ctx);
1043 static guint hal_watch = 0;
1045 int __connman_iface_init(DBusConnection *conn)
1047 DBG("conn %p", conn);
1049 connection = dbus_connection_ref(conn);
1050 if (connection == NULL)
1053 hal_init(connection);
1055 hal_watch = g_dbus_add_watch(connection, "org.freedesktop.Hal",
1056 hal_init, hal_cleanup, connection, NULL);
1061 void __connman_iface_cleanup(void)
1063 DBG("conn %p", connection);
1065 g_dbus_remove_watch(connection, hal_watch);
1067 hal_cleanup(connection);
1069 dbus_connection_unref(connection);