--- 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