---
 src/connman.h |   13 +++++
 src/device.c  |    9 ++--
 src/element.c |   29 ++++++++++
 src/manager.c |   31 +++++------
 src/network.c |    8 +++
 src/service.c |  167 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 6 files changed, 235 insertions(+), 22 deletions(-)

diff --git a/src/connman.h b/src/connman.h
index 84ebf60..719d8e6 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -161,6 +161,8 @@ int __connman_element_count(struct connman_element *element,
 struct connman_service *__connman_element_get_service(struct connman_element 
*element);
 struct connman_device *__connman_element_get_device(struct connman_element 
*element);
 const char *__connman_element_get_device_path(struct connman_element *element);
+struct connman_device *__connman_element_find_device(
+                                                                       enum 
connman_device_type type);
 const char *__connman_element_get_network_path(struct connman_element 
*element);
 
 const char *__connman_element_type2string(enum connman_element_type type);
@@ -215,6 +217,11 @@ int __connman_device_set_offlinemode(connman_bool_t 
offlinemode);
 int __connman_profile_add_device(struct connman_device *device);
 int __connman_profile_remove_device(struct connman_device *device);
 
+struct connman_network *__connman_device_find_network(
+                                                               struct 
connman_device *device,
+                                                               const void 
*ssid, const char *address,
+                                                               const char 
*security, const char *mode);
+
 #include <connman/network.h>
 
 int __connman_network_init(void);
@@ -223,6 +230,8 @@ void __connman_network_cleanup(void);
 void __connman_network_set_device(struct connman_network *network,
                                        struct connman_device *device);
 
+connman_bool_t __connman_network_is_hidden(struct connman_network *network);
+
 int __connman_network_connect(struct connman_network *network);
 int __connman_network_disconnect(struct connman_network *network);
 
@@ -263,6 +272,10 @@ 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_connect(DBusMessage *msg, 
+                                                                       struct 
connman_service **service);
+char *__connman_service_get_path(struct connman_service *service);
+
 #include <connman/notifier.h>
 
 int __connman_notifier_init(void);
diff --git a/src/device.c b/src/device.c
index a7cf31e..e86ead4 100644
--- a/src/device.c
+++ b/src/device.c
@@ -493,9 +493,10 @@ static void convert_name(const char *ssid, char *name,
        }
 }
 
-static struct connman_network *find_network(struct connman_device *device,
-                                       const void *ssid, const char *address,
-                                       const char *security, const char *mode)
+struct connman_network *__connman_device_find_network(
+                                                               struct 
connman_device *device,
+                                                               const void 
*ssid, const char *address,
+                                                               const char 
*security, const char *mode)
 {
        GHashTableIter network_iter;
        gpointer key, value;
@@ -615,7 +616,7 @@ static DBusMessage *join_network(DBusConnection *conn,
        mode = connman_network_get_string(network, "WiFi.Mode");
        address = connman_network_get_string(network, "Address");
 
-       found_network = find_network(device, ssid, address, security, mode);
+       found_network = __connman_device_find_network(device, ssid, address, 
security, mode);
        if (found_network != NULL) {
                const char* passphrase;
 
diff --git a/src/element.c b/src/element.c
index 6ecd595..2d15598 100644
--- a/src/element.c
+++ b/src/element.c
@@ -318,6 +318,35 @@ const char *__connman_element_get_device_path(struct 
connman_element *element)
        return connman_device_get_path(device);
 }
 
+struct find_data {
+       enum connman_device_type type;
+       struct connman_device *device;
+};
+
+static gboolean find_device(GNode *node, gpointer data)
+{
+       struct connman_element *element = node->data;
+       struct find_data *the_data = data;
+
+       if (element->type == the_data->type) {
+                       the_data->device = element->device;
+                       return TRUE;
+       }
+       
+       return FALSE;
+}
+
+struct connman_device *__connman_element_find_device(
+                                                                       enum 
connman_device_type type)
+{
+       struct find_data data= {.type = type, .device = NULL};
+       
+       g_node_traverse(element_root, G_PRE_ORDER,
+                               G_TRAVERSE_ALL, -1, find_device, &data);
+               
+       return data.device;
+}
+
 const char *__connman_element_get_network_path(struct connman_element *element)
 {
        if (element->type == CONNMAN_ELEMENT_TYPE_NETWORK &&
diff --git a/src/manager.c b/src/manager.c
index 71430c8..fdbac62 100644
--- a/src/manager.c
+++ b/src/manager.c
@@ -247,7 +247,10 @@ static DBusMessage *remove_profile(DBusConnection *conn,
 static DBusMessage *connect_service(DBusConnection *conn,
                                        DBusMessage *msg, void *data)
 {
-       DBusMessageIter iter, array;
+       DBusMessage *reply;
+       struct connman_service *service = NULL;
+       char *path = NULL;
+       int err;
 
        DBG("conn %p", conn);
 
@@ -255,26 +258,18 @@ 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);
+       err = __connman_service_create_connect(msg, &service);
+       if (err < 0 )
+               return __connman_error_failed(msg, -err);
 
-               dbus_message_iter_next(&entry);
-               dbus_message_iter_recurse(&entry, &value);
-
-               switch (dbus_message_iter_get_arg_type(&value)) {
-               }
+       reply = dbus_message_new_method_return(msg);
+       if (reply == NULL)
+               return NULL;
 
-               dbus_message_iter_next(&array);
-       }
+       path = __connman_service_get_path(service);
+       dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, 
DBUS_TYPE_INVALID);
 
-       return __connman_error_not_implemented(msg);
+       return reply;
 }
 
 static DBusMessage *register_agent(DBusConnection *conn,
diff --git a/src/network.c b/src/network.c
index afce285..37269ee 100644
--- a/src/network.c
+++ b/src/network.c
@@ -1154,6 +1154,14 @@ void __connman_network_set_device(struct connman_network 
*network,
        network->device = device;
 }
 
+connman_bool_t __connman_network_is_hidden(struct connman_network *network)
+{
+       if (network->wifi.ssid == NULL)
+                       return TRUE;
+       else
+                       return FALSE;
+}
+
 /**
  * connman_network_get_device:
  * @network: network structure
diff --git a/src/service.c b/src/service.c
index 786efd7..83c394e 100644
--- a/src/service.c
+++ b/src/service.c
@@ -1096,6 +1096,168 @@ int __connman_service_connect(struct connman_service 
*service)
        return 0;
 }
 
+static void convert_name(const unsigned char *ssid, char *name,
+                                               unsigned int ssid_len)
+{
+       unsigned int i;
+
+       for (i = 0; i < ssid_len; i++) {
+               if (g_ascii_isprint(ssid[i]))
+                       name[i] = ssid[i];
+               else
+                       name[i] = ' ';
+       }
+}
+
+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);
+}
+
+int __connman_service_create_connect(DBusMessage *msg, 
+                                                       struct connman_service 
**created_service)
+{
+       struct connman_service *service;
+       struct connman_network *network, *found_network;
+       struct connman_device *device;
+       const char *address, *mode, *security, *passphrase, *type, *group;
+       const unsigned char *ssid;
+       char *name;
+       unsigned int ssid_len;
+       int index, err;
+       DBusMessageIter iter, array;
+       
+       *created_service = NULL;
+       
+       if (msg == NULL)
+               return -EINVAL;
+       
+       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, *str;
+
+               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:
+                       dbus_message_iter_get_basic(&value, &str);
+                       if (g_str_equal(key, "WiFi.SSID") == TRUE) {
+                               ssid = (const unsigned char *) str;
+                               ssid_len = strlen(str);
+                       }
+                       else if (g_str_equal(key, "WiFi.Mode") == TRUE)
+                               mode = str;
+                       else if (g_str_equal(key, "WiFi.Passphrase") == TRUE)
+                               passphrase = str;
+                       else if (g_str_equal(key, "WiFi.Security") == TRUE)
+                               security = str;
+                       else if (g_str_equal(key, "Address") == TRUE)
+                               address = str;
+                       else if (g_str_equal(key, "Type") == TRUE)
+                               type = str;
+               break;
+               }
+
+               dbus_message_iter_next(&array);
+       }
+
+       if (g_strcmp0(type, "wifi") != 0)
+               return -EOPNOTSUPP;
+
+       if (security == NULL && passphrase == NULL)
+               return -EINVAL;
+
+       if (g_str_equal(security, "none") == FALSE && passphrase == NULL)
+               return -EINVAL;
+
+       device =__connman_element_find_device(CONNMAN_DEVICE_TYPE_WIFI);
+       if (device == NULL)
+                       return -EOPNOTSUPP; 
+
+       found_network = __connman_device_find_network(
+                                                               device, ssid, 
address, security, mode);
+       if (found_network != NULL && __connman_network_is_hidden(found_network) 
== FALSE) {
+               connman_network_set_string(network, "WiFi.Passphrase", 
passphrase);
+               
+               service = __connman_service_create_from_network(network);
+               if (service == NULL) 
+                       return -ENOMEM;
+
+               if (service->pending != NULL) {
+                       *created_service = service;
+                       return 0;
+               }
+       } else {
+               network = connman_network_create("00_00_00_00_00_00",
+                                                                               
CONNMAN_NETWORK_TYPE_WIFI);
+               if (network == NULL)
+                       return -ENOMEM;
+       
+               connman_network_set_blob(network, "WiFi.SSID", ssid, ssid_len);
+
+               name = g_try_malloc0(ssid_len + 1);
+               if (name == NULL)
+                       return -ENOMEM;
+
+               convert_name(ssid, name, ssid_len);
+               connman_network_set_name(network, name);
+               g_free(name);
+
+               connman_network_set_string(network, "WiFi.Mode", mode);
+               connman_network_set_string(network, "Address", address);
+               connman_network_set_string(network, "WiFi.Security", security);
+               connman_network_set_string(network, "WiFi.Passphrase", 
passphrase);
+
+               group = build_group(ssid, ssid_len, mode, security);
+
+               index = connman_device_get_index(device);
+               connman_network_set_index(network, index);
+
+               connman_network_set_protocol(network, 
CONNMAN_NETWORK_PROTOCOL_IP);
+
+               connman_device_add_network(device, network);
+
+               connman_network_set_available(network, TRUE);
+
+               service = __connman_service_lookup_from_network(network);
+
+               *created_service = service;
+       }
+
+       service->pending = dbus_message_ref(msg);
+
+       err = __connman_service_connect(service);
+       if (err < 0 && err != -EINPROGRESS) {
+               dbus_message_unref(msg);
+               service->pending = NULL;
+               return err;
+       }
+ 
+       return 0; 
+}
+
 int __connman_service_disconnect(struct connman_service *service)
 {
        int err;
@@ -1503,6 +1665,11 @@ done:
        return service;
 }
 
+char *__connman_service_get_path(struct connman_service *service)
+{
+       return service->path;
+}
+
 static int service_load(struct connman_service *service)
 {
        GKeyFile *keyfile;
-- 
1.6.1.3

_______________________________________________
connman mailing list
connman@connman.net
http://lists.connman.net/listinfo/connman

Reply via email to