#ifdef HAVE_LIBOSSO
#include <libosso.h>
#else
-#include "glib/gtypes.h"
-#include "dbus/dbus.h"
+#include <glib.h>
+#include <dbus/dbus.h>
+
+#define WIFISCAN_INTROSPECTION "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n\
+ \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n\
+<node name=\"/org/javiplx/wifiscan\">\n\
+ <interface name=\"org.javiplx.wifiscan\">\n\
+ <method name=\"wakeup\">\n\
+ <arg name=\"result\" type=\"s\" direction=\"out\" />\n\
+ </method>\n\
+ <method name=\"start\">\n\
+ <arg name=\"result\" type=\"s\" direction=\"out\" />\n\
+ </method>\n\
+ <method name=\"scan\">\n\
+ <arg name=\"result\" type=\"s\" direction=\"out\" />\n\
+ </method>\n\
+ <method name=\"stop\">\n\
+ <arg name=\"result\" type=\"s\" direction=\"out\" />\n\
+ </method>\n\
+ </interface>\n\
+</node>\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;
/* ------------------------------------------------------------------ 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;
+ iw_get_range_info(wlan->sock, wlan->ifname, &range);
- 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;
+ /* 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;
- }
-
- 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;
}
#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;
-}
-#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;
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
}
struct ifreq frq;
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;
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)) {
appdata->iface.sock = 0;
#ifdef HAVE_LIBOSSO
osso_deinitialize(appdata->osso_context);
-#else
- dbus_connection_unref(appdata->osso_context);
- dbus_shutdown();
-#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;
retval->value.s = (gchar *) realloc(retval->value.s,23*(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);
}
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
-static DBusObjectPathVTable
-dbus_req_handler_vtable = {
- NULL,
- dbus_req_handler,
- NULL,
-};
+
+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 = 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 */
/* Create AppData */
AppData *appdata;
-#ifdef HAVE_LIBOSSO
appdata = g_new0(AppData, 1);
-#else
- appdata = malloc(sizeof(AppData));
-#endif
appdata->osso_context = osso_context;
memset(&(appdata->iface.info), 0, sizeof(wireless_info));
#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_connection_register_fallback(osso_context, OSSO_OBJECT, &dbus_req_handler_vtable, appdata);
+ int result = dbus_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, handler_wrapper, appdata);
#endif
-// NOTE : valid return codes do not match from both functions
-#ifdef HAVE_LIBOSSO
+
if (result != OSSO_OK) {
-#else
- if (!result) {
-#endif
#ifdef HAVE_LIBOSSO
osso_system_note_infoprint(appdata->osso_context, "Failure while setting OSSO callback", NULL);
#endif
return OSSO_ERROR;
}
-#ifndef HAVE_LIBOSSO
- result = dbus_bus_request_name (osso_context, OSSO_SERVICE, 0, &error);
- if (dbus_error_is_set (&error)) {
- fprintf (stderr, "Error %s\n", error.message);
- dbus_error_free (&error);
- exit (1);
- }
-#endif
-
/* 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)) {}
+ while (dbus_connection_read_write_dispatch(osso_context, -1) && stopped_service==FALSE) {}
#endif
/* Deinitialize OSSO */
#ifdef HAVE_LIBOSSO
osso_deinitialize(osso_context);
#else
- dbus_connection_unref(osso_context);
- dbus_shutdown();
+ dbus_deinitialize(osso_context);
#endif
exit(0);