X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=wifiscand%2Fwifiscand.c;h=d0df690f3053a982e8fd332a8d07ba5c942b17c0;hb=759aacbbfcca9659b56081eaf37dbeaf235a397f;hp=3fb489a11b4b5a85b75e74049c2636cd48ac573a;hpb=ab35928654d40aade3083969cc807e051e9f523d;p=wifihood diff --git a/wifiscand/wifiscand.c b/wifiscand/wifiscand.c index 3fb489a..d0df690 100644 --- a/wifiscand/wifiscand.c +++ b/wifiscand/wifiscand.c @@ -1,9 +1,46 @@ #include +#ifdef HAVE_LIBOSSO #include - -#define WIFISCAND_VERSION_STRING "1.0" +#else +#include +#include + +#define WIFISCAN_INTROSPECTION "\n\ +\n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ + \n\ +\n" + +#define OSSO_OK 0 +#define OSSO_ERROR 1 + +#define osso_context_t DBusConnection +typedef struct osso_rpc_t_values { + int i; + char *s; + } osso_rpc_t_values; +typedef struct osso_rpc_t { + int type; + osso_rpc_t_values value; + } osso_rpc_t; +#endif + +#define WIFISCAND_VERSION_STRING "1.1" #define OSSO_NAME "wifiscan" #define OSSO_SERVICE "org.javiplx."OSSO_NAME @@ -27,162 +64,63 @@ typedef struct { /* ------------------------------------------------------------------ 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); - - 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; + iw_get_range_info(wlan->sock, wlan->ifname, &range); - FD_ZERO(&rfds); - last_fd = -1; + /* We don't call iw_scan to allow fine control of delays and timeouts */ + context.result = NULL; + context.retry = 0; - 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; - } + while(delay>0) { + delay = iw_process_scan(wlan->sock, wlan->ifname, range.we_version_compiled, &context); + if(delay < 0) break; + usleep(delay * 1000); } - if(!ret) { - unsigned char* newbuf; + if ( delay == 0 ) { - 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; + int i = 1; // To acount for the final NULL + struct wireless_scan *ap = context.result; + while ( ap != NULL ) { + ap = ap->next; + i++; } - - else break; - } - } + scan = (ScanInfo**) malloc( i * sizeof(ScanInfo *) ); + memset(scan, 0, i * sizeof(ScanInfo *) ); + ScanInfo **sc = scan; - 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++; - } + /* Extract values */ + ap = context.result; + while ( ap != NULL ) { + WirelessInterface_ScanItem(ap, sc++); + ap = ap->next; } - } - - while(ret > 0); } else { message = "Unknown error"; - free(buffer); - return NULL; } - free(buffer); return scan; } @@ -211,6 +149,11 @@ struct _AppData { osso_context_t *osso_context; }; +#ifdef HAVE_LIBOSSO +static GMainLoop *event_loop = NULL; +#endif +static short int start_flags = 0; + /* Callback for normal D-BUS messages */ gint dbus_req_handler(const gchar * interface, const gchar * method, GArray * arguments, gpointer data, @@ -223,21 +166,85 @@ gint dbus_req_handler(const gchar * interface, const gchar * method, retval->value.s = (gchar*) malloc( sizeof(gchar *) ); retval->value.s[0] = '\0'; +#ifndef HAVE_LIBOSSO + if ( strcmp(method,"Introspect")==0 ) { + retval->value.s = (gchar *) realloc(retval->value.s,630*sizeof(gchar *)); + snprintf(retval->value.s,strlen(WIFISCAN_INTROSPECTION),WIFISCAN_INTROSPECTION); + return OSSO_OK; + } +#endif + + if ( strcmp(method,"wakeup")==0 ) { + retval->value.s = (gchar *) realloc(retval->value.s,16*sizeof(gchar *)); + snprintf(retval->value.s,16,"WifiScand ready"); + return OSSO_OK; + } + if ( strcmp(method,"start")==0 ) { - // osso_system_note_infoprint(appdata->osso_context, "Starting WifiScan", NULL); + + if( (appdata->iface.sock=iw_sockets_open()) < 0) { + retval->value.s = (gchar *) realloc(retval->value.s,33*sizeof(gchar *)); + snprintf(retval->value.s,33,"Failure in socket initialization"); + return OSSO_ERROR; + } + + /* Get range stuff */ + iwrange range; + int has_range = (iw_get_range_info(appdata->iface.sock, appdata->iface.ifname, &range) >= 0); + + /* Check if the interface could support scanning. */ + if((!has_range) || (range.we_version_compiled < 14)) { + retval->value.s = (gchar *) realloc(retval->value.s,35*sizeof(gchar *)); + snprintf(retval->value.s,35,"Interface doesn't support scanning"); + return OSSO_ERROR; + } + + struct ifreq frq; + strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ); + if(ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) { + retval->value.s = (gchar *) realloc(retval->value.s,28*sizeof(gchar *)); + snprintf(retval->value.s,28,"Cannot get interface status"); + return OSSO_ERROR; + } + + start_flags = frq.ifr_flags; + frq.ifr_flags |= IFF_UP | IFF_RUNNING; + + if(ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq)) { + retval->value.s = (gchar *) realloc(retval->value.s,27*sizeof(gchar *)); + snprintf(retval->value.s,27,"Cannot set interface state"); + return OSSO_ERROR; + } + + refresh(&appdata->iface); + retval->value.s = (gchar *) realloc(retval->value.s,22*sizeof(gchar *)); + snprintf(retval->value.s,22,"Interface initialized"); return OSSO_OK; } if ( strcmp(method,"stop")==0 ) { + struct ifreq frq; + strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ); + if(!ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) { + frq.ifr_flags = start_flags; + if(!ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq)) + refresh(&appdata->iface); + } iw_sockets_close(appdata->iface.sock); appdata->iface.sock = 0; - // osso_system_note_infoprint(appdata->osso_context, "Stopping WifiScan", NULL); +#ifdef HAVE_LIBOSSO osso_deinitialize(appdata->osso_context); + /* Instead of exiting, signaling finish to main loop could be better + retval->value.s = (gchar *) realloc(retval->value.s,34*sizeof(gchar *)); + snprintf(retval->value.s,34,"Interface moved to original state"); + */ exit(0); +#else + return OSSO_OK; +#endif } 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) { @@ -246,15 +253,19 @@ gint dbus_req_handler(const gchar * interface, const gchar * method, 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 *)); + int i = 0; + while ( *(scan+i) != NULL ) i++; + retval->value.s = (gchar *) malloc( (22*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); + } + memset(retval->value.s, '\0', (22*i+1) * sizeof(gchar *) ); + i = 0; + while ( *scan != NULL ) { + sprintf(retval->value.s+(22*i),"%s:%d ",(*scan)->mac,(*scan)->rssi); + scan++; + i++; } retval->value.s[strlen(retval->value.s)-1] = '\0'; @@ -266,17 +277,99 @@ gint dbus_req_handler(const gchar * interface, const gchar * method, return OSSO_ERROR; } -static GMainLoop *event_loop = NULL; +#ifndef HAVE_LIBOSSO + +dbus_bool_t stopped_service = FALSE; + +static DBusObjectPathVTable *vtable = NULL; + +int dbus_set_cb_f( DBusConnection *context, + const char *service, const char *object, + const char *interface, void *handler, // FIXME : Set proper type for handler + void *user_data) { + + /* First, we prepare the complex dbus handler structures */ + DBusObjectPathVTable *vtable = malloc( sizeof(DBusObjectPathVTable) ); + memset(vtable , '\0', sizeof(DBusObjectPathVTable) ); + vtable->message_function = (DBusObjectPathMessageFunction) handler; // FIXME : Aqui va el nuevo handler/wrapper + + if (!dbus_connection_register_fallback(context, object, vtable, user_data)) { + return OSSO_ERROR; + } + + DBusError error; + dbus_error_init(&error); + + dbus_bus_request_name (context, service, 0, &error); + if ( dbus_error_is_set(&error) ) { + dbus_error_free (&error); + return OSSO_ERROR; + } + + dbus_error_free (&error); + return OSSO_OK; +} + +void dbus_deinitialize( DBusConnection *context ) { + free(vtable); vtable = NULL; + dbus_connection_unref(context); + dbus_shutdown(); +} + +static DBusHandlerResult handler_wrapper (DBusConnection *connection, + DBusMessage *message, + void *data) { + + gint retcode; + osso_rpc_t *retval = malloc(sizeof(osso_rpc_t)); + + if ( dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ) { + retcode = dbus_req_handler(dbus_message_get_interface(message), + dbus_message_get_member(message), + NULL, data, retval); + + if ( strcmp(dbus_message_get_member(message),"stop")==0 ) + stopped_service = TRUE; + + if ( retval->value.s != NULL ) { + DBusMessage *reply = dbus_message_new_method_return (message); + if (reply == NULL) + exit(0); + if (!dbus_message_append_args (reply, DBUS_TYPE_STRING, &retval->value.s, DBUS_TYPE_INVALID)) + exit(0); + if (!dbus_connection_send (connection, reply, NULL)) + exit(0); + dbus_message_unref (reply); + } + + } + + return DBUS_HANDLER_RESULT_HANDLED; +} + +#endif int main( void ) { osso_context_t *osso_context; +#ifndef HAVE_LIBOSSO + DBusError error; +#endif /* Initialize maemo application */ +#ifdef HAVE_LIBOSSO osso_context = osso_initialize(OSSO_NAME, WIFISCAND_VERSION_STRING, TRUE, NULL); +#else + dbus_error_init(&error); + osso_context = dbus_bus_get(DBUS_BUS_SESSION, &error); +#endif /* Check that initialization was ok */ if (osso_context == NULL) { +#ifndef HAVE_LIBOSSO + fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n", error.message); + dbus_error_free (&error); +#endif exit(OSSO_ERROR); } @@ -290,41 +383,34 @@ int main( void ) { appdata->iface.sock = 0; /* Add handler for hello D-BUS messages */ +#ifdef HAVE_LIBOSSO osso_return_t result = osso_rpc_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, dbus_req_handler, appdata); +#else + int result = dbus_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, handler_wrapper, appdata); +#endif + if (result != OSSO_OK) { +#ifdef HAVE_LIBOSSO osso_system_note_infoprint(appdata->osso_context, "Failure while setting OSSO callback", NULL); +#endif 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 */ +#ifdef HAVE_LIBOSSO event_loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(event_loop); +#else + while (dbus_connection_read_write_dispatch(osso_context, -1) && stopped_service==FALSE) {} +#endif /* Deinitialize OSSO */ +#ifdef HAVE_LIBOSSO osso_deinitialize(osso_context); +#else + dbus_deinitialize(osso_context); +#endif exit(0); }