Convert udhcp plugin to connman task
authorSamuel Ortiz <sameo@linux.intel.com>
Fri, 9 Jul 2010 16:05:41 +0000 (18:05 +0200)
committerSamuel Ortiz <sameo@linux.intel.com>
Fri, 9 Jul 2010 16:11:12 +0000 (18:11 +0200)
The udhcp plugin was still using the old and deprecated
plugins/task.c API.

plugins/udhcp.c
scripts/udhcpc-script.c

index bc71824..4ae7cf4 100644 (file)
 #include <config.h>
 #endif
 
-#include <stdio.h>
+#include <errno.h>
 #include <unistd.h>
 
 #include <gdbus.h>
 
 #define CONNMAN_API_SUBJECT_TO_CHANGE
 #include <connman/plugin.h>
-#include <connman/driver.h>
-#include <connman/inet.h>
-#include <connman/dbus.h>
+#include <connman/utsname.h>
+#include <connman/dhcp.h>
+#include <connman/task.h>
 #include <connman/log.h>
 
-#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)
index a3f3b21..5d417b5 100644 (file)
@@ -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)