Added scanner application
authorjaviplx <javiplx@gmail.com>
Thu, 13 May 2010 12:12:50 +0000 (12:12 +0000)
committerjaviplx <javiplx@gmail.com>
Thu, 13 May 2010 12:12:50 +0000 (12:12 +0000)
git-svn-id: file:///svnroot/wifihood/trunk@1 c51dfc6a-5949-4919-9c8e-f207a149c383

wifiscand/Makefile [new file with mode: 0644]
wifiscand/debian/changelog [new file with mode: 0644]
wifiscand/debian/control [new file with mode: 0644]
wifiscand/debian/dirs [new file with mode: 0644]
wifiscand/debian/postinst [new file with mode: 0644]
wifiscand/debian/rules [new file with mode: 0755]
wifiscand/do_scan [new file with mode: 0755]
wifiscand/do_stop [new file with mode: 0755]
wifiscand/wifiscand.c [new file with mode: 0644]
wifiscand/wifiscand.service [new file with mode: 0644]

diff --git a/wifiscand/Makefile b/wifiscand/Makefile
new file mode 100644 (file)
index 0000000..80f7f27
--- /dev/null
@@ -0,0 +1,9 @@
+
+LDFLAGS = -liw $(shell pkg-config --libs libosso)
+
+CPPFLAGS = $(shell pkg-config --cflags libosso)
+
+default: wifiscand
+
+clean:
+       @rm -rf wifiscand
diff --git a/wifiscand/debian/changelog b/wifiscand/debian/changelog
new file mode 100644 (file)
index 0000000..0e4321f
--- /dev/null
@@ -0,0 +1,6 @@
+wifiscand (1.0-1) fremantle; urgency=low
+
+  * First release
+
+ -- Javier Palacios <javiplx@gmail.com>  Mon,  3 May 2010 23:05:51 +0200
+
diff --git a/wifiscand/debian/control b/wifiscand/debian/control
new file mode 100644 (file)
index 0000000..51f4c38
--- /dev/null
@@ -0,0 +1,13 @@
+Source: wifiscand
+Section: main
+Priority: optional
+Maintainer: Javier Palacios <javiplx@gmai.com>
+Build-Depends: libiw-dev, libosso-dev, debhelper (>= 4.0.0)
+Standards-Version: 3.6.1
+
+Package: wifiscand
+Architecture: any
+Depends: libiw30, libosso1, ${shlibs:Depends}, ${misc:Depends}
+Description: Wireless Scanning daemon
+ OSSO/DBus service for wireless scanning
+
diff --git a/wifiscand/debian/dirs b/wifiscand/debian/dirs
new file mode 100644 (file)
index 0000000..74fe76b
--- /dev/null
@@ -0,0 +1,2 @@
+usr/sbin
+usr/share/dbus-1/services
diff --git a/wifiscand/debian/postinst b/wifiscand/debian/postinst
new file mode 100644 (file)
index 0000000..0eb96fa
--- /dev/null
@@ -0,0 +1,28 @@
+#! /bin/sh
+# postinst script for osso-wlan
+#
+# see: dh_installdeb(1)
+
+#set -e
+
+case "$1" in
+    install|upgrade|configure)
+        # Debhelper invoked update-rc.d won't work without this
+        chmod u+s /usr/sbin/wifiscand
+        ;;
+
+    abort-upgrade)
+        ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+        ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.
+
+#DEBHELPER#
+
+exit 0
diff --git a/wifiscand/debian/rules b/wifiscand/debian/rules
new file mode 100755 (executable)
index 0000000..a0870df
--- /dev/null
@@ -0,0 +1,98 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+
+
+
+CFLAGS = -Wall -g
+
+ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
+       CFLAGS += -O0
+else
+       CFLAGS += -O2
+endif
+
+configure: configure-stamp
+configure-stamp:
+       dh_testdir
+       # Add here commands to configure the package.
+
+       touch configure-stamp
+
+
+build: build-stamp
+
+build-stamp: configure-stamp 
+       dh_testdir
+
+       # Add here commands to compile the package.
+       $(MAKE)
+
+       touch build-stamp
+
+clean:
+       dh_testdir
+       dh_testroot
+       rm -f build-stamp configure-stamp
+
+       # Add here commands to clean up after the build process.
+       -$(MAKE) clean
+
+       dh_clean 
+
+install: build
+       dh_testdir
+       dh_testroot
+       dh_clean -k 
+       dh_installdirs
+
+       # Add here commands to install the package into debian/tmp
+       cp wifiscand $(CURDIR)/debian/tmp/usr/sbin
+       cp wifiscand.service $(CURDIR)/debian/tmp/usr/share/dbus-1/services
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+       dh_testdir
+       dh_testroot
+       dh_installchangelogs 
+       dh_installdocs
+       dh_installexamples
+#      dh_install
+#      dh_installmenu
+#      dh_installdebconf       
+#      dh_installlogrotate
+#      dh_installemacsen
+#      dh_installpam
+#      dh_installmime
+#      dh_installinit
+#      dh_installcron
+#      dh_installinfo
+       dh_installman
+       dh_link
+       dh_strip
+       dh_compress
+       dh_fixperms
+#      dh_perl
+#      dh_python
+#      dh_makeshlibs
+       dh_installdeb
+       dh_shlibdeps
+       dh_gencontrol
+       dh_md5sums
+       dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/wifiscand/do_scan b/wifiscand/do_scan
new file mode 100755 (executable)
index 0000000..e560569
--- /dev/null
@@ -0,0 +1,17 @@
+#!/usr/bin/python
+
+import osso
+
+osso_context = osso.Context("test_scanner", "1.0", False)
+osso_rpc = osso.Rpc(osso_context)
+
+scan = osso_rpc.rpc_run("org.javiplx.wifiscan", "/org/javiplx/wifiscan", "org.javiplx.wifiscan", "scan", wait_reply = True)
+
+fps = {}
+for fingerprint in scan.split(" ") :
+    items = fingerprint.split(":")
+    rssi = int( items.pop() )
+    if rssi != -256 :
+        fps["".join(items)] = rssi
+print fps
+
diff --git a/wifiscand/do_stop b/wifiscand/do_stop
new file mode 100755 (executable)
index 0000000..ce3c298
--- /dev/null
@@ -0,0 +1,9 @@
+#!/usr/bin/python
+
+import osso
+
+osso_context = osso.Context("test_scanner", "1.0", False)
+osso_rpc = osso.Rpc(osso_context)
+
+osso_rpc.rpc_run("org.javiplx.wifiscan", "/org/javiplx/wifiscan", "org.javiplx.wifiscan", "stop")
+
diff --git a/wifiscand/wifiscand.c b/wifiscand/wifiscand.c
new file mode 100644 (file)
index 0000000..3fb489a
--- /dev/null
@@ -0,0 +1,331 @@
+
+#include <iwlib.h>
+
+#include <libosso.h>
+
+#define WIFISCAND_VERSION_STRING  "1.0"
+
+#define OSSO_NAME    "wifiscan"
+#define OSSO_SERVICE "org.javiplx."OSSO_NAME
+#define OSSO_OBJECT  "/org/javiplx/"OSSO_NAME
+#define OSSO_IFACE   "org.javiplx."OSSO_NAME
+
+
+typedef struct {
+       char          mac[18];
+       int           rssi;
+       int           noise;
+} ScanInfo;
+
+
+/* --------------------------------------------------------------------------- WirelessInterface */
+typedef struct {
+       wireless_info info;
+       char*         ifname;
+       int           sock;
+} WirelessInterface;
+
+/* ------------------------------------------------------------------ WirelessInterface_ScanItem */
+
+static int WirelessInterface_ScanItem(struct iw_event* event, ScanInfo **scaninfo) {
+
+       switch(event->cmd) {
+                                 
+               case SIOCGIWAP: {
+
+                       *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;
+               }
+
+               case IWEVQUAL: {
+                       (*scaninfo)->rssi = event->u.qual.level - 0x100;
+                       return 0;
+               }
+
+               default: {
+                        return 0;
+                }
+       }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void* makeScan(WirelessInterface* coso, gchar *message) {
+       struct iwreq          wrq;
+       unsigned char* buffer     = NULL;
+       int            buflen     = IW_SCAN_MAX_DATA;
+       iwrange        range;
+       int            has_range;
+       struct timeval        tv;
+       int            timeout    = 10000000;
+
+       ScanInfo        **scan = NULL;
+
+       has_range = (iw_get_range_info(coso->sock, coso->ifname, &range) >= 0);
+
+       tv.tv_sec          = 0;
+       tv.tv_usec         = 250000;
+       wrq.u.data.pointer = NULL;
+       wrq.u.data.flags   = 0;
+       wrq.u.data.length  = 0;
+
+       if(iw_set_ext(coso->sock, coso->ifname, SIOCSIWSCAN, &wrq) < 0) {
+               if(errno != EPERM) {
+                       message = "Interface doesn't support scanning";
+                       return NULL;
+               }
+               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(!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;
+               int i;
+               for (i=0; i<25; i++) *(scan+i) = 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) {
+                                       *(scan+i) = sc;
+                                       i++;
+                               }
+                       }
+               }
+               
+               while(ret > 0);
+
+       } else {
+               message = "Unknown error";
+               free(buffer);
+               return NULL;
+       }
+
+       free(buffer);
+       return scan;
+}
+
+static void refresh(WirelessInterface* coso) {
+       struct iwreq wrq;
+       
+       iw_get_basic_config(coso->sock, coso->ifname, &(coso->info.b));
+       iw_get_range_info(coso->sock, coso->ifname, &(coso->info.range));
+
+       iw_get_ext(coso->sock, coso->ifname, SIOCGIWRATE, &wrq);
+       memcpy(&(coso->info.bitrate), &wrq.u.bitrate, sizeof(iwparam));
+
+       iw_get_ext(coso->sock, coso->ifname, SIOCGIWAP, &wrq);
+       memcpy(&(coso->info.ap_addr), &wrq.u.ap_addr, sizeof (sockaddr));
+
+       iw_get_stats(
+               coso->sock, coso->ifname, &(coso->info.stats), 
+               &(coso->info.range), coso->info.has_range
+       );
+}
+
+/* Application UI data struct */
+typedef struct _AppData AppData;
+struct _AppData {
+    WirelessInterface iface;
+    osso_context_t *osso_context;
+};
+
+/* Callback for normal D-BUS messages */
+gint dbus_req_handler(const gchar * interface, const gchar * method,
+                      GArray * arguments, gpointer data,
+                      osso_rpc_t * retval)
+{
+    AppData *appdata;
+    appdata = (AppData *) data;
+
+    retval->type = DBUS_TYPE_STRING;
+    retval->value.s = (gchar*) malloc( sizeof(gchar *) );
+    retval->value.s[0] = '\0';
+
+    if ( strcmp(method,"start")==0 ) {
+    //    osso_system_note_infoprint(appdata->osso_context, "Starting WifiScan", NULL);
+        return OSSO_OK;
+    }
+
+    if ( strcmp(method,"stop")==0 ) {
+        iw_sockets_close(appdata->iface.sock);
+       appdata->iface.sock = 0;
+    //    osso_system_note_infoprint(appdata->osso_context, "Stopping WifiScan", NULL);
+        osso_deinitialize(appdata->osso_context);
+        exit(0);
+    }
+
+    if ( strcmp(method,"scan")==0 ) {
+    //    osso_system_note_infoprint(appdata->osso_context, "Scanning ...", NULL);
+
+        ScanInfo **scan = (ScanInfo **) makeScan(&appdata->iface,retval->value.s);
+        if(scan == NULL) {
+            retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *));
+            snprintf(retval->value.s,64,"ERROR");
+            return OSSO_ERROR;
+        }
+
+        int i;
+        for (i=0; i<25&&*(scan+i)!=NULL; i++) {
+            ScanInfo* sc = *(scan+i);
+            retval->value.s = (gchar *) realloc(retval->value.s,23*(i+1)*sizeof(gchar *));
+           if ( retval->value.s == NULL ) {
+                retval->value.s = "Error allocating memory";
+                return OSSO_ERROR;
+           }
+            sprintf(retval->value.s+strlen(retval->value.s),"%s:%d ",sc->mac,sc->rssi);
+        }
+
+        retval->value.s[strlen(retval->value.s)-1]  = '\0';
+        return OSSO_OK;
+    }
+
+    retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *));
+    snprintf(retval->value.s,64,"Unknown method");
+    return OSSO_ERROR;
+}
+
+static GMainLoop *event_loop = NULL;
+
+int main( void ) {
+
+       osso_context_t *osso_context;
+
+       /* Initialize maemo application */
+       osso_context = osso_initialize(OSSO_NAME, WIFISCAND_VERSION_STRING, TRUE, NULL);
+
+       /* Check that initialization was ok */
+       if (osso_context == NULL) {
+               exit(OSSO_ERROR);
+               }
+
+       /* Create AppData */
+       AppData *appdata;
+       appdata = g_new0(AppData, 1);
+       appdata->osso_context = osso_context;
+
+       memset(&(appdata->iface.info), 0, sizeof(wireless_info));
+       appdata->iface.ifname = "wlan0";
+       appdata->iface.sock   = 0;
+
+       /* Add handler for hello D-BUS messages */
+       osso_return_t result = osso_rpc_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, dbus_req_handler, appdata);
+       if (result != OSSO_OK) {
+               osso_system_note_infoprint(appdata->osso_context, "Failure while setting OSSO callback", NULL);
+               return OSSO_ERROR;
+       }
+
+       /* INITIALIZATION */
+       appdata->iface.sock = iw_sockets_open();
+
+       if(appdata->iface.sock < 0) {
+               osso_system_note_infoprint(osso_context, "Failure in socket initialization", NULL);
+               return OSSO_ERROR;
+       }
+
+       struct ifreq frq;
+
+       strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ);
+                       
+       if(ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) {
+               osso_system_note_infoprint(osso_context, "Cannot scan", NULL);
+               return OSSO_ERROR;
+       }
+
+       frq.ifr_flags |= IFF_UP | IFF_RUNNING;
+               
+       ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq);
+                       
+       refresh(&appdata->iface);
+       /* INITIALIZATION FINISH */
+
+       event_loop = g_main_loop_new(NULL, FALSE);
+       g_main_loop_run(event_loop);
+
+       /* Deinitialize OSSO */
+       osso_deinitialize(osso_context);
+
+       exit(0);
+}
+
diff --git a/wifiscand/wifiscand.service b/wifiscand/wifiscand.service
new file mode 100644 (file)
index 0000000..e8beff8
--- /dev/null
@@ -0,0 +1,4 @@
+[D-BUS Service]
+Name=org.javiplx.wifiscan
+Exec=/usr/sbin/wifiscand
+User=root