/* ------------------------------------------------------------------ WirelessInterface_ScanItem */
-static int WirelessInterface_ScanItem(struct iw_event* event, ScanInfo **scaninfo) {
-
- switch(event->cmd) {
-
- case SIOCGIWAP: {
+void WirelessInterface_ScanItem(struct wireless_scan* ap, ScanInfo **scaninfo) {
*scaninfo = (ScanInfo*) malloc( sizeof(ScanInfo) );
memset(*scaninfo, 0, sizeof(ScanInfo) );
- iw_ether_ntop( (const struct ether_addr*)(event->u.ap_addr.sa_data), (*scaninfo)->mac);
- return 1;
- }
+ iw_sawap_ntop( &ap->ap_addr, (*scaninfo)->mac);
- case IWEVQUAL: {
- (*scaninfo)->rssi = event->u.qual.level - 0x100;
- return 0;
- }
+ (*scaninfo)->rssi = ap->stats.qual.level - 0x100;
+ (*scaninfo)->noise = ap->stats.qual.level - 0x100;
- default: {
- return 0;
- }
- }
}
/* ---------------------------------------------------------------------- */
-void* makeScan(WirelessInterface* coso, gchar *message) {
- struct iwreq wrq;
- unsigned char* buffer = NULL;
- int buflen = IW_SCAN_MAX_DATA;
+void* makeScan(WirelessInterface* wlan, gchar *message) {
+ wireless_scan_head context;
iwrange range;
- int has_range;
- struct timeval tv;
- int timeout = 10000000;
+ int delay = 1;
ScanInfo **scan = NULL;
- has_range = (iw_get_range_info(coso->sock, coso->ifname, &range) >= 0);
+ iw_get_range_info(wlan->sock, wlan->ifname, &range);
- tv.tv_sec = 0;
- tv.tv_usec = 250000;
- wrq.u.data.pointer = NULL;
- wrq.u.data.flags = 0;
- wrq.u.data.length = 0;
+ /* We don't call iw_scan to allow fine control of delays and timeouts */
+ context.result = NULL;
+ context.retry = 0;
- if(iw_set_ext(coso->sock, coso->ifname, SIOCSIWSCAN, &wrq) < 0) {
- if(errno != EPERM) {
- message = "Interface doesn't support scanning";
- return NULL;
+ while(delay>0) {
+ delay = iw_process_scan(wlan->sock, wlan->ifname, range.we_version_compiled, &context);
+ if(delay < 0) break;
+ usleep(delay * 1000);
}
- tv.tv_usec = 0;
- }
- timeout -= tv.tv_usec;
- while(1) {
- fd_set rfds;
- int last_fd;
- int ret;
-
- FD_ZERO(&rfds);
- last_fd = -1;
-
- ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);
-
- if(ret < 0) {
- if(errno == EAGAIN || errno == EINTR) continue;
-
- else {
- message = "Unknown scanning error";
- return NULL;
- }
- }
+ if ( delay == 0 ) {
- if(!ret) {
- unsigned char* newbuf;
-
- realloc:
- newbuf = (unsigned char*) realloc(buffer, buflen);
-
- if(!newbuf) {
- if(buffer) free(buffer);
- message = "Memory allocation failure in scan";
- return NULL;
- }
-
- buffer = newbuf;
-
- wrq.u.data.pointer = buffer;
- wrq.u.data.flags = 0;
- wrq.u.data.length = buflen;
-
- if(iw_get_ext(coso->sock, coso->ifname, SIOCGIWSCAN, &wrq) < 0) {
- if((errno == E2BIG)) {
- if(wrq.u.data.length > buflen) buflen = wrq.u.data.length;
- else buflen *= 2;
-
- goto realloc;
- }
-
- if(errno == EAGAIN) {
- tv.tv_sec = 0;
- tv.tv_usec = 100000;
- timeout -= tv.tv_usec;
-
- if(timeout > 0) continue;
- }
-
- free(buffer);
-
- message = "Unable to read scan data";
-
- return NULL;
- }
-
- else break;
- }
- }
-
-
- if(wrq.u.data.length) {
- struct iw_event iwe;
- stream_descr stream;
- int ret;
- void* scan_dict = NULL;
-
- iw_init_event_stream(&stream, (char*)(buffer), wrq.u.data.length);
-
scan = (ScanInfo**) malloc( 25 * sizeof(ScanInfo *) );
memset(scan, 0, 25 * sizeof(ScanInfo *) );
*scan = NULL;
i = 0;
ScanInfo *sc = NULL;
- do {
- ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled);
-
- if(ret > 0) {
- int sr = WirelessInterface_ScanItem(&iwe, &sc);
- if(sr && i<25) {
+
+ /* Extract values */
+ struct wireless_scan *ap = context.result;
+ while ( ap != NULL && i < 25 ) {
+ WirelessInterface_ScanItem(ap, &sc);
*(scan+i) = sc;
+ ap = ap->next;
i++;
- }
}
- }
-
- while(ret > 0);
} else {
message = "Unknown error";
- free(buffer);
- return NULL;
}
- free(buffer);
return scan;
}