#endif
#include <stdio.h>
+#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <linux/if_arp.h>
+#include <linux/wireless.h>
#include <net/ethernet.h>
#include <gdbus.h>
enum supplicant_state state;
gboolean noscan;
GSList *scan_results;
+ struct iw_range *range;
};
static GSList *task_list = NULL;
result->has_wep = TRUE;
}
-static unsigned char calculate_strength(struct supplicant_result *result)
+static unsigned char calculate_strength(struct supplicant_task *task,
+ struct supplicant_result *result)
{
- if (result->quality < 0) {
+ if (task->range->max_qual.qual == 0) {
unsigned char strength;
if (result->level > 0)
return strength;
}
- return result->quality;
+ return (result->quality * 100) / task->range->max_qual.qual;
}
static unsigned short calculate_channel(struct supplicant_result *result)
else if (result.frequency == 14)
result.frequency = 2484;
- strength = calculate_strength(&result);
+ strength = calculate_strength(task, &result);
channel = calculate_channel(&result);
frequency = (result.frequency < 0) ? 0 : result.frequency;
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
+static int supplicant_get_range(struct supplicant_task *task)
+{
+ int fd, ret;
+ struct iwreq wrq;
+
+ fd = socket(PF_INET, SOCK_DGRAM, 0);
+ if (fd < 0)
+ return -errno;
+
+ memset(&wrq, 0, sizeof(struct iwreq));
+ strncpy(wrq.ifr_name, task->ifname, IFNAMSIZ);
+ wrq.u.data.pointer = task->range;
+ wrq.u.data.length = sizeof(struct iw_range);
+
+ ret = ioctl(fd, SIOCGIWRANGE, &wrq);
+
+ close(fd);
+
+ return ret;
+}
+
int supplicant_start(struct connman_device *device)
{
struct supplicant_task *task;
+ int err;
DBG("device %p", device);
task->ifname = connman_inet_ifname(task->ifindex);
if (task->ifname == NULL) {
- g_free(task);
- return -ENOMEM;
+ err = -ENOMEM;
+ goto err_ifname;
}
+ task->range = g_try_malloc0(sizeof(struct iw_range));
+ if (task->range == NULL) {
+ err = -ENOMEM;
+ goto err_range;
+ }
+
+ err = supplicant_get_range(task);
+ if (err)
+ goto err_get_range;
+
task->device = connman_device_ref(device);
task->created = FALSE;
task_list = g_slist_append(task_list, task);
return create_interface(task);
+
+err_get_range:
+ g_free(task->range);
+
+err_range:
+ g_free(task->ifname);
+
+err_ifname:
+ g_free(task);
+
+ return err;
}
int supplicant_stop(struct connman_device *device)
if (task == NULL)
return -ENODEV;
+ g_free(task->range);
+
task_list = g_slist_remove(task_list, task);
disable_network(task);