int wpa_ie_len;
unsigned char rsn_ie[40];
int rsn_ie_len;
+
+ int has_wep;
+ int has_wpa;
+ int has_rsn;
};
struct iface_data {
char ifname[IFNAMSIZ];
GSList *stations;
+
+ gchar *network;
+ gchar *passphrase;
};
+static void report_station(struct connman_iface *iface,
+ struct station_data *station)
+{
+ int security = 0;
+
+ if (station == NULL)
+ return;
+
+ if (station->name == NULL)
+ return;
+
+ if (station->has_wep)
+ security |= 0x01;
+ if (station->has_wpa)
+ security |= 0x02;
+ if (station->has_rsn)
+ security |= 0x04;
+
+ connman_iface_indicate_station(iface, station->name,
+ station->qual, security);
+}
+
static struct station_data *create_station(struct iface_data *iface,
const char *address)
{
// station->address, station->mode,
// station->name, station->qual);
+ if (station->name == NULL)
+ continue;
+
g_key_file_set_string(keyfile, station->address,
"Name", station->name);
connman_iface_set_data(iface, NULL);
- free(data);
-}
+ g_free(data->network);
+ g_free(data->passphrase);
-static int iface_activate(struct connman_iface *iface)
-{
- struct iface_data *data = connman_iface_get_data(iface);
-
- printf("[802.11] activate %s\n", data->ifname);
-
- connman_iface_update(iface, CONNMAN_IFACE_STATE_ACTIVE);
-
- return 0;
+ free(data);
}
static int iface_scan(struct connman_iface *iface)
static int iface_connect(struct connman_iface *iface,
struct connman_network *network)
{
- printf("[802.11] connect interface index %d\n", iface->index);
+ struct iface_data *data = connman_iface_get_data(iface);
+
+ printf("[802.11] connect %s\n", data->ifname);
__supplicant_start(iface);
- __supplicant_connect(iface);
+ if (data->network != NULL)
+ __supplicant_connect(iface, data->network, data->passphrase);
+
+ return 0;
+}
+
+static int iface_disconnect(struct connman_iface *iface)
+{
+ struct iface_data *data = connman_iface_get_data(iface);
+
+ printf("[802.11] disconnect %s\n", data->ifname);
+
+ if (data->network != NULL)
+ __supplicant_disconnect(iface);
+
+ __supplicant_stop(iface);
return 0;
}
-static void iface_carrier(struct connman_iface *iface, int carrier)
+static void iface_set_network(struct connman_iface *iface,
+ const char *network)
{
- printf("[802.11] carrier %s\n", carrier ? "on" : "off");
+ struct iface_data *data = connman_iface_get_data(iface);
+
+ printf("[802.11] set network %s\n", data->ifname);
+
+ if (data->network != NULL)
+ __supplicant_disconnect(iface);
- connman_iface_indicate_carrier(iface, carrier);
+ g_free(data->network);
+
+ data->network = g_strdup(network);
+
+ if (data->network != NULL)
+ __supplicant_connect(iface, data->network, data->passphrase);
+}
+
+static void iface_set_passphrase(struct connman_iface *iface,
+ const char *passphrase)
+{
+ struct iface_data *data = connman_iface_get_data(iface);
+
+ printf("[802.11] set passphrase %s\n", data->ifname);
+
+ if (data->network != NULL)
+ __supplicant_disconnect(iface);
+
+ g_free(data->passphrase);
+
+ data->passphrase = g_strdup(passphrase);
+
+ if (data->network != NULL)
+ __supplicant_connect(iface, data->network, data->passphrase);
}
static void parse_genie(struct station_data *station,
switch (data[offset]) {
case 0xdd: /* WPA1 (and other) */
+ station->has_wpa = 1;
break;
case 0x30: /* WPA2 (RSN) */
+ station->has_rsn = 1;
break;
default:
break;
switch (event->cmd) {
case SIOCGIWAP:
+ report_station(iface, station);
eth = (void *) &event->u.ap_addr.sa_data;
sprintf(addr, "%02X:%02X:%02X:%02X:%02X:%02X",
eth->ether_addr_octet[0],
break;
case SIOCGIWESSID:
if (station != NULL) {
- station->name = malloc(event->len - 7);
+ station->name = malloc(event->len - IW_EV_POINT_LEN + 1);
if (station->name != NULL) {
- memset(station->name, 0, event->len - 7);
- memcpy(station->name, ptr + 8,
- event->len - 8);
+ memset(station->name, 0,
+ event->len - IW_EV_POINT_LEN + 1);
+ memcpy(station->name, ptr + IW_EV_POINT_LEN,
+ event->len - IW_EV_POINT_LEN);
}
}
break;
break;
case SIOCGIWENCODE:
if (station != NULL) {
- if (!(event->u.data.flags & IW_ENCODE_DISABLED)) {
- /* privacy */
- }
+ if (!(event->u.data.flags & IW_ENCODE_DISABLED))
+ station->has_wep = 1;
}
break;
case SIOCGIWRATE:
len -= event->len;
}
+ report_station(iface, station);
+
printf("[802.11] found %d networks\n", num);
}
{
struct iface_data *data = connman_iface_get_data(iface);
struct iwreq iwr;
- unsigned char *buf;
- int sk, err, size = 1024;
+ void *buf;
+ size_t size;
+ int sk, err, done = 0;
+
+ if (data == NULL)
+ return;
+
+ memset(&iwr, 0, sizeof(iwr));
+ memcpy(iwr.ifr_name, data->ifname, IFNAMSIZ);
sk = socket(PF_INET, SOCK_DGRAM, 0);
if (sk < 0)
return;
-retrieve:
- buf = malloc(size);
- if (buf == NULL) {
- close(sk);
- return;
- }
+ buf = NULL;
+ size = 1024;
- memset(&iwr, 0, sizeof(iwr));
- strncpy(iwr.ifr_name, data->ifname, IFNAMSIZ);
- iwr.u.data.pointer = buf;
- iwr.u.data.length = size;
- iwr.u.data.flags = 0;
-
- err = ioctl(sk, SIOCGIWSCAN, &iwr);
- if (err < 0) {
- if (errno == E2BIG) {
- free(buf);
- size *= 2;
- goto retrieve;
+ while (!done) {
+ void *newbuf;
+
+ newbuf = g_realloc(buf, size);
+ if (newbuf == NULL) {
+ close(sk);
+ return;
}
- } else
- parse_scan_results(iface, iwr.u.data.pointer,
- iwr.u.data.length);
- close(sk);
+ buf = newbuf;
+ iwr.u.data.pointer = buf;
+ iwr.u.data.length = size;
+ iwr.u.data.flags = 0;
+
+ err = ioctl(sk, SIOCGIWSCAN, &iwr);
+ if (err < 0) {
+ if (errno == E2BIG)
+ size *= 2;
+ else
+ done = 1;
+ } else {
+ parse_scan_results(iface, iwr.u.data.pointer,
+ iwr.u.data.length);
+ done = 1;
+ }
+ }
- free(buf);
+ g_free(buf);
+
+ close(sk);
print_stations(data);
}
.capability = "net.80211",
.probe = iface_probe,
.remove = iface_remove,
- .activate = iface_activate,
.scan = iface_scan,
.connect = iface_connect,
- .rtnl_carrier = iface_carrier,
+ .disconnect = iface_disconnect,
+ .set_network = iface_set_network,
+ .set_passphrase = iface_set_passphrase,
.rtnl_wireless = iface_wireless,
};