X-Git-Url: http://vcs.maemo.org/git/?a=blobdiff_plain;f=wifiscand%2Fwifiscand.c;h=d0df690f3053a982e8fd332a8d07ba5c942b17c0;hb=42fb4f3fd9cd4c79b1cc4b32a0db9bfa29bfb8ca;hp=abc067cd35c8953e377022c5331a8d0f41b0abc2;hpb=1c67de4a8fdb2d1aaf9da228663ad4658a9ae7f8;p=wifihood diff --git a/wifiscand/wifiscand.c b/wifiscand/wifiscand.c index abc067c..d0df690 100644 --- a/wifiscand/wifiscand.c +++ b/wifiscand/wifiscand.c @@ -6,11 +6,29 @@ #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 -#endif -#ifndef HAVE_LIBOSSO #define osso_context_t DBusConnection typedef struct osso_rpc_t_values { int i; @@ -46,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); + 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 ( delay == 0 ) { - 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; + 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; } @@ -235,70 +154,11 @@ static GMainLoop *event_loop = NULL; #endif static short int start_flags = 0; -#ifndef HAVE_LIBOSSO -int submit_reply_message(DBusConnection *connection, DBusMessage *message, char *string) { - DBusMessage *reply = dbus_message_new_method_return (message); - if (reply == NULL) - exit(0); - if (!dbus_message_append_args (reply, DBUS_TYPE_STRING, &string, DBUS_TYPE_INVALID)) - exit(0); - if (!dbus_connection_send (connection, reply, NULL)) - exit(0); - dbus_message_unref (reply); - return DBUS_HANDLER_RESULT_HANDLED; -} - -static DBusObjectPathVTable *vtable = NULL; - -int dbus_set_cb_f( DBusConnection *context, - const char *service, const char *object, - const char *interface, void *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; - - 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(); -} -#endif - /* Callback for normal D-BUS messages */ -#ifdef HAVE_LIBOSSO gint dbus_req_handler(const gchar * interface, const gchar * method, GArray * arguments, gpointer data, osso_rpc_t * retval) -#else -static DBusHandlerResult dbus_req_handler (DBusConnection *connection, - DBusMessage *message, - void *data) -#endif { -#ifndef HAVE_LIBOSSO - osso_rpc_t *retval = malloc(sizeof(osso_rpc_t)); -#endif - AppData *appdata; appdata = (AppData *) data; @@ -306,34 +166,37 @@ static DBusHandlerResult dbus_req_handler (DBusConnection *connection, retval->value.s = (gchar*) malloc( sizeof(gchar *) ); retval->value.s[0] = '\0'; -#ifdef HAVE_LIBOSSO - if ( strcmp(method,"wakeup")==0 ) { -#else - if (dbus_message_is_method_call(message, OSSO_IFACE, "wakeup")) { +#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"); -#ifdef HAVE_LIBOSSO return OSSO_OK; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif } -#ifdef HAVE_LIBOSSO if ( strcmp(method,"start")==0 ) { -#else - if (dbus_message_is_method_call(message, OSSO_IFACE, "start")) { -#endif 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"); -#ifdef HAVE_LIBOSSO return OSSO_ERROR; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif + } + + /* 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; @@ -341,11 +204,7 @@ static DBusHandlerResult dbus_req_handler (DBusConnection *connection, 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"); -#ifdef HAVE_LIBOSSO return OSSO_ERROR; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif } start_flags = frq.ifr_flags; @@ -354,28 +213,16 @@ static DBusHandlerResult dbus_req_handler (DBusConnection *connection, 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"); -#ifdef HAVE_LIBOSSO return OSSO_ERROR; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif } refresh(&appdata->iface); retval->value.s = (gchar *) realloc(retval->value.s,22*sizeof(gchar *)); snprintf(retval->value.s,22,"Interface initialized"); -#ifdef HAVE_LIBOSSO return OSSO_OK; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif } -#ifdef HAVE_LIBOSSO if ( strcmp(method,"stop")==0 ) { -#else - if (dbus_message_is_method_call(message, OSSO_IFACE, "stop")) { -#endif struct ifreq frq; strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ); if(!ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) { @@ -387,65 +234,121 @@ static DBusHandlerResult dbus_req_handler (DBusConnection *connection, appdata->iface.sock = 0; #ifdef HAVE_LIBOSSO osso_deinitialize(appdata->osso_context); -#else - dbus_deinitialize(appdata->osso_context); -#endif /* 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 } -#ifdef HAVE_LIBOSSO if ( strcmp(method,"scan")==0 ) { -#else - if (dbus_message_is_method_call(message, OSSO_IFACE, "scan")) { -#endif 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"); -#ifdef HAVE_LIBOSSO return OSSO_ERROR; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif } - 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"; -#ifdef HAVE_LIBOSSO return OSSO_ERROR; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif - } - 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'; -#ifdef HAVE_LIBOSSO return OSSO_OK; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif } retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *)); snprintf(retval->value.s,64,"Unknown method"); -#ifdef HAVE_LIBOSSO return OSSO_ERROR; -#else - return submit_reply_message(connection, message, retval->value.s); -#endif } +#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; @@ -458,7 +361,7 @@ int main( void ) { osso_context = osso_initialize(OSSO_NAME, WIFISCAND_VERSION_STRING, TRUE, NULL); #else dbus_error_init(&error); - osso_context = dbus_bus_get(DBUS_BUS_STARTER, &error); + osso_context = dbus_bus_get(DBUS_BUS_SESSION, &error); #endif /* Check that initialization was ok */ @@ -483,7 +386,7 @@ int main( void ) { #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, dbus_req_handler, appdata); + int result = dbus_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, handler_wrapper, appdata); #endif if (result != OSSO_OK) { @@ -499,7 +402,7 @@ int main( void ) { event_loop = g_main_loop_new(NULL, FALSE); g_main_loop_run(event_loop); #else - while (dbus_connection_read_write_dispatch (osso_context, -1)) {} + while (dbus_connection_read_write_dispatch(osso_context, -1) && stopped_service==FALSE) {} #endif /* Deinitialize OSSO */