From 6877508042fec2f80b5340981edb728a0c715725 Mon Sep 17 00:00:00 2001 From: Samuel Ortiz Date: Fri, 9 Jul 2010 18:05:41 +0200 Subject: [PATCH] Convert udhcp plugin to connman task The udhcp plugin was still using the old and deprecated plugins/task.c API. --- plugins/udhcp.c | 248 ++++++++++++++++++++++-------------------------- scripts/udhcpc-script.c | 11 ++- 2 files changed, 124 insertions(+), 135 deletions(-) diff --git a/plugins/udhcp.c b/plugins/udhcp.c index bc71824..4ae7cf4 100644 --- a/plugins/udhcp.c +++ b/plugins/udhcp.c @@ -23,92 +23,41 @@ #include #endif -#include +#include #include #include #define CONNMAN_API_SUBJECT_TO_CHANGE #include -#include -#include -#include +#include +#include +#include #include -#include "task.h" - -#define UDHCPC_INTF "net.busybox.udhcpc" -#define UDHCPC_PATH "/net/busybox/udhcpc" +struct udhcp_data { + struct connman_task *task; + struct connman_dhcp *dhcp; + char *ifname; +}; -static int udhcp_probe(struct connman_element *element) +static void udhcp_unlink(const char *ifname) { - struct task_data *task; - char *argv[9], *envp[2], *ifname; - char pidfile[PATH_MAX], script[PATH_MAX]; - - DBG("element %p name %s", element, element->name); - - if (access(UDHCPC, X_OK) < 0) - return -errno; - - ifname = connman_inet_ifname(element->index); - if (ifname == NULL) - return -ENOMEM; + char *pathname; - snprintf(pidfile, sizeof(pidfile) - 1, - "%s/udhcpc.%s.pid", STATEDIR, ifname); - snprintf(script, sizeof(script) - 1, "%s/udhcpc-script", SCRIPTDIR); - - argv[0] = UDHCPC; - argv[1] = "-f"; - argv[2] = "-i"; - argv[3] = ifname; - argv[4] = "-p"; - argv[5] = pidfile; - argv[6] = "-s"; - argv[7] = script; - argv[8] = NULL; - - envp[0] = NULL; - - task = task_spawn(element->index, argv, envp, NULL, element); - if (task == NULL) { - g_free(ifname); - return -EIO; - } - - g_free(ifname); - - return 0; + pathname = g_strdup_printf("%s/udhcpc.%s.pid", + STATEDIR, ifname); + unlink(pathname); + g_free(pathname); } -static void udhcp_remove(struct connman_element *element) +static void udhcp_notify(struct connman_task *task, + DBusMessage *msg, void *user_data) { - struct task_data *task; + struct connman_dhcp *dhcp = user_data; + const char *interface, *address, *netmask, *broadcast, *gateway, *dns, *action; - DBG("element %p name %s", element, element->name); - - task = task_find_by_index(element->index); - if (task == NULL) - return; - - task_kill(task); -} - -static struct connman_driver udhcp_driver = { - .name = "udhcp", - .type = CONNMAN_ELEMENT_TYPE_DHCP, - .priority = CONNMAN_DRIVER_PRIORITY_HIGH, - .probe = udhcp_probe, - .remove = udhcp_remove, -}; - -static void udhcp_bound(DBusMessage *msg, gboolean renew) -{ - struct task_data *task; - struct connman_element *element, *parent; - const char *interface, *address, *netmask, *broadcast, *gateway, *dns; - int index; + DBG(""); dbus_message_get_args(msg, NULL, DBUS_TYPE_STRING, &interface, DBUS_TYPE_STRING, &address, @@ -116,102 +65,135 @@ static void udhcp_bound(DBusMessage *msg, gboolean renew) DBUS_TYPE_STRING, &broadcast, DBUS_TYPE_STRING, &gateway, DBUS_TYPE_STRING, &dns, + DBUS_TYPE_STRING, &action, DBUS_TYPE_INVALID); - DBG("%s ==> address %s gateway %s", interface, address, gateway); + DBG("%s address %s gateway %s", action, address, gateway); - index = connman_inet_ifindex(interface); - if (index < 0) - return; + connman_dhcp_set_value(dhcp, "Address", address); + connman_dhcp_set_value(dhcp, "Netmask", netmask); + connman_dhcp_set_value(dhcp, "Gateway", gateway); + connman_dhcp_set_value(dhcp, "Broadcast", broadcast); + connman_dhcp_set_value(dhcp, "Nameserver", dns); - task = task_find_by_index(index); - if (task == NULL) - return; + if (g_strcmp0(action, "bound") == 0) { + connman_dhcp_bound(dhcp); + } else if (g_strcmp0(action, "renew") == 0) { + connman_dhcp_bound(dhcp); + } else { + connman_error("Unknown action %s", action); + } +} - parent = task_get_data(task); - if (parent == NULL) - return; +static void udhcp_died(struct connman_task *task, void *user_data) +{ + struct udhcp_data *udhcpc = user_data; - g_free(parent->ipv4.address); - parent->ipv4.address = g_strdup(address); + connman_dhcp_set_data(udhcpc->dhcp, NULL); - g_free(parent->ipv4.netmask); - parent->ipv4.netmask = g_strdup(netmask); + connman_dhcp_unref(udhcpc->dhcp); - g_free(parent->ipv4.broadcast); - parent->ipv4.broadcast = g_strdup(broadcast); + connman_task_destroy(udhcpc->task); + udhcpc->task = NULL; - g_free(parent->ipv4.gateway); - parent->ipv4.gateway = g_strdup(gateway); + udhcp_unlink(udhcpc->ifname); - g_free(parent->ipv4.nameserver); - parent->ipv4.nameserver = g_strdup(dns); + g_free(udhcpc->ifname); + g_free(udhcpc); +} - connman_element_update(parent); - if (renew == TRUE) - return; +static void udhcp_setup(struct connman_task *task, const char *ifname) +{ + const char *path, *hostname; - element = connman_element_create(NULL); - if (element == NULL) - return; + path = connman_task_get_path(task); - element->type = CONNMAN_ELEMENT_TYPE_IPV4; - element->index = index; + DBG("path %s", path); - if (connman_element_register(element, parent) < 0) - connman_element_unref(element); -} + connman_task_add_argument(task, "-f", NULL); + connman_task_add_argument(task, "-i", "%s", ifname); + connman_task_add_argument(task, "-p", "%s/udhcpc.%s.pid", STATEDIR, ifname); + connman_task_add_argument(task, "-s", "%s/udhcpc-script", SCRIPTDIR); -static gboolean udhcp_filter(DBusConnection *conn, - DBusMessage *msg, void *data) -{ - if (dbus_message_is_method_call(msg, UDHCPC_INTF, "bound") == TRUE) { - udhcp_bound(msg, FALSE); - return TRUE; - } + hostname = connman_utsname_get_hostname(); + if (hostname != NULL) + connman_task_add_argument(task, "-H", hostname); - if (dbus_message_is_method_call(msg, UDHCPC_INTF, "renew") == TRUE) { - udhcp_bound(msg, TRUE); - return TRUE; - } + connman_task_add_variable(task, "PATH", path); - return TRUE; } -static DBusConnection *connection; -static guint watch; - -static int udhcp_init(void) +static int udhcp_request(struct connman_dhcp *dhcp) { - int err; + struct udhcp_data *udhcpc; - connection = connman_dbus_get_connection(); + DBG("dhcp %p %s", dhcp, UDHCPC); - watch = g_dbus_add_signal_watch(connection, NULL, UDHCPC_PATH, - UDHCPC_INTF, NULL, udhcp_filter, - NULL, NULL); - if (watch == 0) + if (access(UDHCPC, X_OK) < 0) return -EIO; - err = connman_driver_register(&udhcp_driver); - if (err < 0) { - dbus_connection_unref(connection); - return err; + udhcpc = g_try_new0(struct udhcp_data, 1); + if (udhcpc == NULL) + return -ENOMEM; + + udhcpc->task = connman_task_create(UDHCPC); + if (udhcpc->task == NULL) { + g_free(udhcpc); + return -ENOMEM; } + udhcpc->dhcp = connman_dhcp_ref(dhcp); + udhcpc->ifname = connman_dhcp_get_interface(dhcp); + + udhcp_setup(udhcpc->task, udhcpc->ifname); + + connman_dhcp_set_data(dhcp, udhcpc); + + connman_task_set_notify(udhcpc->task, "Notify", + udhcp_notify, dhcp); + + connman_task_run(udhcpc->task, udhcp_died, udhcpc, + NULL, NULL, NULL); + return 0; } -static void udhcp_exit(void) +static int udhcp_release(struct connman_dhcp *dhcp) { - connman_driver_unregister(&udhcp_driver); + struct udhcp_data *udhcpc = connman_dhcp_get_data(dhcp); + + DBG("udhcp %p", udhcpc); + + if (udhcpc == NULL) + return -ESRCH; - g_dbus_remove_watch(connection, watch); + if (udhcpc->task != NULL) + connman_task_stop(udhcpc->task); - dbus_connection_unref(connection); + udhcp_unlink(udhcpc->ifname); + + return 0; +} + + +static struct connman_dhcp_driver udhcp_driver = { + .name = "udhcp", + .priority = CONNMAN_DHCP_PRIORITY_LOW, + .request = udhcp_request, + .release = udhcp_release, +}; + +static int udhcp_init(void) +{ + return connman_dhcp_driver_register(&udhcp_driver); +} + +static void udhcp_exit(void) +{ + connman_dhcp_driver_unregister(&udhcp_driver); } CONNMAN_PLUGIN_DEFINE(udhcp, "uDHCP client plugin", VERSION, - CONNMAN_PLUGIN_PRIORITY_DEFAULT, udhcp_init, udhcp_exit) + CONNMAN_PLUGIN_PRIORITY_LOW, udhcp_init, udhcp_exit) diff --git a/scripts/udhcpc-script.c b/scripts/udhcpc-script.c index a3f3b21..5d417b5 100644 --- a/scripts/udhcpc-script.c +++ b/scripts/udhcpc-script.c @@ -39,6 +39,7 @@ int main(int argc, char *argv[]) DBusMessage *msg; char *busname, *interface, *address, *netmask, *broadcast; char *gateway, *dns; + char *path; if (argc < 2) return 0; @@ -50,6 +51,10 @@ int main(int argc, char *argv[]) interface = getenv("interface"); + path = getenv("PATH"); + if (path == NULL) + path = ""; + address = getenv("ip"); if (address == NULL) address = ""; @@ -82,8 +87,9 @@ int main(int argc, char *argv[]) return 0; } - msg = dbus_message_new_method_call(busname, UDHCPC_PATH, - UDHCPC_INTF, argv[1]); + msg = dbus_message_new_method_call(busname, path, + "org.moblin.connman.Task", + "Notify"); if (msg == NULL) { dbus_connection_unref(conn); fprintf(stderr, "Failed to allocate method call\n"); @@ -98,6 +104,7 @@ int main(int argc, char *argv[]) DBUS_TYPE_STRING, &broadcast, DBUS_TYPE_STRING, &gateway, DBUS_TYPE_STRING, &dns, + DBUS_TYPE_STRING, &argv[1], DBUS_TYPE_INVALID); if (dbus_connection_send(conn, msg, NULL) == FALSE) -- 2.7.4