10 #define WIFISCAN_INTROSPECTION "<!DOCTYPE node PUBLIC \"-//freedesktop//DTD D-BUS Object Introspection 1.0//EN\"\n\
11 \"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd\">\n\
12 <node name=\"/org/javiplx/wifiscan\">\n\
13 <interface name=\"org.javiplx.wifiscan\">\n\
14 <method name=\"wakeup\">\n\
15 <arg name=\"result\" type=\"s\" direction=\"out\" />\n\
17 <method name=\"start\">\n\
18 <arg name=\"result\" type=\"s\" direction=\"out\" />\n\
20 <method name=\"scan\">\n\
21 <arg name=\"result\" type=\"s\" direction=\"out\" />\n\
23 <method name=\"stop\">\n\
24 <arg name=\"result\" type=\"s\" direction=\"out\" />\n\
32 #define osso_context_t DBusConnection
33 typedef struct osso_rpc_t_values {
37 typedef struct osso_rpc_t {
39 osso_rpc_t_values value;
43 #define WIFISCAND_VERSION_STRING "1.1"
45 #define OSSO_NAME "wifiscan"
46 #define OSSO_SERVICE "org.javiplx."OSSO_NAME
47 #define OSSO_OBJECT "/org/javiplx/"OSSO_NAME
48 #define OSSO_IFACE "org.javiplx."OSSO_NAME
58 /* --------------------------------------------------------------------------- WirelessInterface */
65 /* ------------------------------------------------------------------ WirelessInterface_ScanItem */
67 void WirelessInterface_ScanItem(struct wireless_scan* ap, ScanInfo **scaninfo) {
69 *scaninfo = (ScanInfo*) malloc( sizeof(ScanInfo) );
70 memset(*scaninfo, 0, sizeof(ScanInfo) );
72 iw_sawap_ntop( &ap->ap_addr, (*scaninfo)->mac);
74 (*scaninfo)->rssi = ap->stats.qual.level - 0x100;
75 (*scaninfo)->noise = ap->stats.qual.level - 0x100;
79 /* ---------------------------------------------------------------------- */
81 void* makeScan(WirelessInterface* wlan, gchar *message) {
82 wireless_scan_head context;
86 ScanInfo **scan = NULL;
88 iw_get_range_info(wlan->sock, wlan->ifname, &range);
90 /* We don't call iw_scan to allow fine control of delays and timeouts */
91 context.result = NULL;
95 delay = iw_process_scan(wlan->sock, wlan->ifname, range.we_version_compiled, &context);
102 int i = 1; // To acount for the final NULL
103 struct wireless_scan *ap = context.result;
104 while ( ap != NULL ) {
108 scan = (ScanInfo**) malloc( i * sizeof(ScanInfo *) );
109 memset(scan, 0, i * sizeof(ScanInfo *) );
111 ScanInfo **sc = scan;
115 while ( ap != NULL ) {
116 WirelessInterface_ScanItem(ap, sc++);
121 message = "Unknown error";
127 static void refresh(WirelessInterface* coso) {
130 iw_get_basic_config(coso->sock, coso->ifname, &(coso->info.b));
131 iw_get_range_info(coso->sock, coso->ifname, &(coso->info.range));
133 iw_get_ext(coso->sock, coso->ifname, SIOCGIWRATE, &wrq);
134 memcpy(&(coso->info.bitrate), &wrq.u.bitrate, sizeof(iwparam));
136 iw_get_ext(coso->sock, coso->ifname, SIOCGIWAP, &wrq);
137 memcpy(&(coso->info.ap_addr), &wrq.u.ap_addr, sizeof (sockaddr));
140 coso->sock, coso->ifname, &(coso->info.stats),
141 &(coso->info.range), coso->info.has_range
145 /* Application UI data struct */
146 typedef struct _AppData AppData;
148 WirelessInterface iface;
149 osso_context_t *osso_context;
153 static GMainLoop *event_loop = NULL;
155 static short int start_flags = 0;
157 /* Callback for normal D-BUS messages */
158 gint dbus_req_handler(const gchar * interface, const gchar * method,
159 GArray * arguments, gpointer data,
163 appdata = (AppData *) data;
165 retval->type = DBUS_TYPE_STRING;
166 retval->value.s = (gchar*) malloc( sizeof(gchar *) );
167 retval->value.s[0] = '\0';
170 if ( strcmp(method,"Introspect")==0 ) {
171 retval->value.s = (gchar *) realloc(retval->value.s,630*sizeof(gchar *));
172 snprintf(retval->value.s,strlen(WIFISCAN_INTROSPECTION),WIFISCAN_INTROSPECTION);
177 if ( strcmp(method,"wakeup")==0 ) {
178 retval->value.s = (gchar *) realloc(retval->value.s,16*sizeof(gchar *));
179 snprintf(retval->value.s,16,"WifiScand ready");
183 if ( strcmp(method,"start")==0 ) {
185 if( (appdata->iface.sock=iw_sockets_open()) < 0) {
186 retval->value.s = (gchar *) realloc(retval->value.s,33*sizeof(gchar *));
187 snprintf(retval->value.s,33,"Failure in socket initialization");
191 /* Get range stuff */
193 int has_range = (iw_get_range_info(appdata->iface.sock, appdata->iface.ifname, &range) >= 0);
195 /* Check if the interface could support scanning. */
196 if((!has_range) || (range.we_version_compiled < 14)) {
197 retval->value.s = (gchar *) realloc(retval->value.s,35*sizeof(gchar *));
198 snprintf(retval->value.s,35,"Interface doesn't support scanning");
203 strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ);
204 if(ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) {
205 retval->value.s = (gchar *) realloc(retval->value.s,28*sizeof(gchar *));
206 snprintf(retval->value.s,28,"Cannot get interface status");
210 start_flags = frq.ifr_flags;
211 frq.ifr_flags |= IFF_UP | IFF_RUNNING;
213 if(ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq)) {
214 retval->value.s = (gchar *) realloc(retval->value.s,27*sizeof(gchar *));
215 snprintf(retval->value.s,27,"Cannot set interface state");
219 refresh(&appdata->iface);
220 retval->value.s = (gchar *) realloc(retval->value.s,22*sizeof(gchar *));
221 snprintf(retval->value.s,22,"Interface initialized");
225 if ( strcmp(method,"stop")==0 ) {
227 strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ);
228 if(!ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) {
229 frq.ifr_flags = start_flags;
230 if(!ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq))
231 refresh(&appdata->iface);
233 iw_sockets_close(appdata->iface.sock);
234 appdata->iface.sock = 0;
236 osso_deinitialize(appdata->osso_context);
237 /* Instead of exiting, signaling finish to main loop could be better
238 retval->value.s = (gchar *) realloc(retval->value.s,34*sizeof(gchar *));
239 snprintf(retval->value.s,34,"Interface moved to original state");
247 if ( strcmp(method,"scan")==0 ) {
249 ScanInfo **scan = (ScanInfo **) makeScan(&appdata->iface,retval->value.s);
251 retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *));
252 snprintf(retval->value.s,64,"ERROR");
257 while ( *(scan+i) != NULL ) i++;
258 retval->value.s = (gchar *) malloc( (22*i+1) * sizeof(gchar *) );
259 if ( retval->value.s == NULL ) {
260 retval->value.s = "Error allocating memory";
263 memset(retval->value.s, '\0', (22*i+1) * sizeof(gchar *) );
265 while ( *scan != NULL ) {
266 sprintf(retval->value.s+(22*i),"%s:%d ",(*scan)->mac,(*scan)->rssi);
271 retval->value.s[strlen(retval->value.s)-1] = '\0';
275 retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *));
276 snprintf(retval->value.s,64,"Unknown method");
282 dbus_bool_t stopped_service = FALSE;
284 static DBusObjectPathVTable *vtable = NULL;
286 int dbus_set_cb_f( DBusConnection *context,
287 const char *service, const char *object,
288 const char *interface, void *handler, // FIXME : Set proper type for handler
291 /* First, we prepare the complex dbus handler structures */
292 DBusObjectPathVTable *vtable = malloc( sizeof(DBusObjectPathVTable) );
293 memset(vtable , '\0', sizeof(DBusObjectPathVTable) );
294 vtable->message_function = (DBusObjectPathMessageFunction) handler; // FIXME : Aqui va el nuevo handler/wrapper
296 if (!dbus_connection_register_fallback(context, object, vtable, user_data)) {
301 dbus_error_init(&error);
303 dbus_bus_request_name (context, service, 0, &error);
304 if ( dbus_error_is_set(&error) ) {
305 dbus_error_free (&error);
309 dbus_error_free (&error);
313 void dbus_deinitialize( DBusConnection *context ) {
314 free(vtable); vtable = NULL;
315 dbus_connection_unref(context);
319 static DBusHandlerResult handler_wrapper (DBusConnection *connection,
320 DBusMessage *message,
324 osso_rpc_t *retval = malloc(sizeof(osso_rpc_t));
326 if ( dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ) {
327 retcode = dbus_req_handler(dbus_message_get_interface(message),
328 dbus_message_get_member(message),
331 if ( strcmp(dbus_message_get_member(message),"stop")==0 )
332 stopped_service = TRUE;
334 if ( retval->value.s != NULL ) {
335 DBusMessage *reply = dbus_message_new_method_return (message);
338 if (!dbus_message_append_args (reply, DBUS_TYPE_STRING, &retval->value.s, DBUS_TYPE_INVALID))
340 if (!dbus_connection_send (connection, reply, NULL))
342 dbus_message_unref (reply);
347 return DBUS_HANDLER_RESULT_HANDLED;
354 osso_context_t *osso_context;
359 /* Initialize maemo application */
361 osso_context = osso_initialize(OSSO_NAME, WIFISCAND_VERSION_STRING, TRUE, NULL);
363 dbus_error_init(&error);
364 osso_context = dbus_bus_get(DBUS_BUS_SESSION, &error);
367 /* Check that initialization was ok */
368 if (osso_context == NULL) {
370 fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n", error.message);
371 dbus_error_free (&error);
378 appdata = g_new0(AppData, 1);
379 appdata->osso_context = osso_context;
381 memset(&(appdata->iface.info), 0, sizeof(wireless_info));
382 appdata->iface.ifname = "wlan0";
383 appdata->iface.sock = 0;
385 /* Add handler for hello D-BUS messages */
387 osso_return_t result = osso_rpc_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, dbus_req_handler, appdata);
389 int result = dbus_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, handler_wrapper, appdata);
392 if (result != OSSO_OK) {
394 osso_system_note_infoprint(appdata->osso_context, "Failure while setting OSSO callback", NULL);
399 /* INITIALIZATION FINISH */
402 event_loop = g_main_loop_new(NULL, FALSE);
403 g_main_loop_run(event_loop);
405 while (dbus_connection_read_write_dispatch(osso_context, -1) && stopped_service==FALSE) {}
408 /* Deinitialize OSSO */
410 osso_deinitialize(osso_context);
412 dbus_deinitialize(osso_context);