#include <config.h>
#endif
+#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <net/ethernet.h>
#include <gdbus.h>
};
struct supplicant_result {
- char *identifier;
+ char *path;
+ char *name;
+ char *addr;
unsigned char *ssid;
unsigned int ssid_len;
dbus_uint16_t capabilities;
gboolean has_wep;
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;
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);
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);
connman_device_set_powered(task->device, FALSE);
+ connman_device_unref(task->device);
+
+ inet_ifdown(task->ifindex);
+
free_task(task);
dbus_message_unref(reply);
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);
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;
DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
+ 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);
return 0;
}
+static struct {
+ char *name;
+ char *value;
+} special_ssid[] = {
+ { "<hidden>", "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)
+{
+ DBusMessageIter array;
+ struct ether_addr *eth;
+ unsigned char *addr;
+ int addr_len;
+
+ dbus_message_iter_recurse(value, &array);
+ dbus_message_iter_get_fixed_array(&array, &addr, &addr_len);
+
+ if (addr_len != 6)
+ return;
+
+ eth = (void *) addr;
+
+ result->addr = g_try_malloc0(18);
+ if (result->addr == NULL)
+ return;
+
+ snprintf(result->addr, 18, "%02X:%02X:%02X:%02X:%02X:%02X",
+ eth->ether_addr_octet[0],
+ eth->ether_addr_octet[1],
+ eth->ether_addr_octet[2],
+ eth->ether_addr_octet[3],
+ eth->ether_addr_octet[4],
+ eth->ether_addr_octet[5]);
+
+ result->path = g_try_malloc0(18);
+ if (result->path == NULL)
+ return;
+
+ 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],
+ eth->ether_addr_octet[3],
+ eth->ether_addr_octet[4],
+ eth->ether_addr_octet[5]);
+}
+
static void extract_ssid(DBusMessageIter *value,
struct supplicant_result *result)
{
memcpy(result->ssid, ssid, ssid_len);
result->ssid_len = ssid_len;
- result->identifier = g_try_malloc0(ssid_len + 1);
- if (result->identifier == NULL)
+ result->name = g_try_malloc0(ssid_len + 1);
+ if (result->name == NULL)
return;
- memcpy(result->identifier, ssid, ssid_len);
+ memcpy(result->name, ssid, ssid_len);
}
static void extract_wpaie(DBusMessageIter *value,
result->has_rsn = TRUE;
}
+static void extract_wpsie(DBusMessageIter *value,
+ struct supplicant_result *result)
+{
+ DBusMessageIter array;
+ unsigned char *ie;
+ int ie_len;
+
+ dbus_message_iter_recurse(value, &array);
+ dbus_message_iter_get_fixed_array(&array, &ie, &ie_len);
+
+ if (ie_len > 0)
+ result->has_wps = TRUE;
+}
+
static void extract_capabilites(DBusMessageIter *value,
struct supplicant_result *result)
{
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)
struct connman_network *network;
DBusMessage *reply;
DBusMessageIter array, dict;
- char *security;
unsigned char strength;
+ unsigned short channel, frequency;
+ const char *mode, *security;
+ char *group;
DBG("task %p", task);
}
memset(&result, 0, sizeof(result));
+ result.frequency = -1;
+ result.quality = -1;
+ result.level = -1;
+ result.noise = -1;
dbus_message_iter_init(reply, &array);
* ssid : a (97)
* wpaie : a (97)
* rsnie : a (97)
+ * wpsie : a (97)
* frequency : i (105)
* capabilities : q (113)
* quality : i (105)
* maxrate : i (105)
*/
- if (g_str_equal(key, "ssid") == TRUE)
+ if (g_str_equal(key, "bssid") == TRUE)
+ extract_addr(&value, &result);
+ else if (g_str_equal(key, "ssid") == TRUE)
extract_ssid(&value, &result);
else if (g_str_equal(key, "wpaie") == TRUE)
extract_wpaie(&value, &result);
else if (g_str_equal(key, "rsnie") == TRUE)
extract_rsnie(&value, &result);
+ else if (g_str_equal(key, "wpsie") == TRUE)
+ 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)
dbus_message_iter_next(&dict);
}
- if (result.identifier == NULL)
+ if (result.path == NULL)
goto done;
- if (result.identifier[0] == '\0')
+ if (result.path[0] == '\0')
goto done;
- strength = result.quality;
+ if (result.frequency > 0 && result.frequency < 14)
+ result.frequency = 2407 + (5 * result.frequency);
+ else if (result.frequency == 14)
+ result.frequency = 2484;
+
+ 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)
else
security = "none";
- network = connman_device_get_network(task->device, result.identifier);
+ 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) {
- const char *mode;
int index;
- network = connman_network_create(result.identifier,
+ network = connman_network_create(result.path,
CONNMAN_NETWORK_TYPE_WIFI);
if (network == NULL)
goto done;
connman_network_set_protocol(network,
CONNMAN_NETWORK_PROTOCOL_IP);
- connman_network_set_string(network, "Name", result.identifier);
-
- 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", result.identifier, mode,
- security, strength);
+ connman_network_set_string(network, "Address", result.addr);
if (connman_device_add_network(task->device, network) < 0) {
connman_network_unref(network);
}
}
+ 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);
+
+ 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");
+
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.identifier);
+ g_free(result.path);
+ g_free(result.addr);
+ g_free(result.name);
g_free(result.ssid);
dbus_message_unref(reply);
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);
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:
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;
}
}
task->ifindex = connman_device_get_index(device);
task->ifname = inet_index2name(task->ifindex);
- task->device = device;
if (task->ifname == NULL) {
g_free(task);
return -ENOMEM;
}
+ task->device = connman_device_ref(device);
+
task->created = FALSE;
task->noscan = FALSE;
task->state = WPA_INVALID;
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;
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;
}