Add support for connecting existing services via SSID
authorMarcel Holtmann <marcel@holtmann.org>
Thu, 16 Jul 2009 02:59:13 +0000 (04:59 +0200)
committerMarcel Holtmann <marcel@holtmann.org>
Thu, 16 Jul 2009 02:59:13 +0000 (04:59 +0200)
src/connman.h
src/device.c
src/manager.c
src/service.c

index a688db2..4b461f1 100644 (file)
@@ -266,6 +266,7 @@ int __connman_service_indicate_default(struct connman_service *service);
 
 int __connman_service_connect(struct connman_service *service);
 int __connman_service_disconnect(struct connman_service *service);
+int __connman_service_create_and_connect(DBusMessage *msg);
 
 #include <connman/notifier.h>
 
index 3ee1f61..9810444 100644 (file)
@@ -496,26 +496,6 @@ static DBusMessage *set_property(DBusConnection *conn,
        return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
 
-static char *build_group(const unsigned char *ssid, unsigned int ssid_len,
-                                       const char *mode, const char *security)
-{
-       GString *str;
-       unsigned int i;
-
-       str = g_string_sized_new((ssid_len * 2) + 24);
-       if (str == NULL)
-               return NULL;
-
-       if (ssid_len > 0 && ssid[0] != '\0') {
-               for (i = 0; i < ssid_len; i++)
-                       g_string_append_printf(str, "%02x", ssid[i]);
-       }
-
-       g_string_append_printf(str, "_%s_%s", mode, security);
-
-       return g_string_free(str, FALSE);
-}
-
 static void convert_name(const char *ssid, char *name,
                                                unsigned int ssid_len)
 {
@@ -674,7 +654,7 @@ static DBusMessage *join_network(DBusConnection *conn,
                return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
        }
 
-       group = build_group(ssid, ssid_size, mode, security);
+       group = connman_wifi_build_group_name(ssid, ssid_size, mode, security);
 
        index = connman_device_get_index(device);
        connman_network_set_index(network, index);
index 71430c8..3a79bc5 100644 (file)
@@ -247,7 +247,7 @@ static DBusMessage *remove_profile(DBusConnection *conn,
 static DBusMessage *connect_service(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
-       DBusMessageIter iter, array;
+       int err;
 
        DBG("conn %p", conn);
 
@@ -255,26 +255,17 @@ static DBusMessage *connect_service(DBusConnection *conn,
                                        CONNMAN_SECURITY_PRIVILEGE_MODIFY) < 0)
                return __connman_error_permission_denied(msg);
 
-       dbus_message_iter_init(msg, &iter);
-       dbus_message_iter_recurse(&iter, &array);
-
-       while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
-               DBusMessageIter entry, value;
-               const char *key;
-
-               dbus_message_iter_recurse(&array, &entry);
-               dbus_message_iter_get_basic(&entry, &key);
-
-               dbus_message_iter_next(&entry);
-               dbus_message_iter_recurse(&entry, &value);
-
-               switch (dbus_message_iter_get_arg_type(&value)) {
+       err = __connman_service_create_and_connect(msg);
+       if (err < 0) {
+               if (err == -EINPROGRESS) {
+                       connman_error("Invalid return code from callbacks");
+                       err = -EINVAL;
                }
 
-               dbus_message_iter_next(&array);
+               return __connman_error_failed(msg, -err);
        }
 
-       return __connman_error_not_implemented(msg);
+       return NULL;
 }
 
 static DBusMessage *register_agent(DBusConnection *conn,
index 14f14c5..b6e049f 100644 (file)
@@ -1140,6 +1140,101 @@ static struct connman_service *__connman_service_lookup(const char *identifier)
        return NULL;
 }
 
+int __connman_service_create_and_connect(DBusMessage *msg)
+{
+       struct connman_service *service;
+       struct connman_device *device;
+       DBusMessageIter iter, array;
+       const char *mode = "managed", *security = "none";
+       const char *type = NULL, *ssid = NULL, *passphrase = NULL;
+       const char *ident;
+       char *name, *group;
+       int err;
+
+       dbus_message_iter_init(msg, &iter);
+       dbus_message_iter_recurse(&iter, &array);
+
+       while (dbus_message_iter_get_arg_type(&array) == DBUS_TYPE_DICT_ENTRY) {
+               DBusMessageIter entry, value;
+               const char *key;
+
+               dbus_message_iter_recurse(&array, &entry);
+               dbus_message_iter_get_basic(&entry, &key);
+
+               dbus_message_iter_next(&entry);
+               dbus_message_iter_recurse(&entry, &value);
+
+               switch (dbus_message_iter_get_arg_type(&value)) {
+               case DBUS_TYPE_STRING:
+                       if (g_str_equal(key, "Type") == TRUE)
+                               dbus_message_iter_get_basic(&value, &type);
+                       else if (g_str_equal(key, "WiFi.Mode") == TRUE ||
+                                       g_str_equal(key, "Mode") == TRUE)
+                               dbus_message_iter_get_basic(&value, &mode);
+                       else if (g_str_equal(key, "WiFi.Security") == TRUE ||
+                                       g_str_equal(key, "Security") == TRUE)
+                               dbus_message_iter_get_basic(&value, &security);
+                       else if (g_str_equal(key, "WiFi.Passphrase") == TRUE ||
+                                       g_str_equal(key, "Passphrase") == TRUE)
+                               dbus_message_iter_get_basic(&value, &passphrase);
+                       else if (g_str_equal(key, "WiFi.SSID") == TRUE ||
+                                       g_str_equal(key, "SSID") == TRUE)
+                               dbus_message_iter_get_basic(&value, &ssid);
+               }
+
+               dbus_message_iter_next(&array);
+       }
+
+       if (type == NULL)
+               return -EINVAL;
+
+       if (g_strcmp0(type, "wifi") != 0 || g_strcmp0(mode, "managed") != 0)
+               return -EOPNOTSUPP;
+
+       if (ssid == NULL)
+               return -EINVAL;
+
+       device = __connman_element_find_device(CONNMAN_DEVICE_TYPE_WIFI);
+       if (device == NULL)
+               return -EOPNOTSUPP;
+
+       ident = __connman_device_get_ident(device);
+       if (ident == NULL)
+               return -EOPNOTSUPP;
+
+       group = connman_wifi_build_group_name((unsigned char *) ssid,
+                                               strlen(ssid), mode, security);
+       if (group == NULL)
+               return -EINVAL;
+
+       name = g_strdup_printf("%s_%s_%s", type, ident, group);
+
+       g_free(group);
+
+       service = __connman_service_lookup(name);
+
+       g_free(name);
+
+       if (service != NULL) {
+               if (passphrase != NULL) {
+                       g_free(service->passphrase);
+                       service->passphrase = g_strdup(passphrase);
+               }
+
+               err = __connman_service_connect(service);
+               if (err < 0 && err != -EINPROGRESS)
+                       return err;
+
+               g_dbus_send_reply(connection, msg,
+                                       DBUS_TYPE_OBJECT_PATH, &service->path,
+                                                       DBUS_TYPE_INVALID);
+
+               return 0;
+       }
+
+       return -EOPNOTSUPP;
+}
+
 /**
  * __connman_service_get:
  * @identifier: service identifier