X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=plugins%2Fsupplicant.c;h=3acb99eec509db748a1dd79e9d72cc0be5ea578a;hb=7908b1d662e6ce8400a586c287a049199f4a8f24;hp=66398673c188be252e246dd05348cd49a13fc3ec;hpb=6807913ff2db5e688eb27f8c7bb7ee5534f959de;p=connman diff --git a/plugins/supplicant.c b/plugins/supplicant.c index 6639867..3acb99e 100644 --- a/plugins/supplicant.c +++ b/plugins/supplicant.c @@ -158,6 +158,7 @@ struct supplicant_result { gboolean has_wpa; gboolean has_rsn; gboolean has_wps; + dbus_int32_t frequency; dbus_int32_t quality; dbus_int32_t noise; dbus_int32_t level; @@ -279,6 +280,12 @@ static int add_interface(struct supplicant_task *task) return -EIO; } + if (call == NULL) { + connman_error("D-Bus connection not available"); + dbus_message_unref(message); + return -EIO; + } + dbus_pending_call_set_notify(call, add_interface_reply, task, NULL); dbus_message_unref(message); @@ -349,6 +356,12 @@ static int create_interface(struct supplicant_task *task) return -EIO; } + if (call == NULL) { + connman_error("D-Bus connection not available"); + dbus_message_unref(message); + return -EIO; + } + dbus_pending_call_set_notify(call, get_interface_reply, task, NULL); dbus_message_unref(message); @@ -369,6 +382,8 @@ static void remove_interface_reply(DBusPendingCall *call, void *user_data) connman_device_unref(task->device); + inet_ifdown(task->ifindex); + free_task(task); dbus_message_unref(reply); @@ -401,6 +416,12 @@ static int remove_interface(struct supplicant_task *task) return -EIO; } + if (call == NULL) { + connman_error("D-Bus connection not available"); + dbus_message_unref(message); + return -EIO; + } + dbus_pending_call_set_notify(call, remove_interface_reply, task, NULL); dbus_message_unref(message); @@ -656,12 +677,12 @@ static int disable_network(struct supplicant_task *task) static int set_network(struct supplicant_task *task, const unsigned char *network, int len, - const char *security, const char *passphrase) + const char *address, const char *security, + const char *passphrase) { DBusMessage *message, *reply; DBusMessageIter array, dict; DBusError error; - const char *scan = "1"; DBG("task %p", task); @@ -680,14 +701,19 @@ static int set_network(struct supplicant_task *task, DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); - connman_dbus_dict_append_variant(&dict, "scan_ssid", - DBUS_TYPE_STRING, &scan); + if (address == NULL) { + dbus_uint32_t scan_ssid = 1; + connman_dbus_dict_append_variant(&dict, "scan_ssid", + DBUS_TYPE_UINT32, &scan_ssid); + } else + connman_dbus_dict_append_variant(&dict, "bssid", + DBUS_TYPE_STRING, &address); connman_dbus_dict_append_array(&dict, "ssid", DBUS_TYPE_BYTE, &network, len); if (g_ascii_strcasecmp(security, "wpa") == 0 || - g_ascii_strcasecmp(security, "wpa2") == 0) { + g_ascii_strcasecmp(security, "rsn") == 0) { const char *key_mgmt = "WPA-PSK"; connman_dbus_dict_append_variant(&dict, "key_mgmt", DBUS_TYPE_STRING, &key_mgmt); @@ -778,6 +804,64 @@ static int initiate_scan(struct supplicant_task *task) return 0; } +static struct { + char *name; + char *value; +} special_ssid[] = { + { "", "hidden" }, + { "default", "linksys" }, + { "wireless" }, + { "linksys" }, + { "netgear" }, + { "dlink" }, + { "2wire" }, + { "compaq" }, + { "tsunami" }, + { "comcomcom" }, + { "Symbol", "symbol" }, + { "Wireless" , "wireless" }, + { "WLAN", "wlan" }, + { } +}; + +static char *build_group(const char *addr, const char *name, + const unsigned char *ssid, unsigned int ssid_len, + const char *mode, const char *security) +{ + GString *str; + unsigned int i; + + if (addr == NULL) + return NULL; + + str = g_string_sized_new((ssid_len * 2) + 24); + if (str == NULL) + return NULL; + + for (i = 0; special_ssid[i].name; i++) { + if (g_strcmp0(special_ssid[i].name, name) == 0) { + if (special_ssid[i].value == NULL) + g_string_append_printf(str, "%s_%s", + name, addr); + else + g_string_append_printf(str, "%s_%s", + special_ssid[i].value, addr); + goto done; + } + } + + if (ssid_len > 0 && ssid[0] != '\0') { + for (i = 0; i < ssid_len; i++) + g_string_append_printf(str, "%02x", ssid[i]); + } else + g_string_append_printf(str, "hidden_%s", addr); + +done: + g_string_append_printf(str, "_%s_%s", mode, security); + + return g_string_free(str, FALSE); +} + static void extract_addr(DBusMessageIter *value, struct supplicant_result *result) { @@ -810,7 +894,7 @@ static void extract_addr(DBusMessageIter *value, if (result->path == NULL) return; - snprintf(result->path, 18, "%02X_%02X_%02X_%02X_%02X_%02X", + snprintf(result->path, 18, "%02x%02x%02x%02x%02x%02x", eth->ether_addr_octet[0], eth->ether_addr_octet[1], eth->ether_addr_octet[2], @@ -832,9 +916,6 @@ static void extract_ssid(DBusMessageIter *value, if (ssid_len < 1) return; - if (ssid[0] == '\0') - return; - result->ssid = g_try_malloc(ssid_len); if (result->ssid == NULL) return; @@ -905,6 +986,19 @@ static void extract_capabilites(DBusMessageIter *value, result->has_wep = TRUE; } +static unsigned char calculate_strength(struct supplicant_result *result) +{ + if (result->quality < 0) + return 0; + + return result->quality; +} + +static unsigned short calculate_channel(struct supplicant_result *result) +{ + return 0; +} + static void get_properties(struct supplicant_task *task); static void properties_reply(DBusPendingCall *call, void *user_data) @@ -914,8 +1008,10 @@ static void properties_reply(DBusPendingCall *call, void *user_data) struct connman_network *network; DBusMessage *reply; DBusMessageIter array, dict; - const char *mode, *security; unsigned char strength; + unsigned short channel, frequency; + const char *mode, *security; + char *group; DBG("task %p", task); @@ -932,6 +1028,10 @@ static void properties_reply(DBusPendingCall *call, void *user_data) } memset(&result, 0, sizeof(result)); + result.frequency = -1; + result.quality = -1; + result.level = -1; + result.noise = -1; dbus_message_iter_init(reply, &array); @@ -977,6 +1077,8 @@ static void properties_reply(DBusPendingCall *call, void *user_data) extract_wpsie(&value, &result); else if (g_str_equal(key, "capabilities") == TRUE) extract_capabilites(&value, &result); + else if (g_str_equal(key, "frequency") == TRUE) + dbus_message_iter_get_basic(&value, &result.frequency); else if (g_str_equal(key, "quality") == TRUE) dbus_message_iter_get_basic(&value, &result.quality); else if (g_str_equal(key, "noise") == TRUE) @@ -995,10 +1097,13 @@ static void properties_reply(DBusPendingCall *call, void *user_data) if (result.path[0] == '\0') goto done; - strength = result.quality; + strength = calculate_strength(&result); + channel = calculate_channel(&result); + + frequency = (result.frequency < 0) ? 0 : result.frequency; if (result.has_rsn == TRUE) - security = "wpa2"; + security = "rsn"; else if (result.has_wpa == TRUE) security = "wpa"; else if (result.has_wep == TRUE) @@ -1006,6 +1111,12 @@ static void properties_reply(DBusPendingCall *call, void *user_data) else security = "none"; + mode = (result.adhoc == TRUE) ? "adhoc" : "managed"; + + group = build_group(result.path, result.name, + result.ssid, result.ssid_len, + mode, security); + network = connman_device_get_network(task->device, result.path); if (network == NULL) { int index; @@ -1029,23 +1140,29 @@ static void properties_reply(DBusPendingCall *call, void *user_data) } } - connman_network_set_string(network, "Name", result.name); + if (result.name != NULL && result.name[0] != '\0') + connman_network_set_string(network, "Name", result.name); connman_network_set_blob(network, "WiFi.SSID", result.ssid, result.ssid_len); - mode = (result.adhoc == TRUE) ? "adhoc" : "managed"; connman_network_set_string(network, "WiFi.Mode", mode); DBG("%s (%s %s) strength %d (%s)", - result.name, mode, security, strength, - (result.has_wps == TRUE) ? "WPS" : "no WPS"); + result.name, mode, security, strength, + (result.has_wps == TRUE) ? "WPS" : "no WPS"); connman_network_set_available(network, TRUE); connman_network_set_uint8(network, "Strength", strength); + connman_network_set_uint16(network, "Frequency", frequency); + connman_network_set_uint16(network, "WiFi.Channel", channel); connman_network_set_string(network, "WiFi.Security", security); + connman_network_set_group(network, group); + + g_free(group); + done: g_free(result.path); g_free(result.addr); @@ -1084,6 +1201,12 @@ static void get_properties(struct supplicant_task *task) goto noscan; } + if (call == NULL) { + connman_error("D-Bus connection not available"); + dbus_message_unref(message); + goto noscan; + } + dbus_pending_call_set_notify(call, properties_reply, task, NULL); dbus_message_unref(message); @@ -1175,6 +1298,11 @@ static void scan_results_available(struct supplicant_task *task) if (task->noscan == FALSE) connman_device_set_scanning(task->device, TRUE); + if (call == NULL) { + connman_error("D-Bus connection not available"); + goto done; + } + dbus_pending_call_set_notify(call, scan_results_reply, task, NULL); done: @@ -1267,7 +1395,11 @@ static void state_change(struct supplicant_task *task, DBusMessage *msg) connman_network_set_connected(task->network, FALSE); connman_device_set_scanning(task->device, FALSE); break; + case WPA_ASSOCIATING: + connman_network_set_associating(task->network, TRUE); + break; default: + connman_network_set_associating(task->network, FALSE); break; } } @@ -1385,19 +1517,21 @@ int supplicant_scan(struct connman_device *device) int supplicant_connect(struct connman_network *network) { struct supplicant_task *task; - const char *security, *passphrase; + const char *address, *security, *passphrase; const void *ssid; unsigned int ssid_len; int index; DBG("network %p", network); + address = connman_network_get_string(network, "Address"); security = connman_network_get_string(network, "WiFi.Security"); passphrase = connman_network_get_string(network, "WiFi.Passphrase"); ssid = connman_network_get_blob(network, "WiFi.SSID", &ssid_len); - DBG("security %s passphrase %s", security, passphrase); + DBG("address %s security %s passphrase %s", + address, security, passphrase); if (security == NULL && passphrase == NULL) return -EINVAL; @@ -1418,10 +1552,12 @@ int supplicant_connect(struct connman_network *network) select_network(task); disable_network(task); - set_network(task, ssid, ssid_len, security, passphrase); + set_network(task, ssid, ssid_len, address, security, passphrase); enable_network(task); + connman_network_set_associating(task->network, TRUE); + return 0; }