13 #define osso_context_t DBusConnection
14 typedef struct osso_rpc_t_values {
18 typedef struct osso_rpc_t {
20 osso_rpc_t_values value;
24 #define WIFISCAND_VERSION_STRING "1.1"
26 #define OSSO_NAME "wifiscan"
27 #define OSSO_SERVICE "org.javiplx."OSSO_NAME
28 #define OSSO_OBJECT "/org/javiplx/"OSSO_NAME
29 #define OSSO_IFACE "org.javiplx."OSSO_NAME
39 /* --------------------------------------------------------------------------- WirelessInterface */
46 /* ------------------------------------------------------------------ WirelessInterface_ScanItem */
48 static int WirelessInterface_ScanItem(struct iw_event* event, ScanInfo **scaninfo) {
54 *scaninfo = (ScanInfo*) malloc( sizeof(ScanInfo) );
55 memset(*scaninfo, 0, sizeof(ScanInfo) );
57 iw_ether_ntop( (const struct ether_addr*)(event->u.ap_addr.sa_data), (*scaninfo)->mac);
62 (*scaninfo)->rssi = event->u.qual.level - 0x100;
72 /* ---------------------------------------------------------------------- */
74 void* makeScan(WirelessInterface* coso, gchar *message) {
76 unsigned char* buffer = NULL;
77 int buflen = IW_SCAN_MAX_DATA;
81 int timeout = 10000000;
83 ScanInfo **scan = NULL;
85 has_range = (iw_get_range_info(coso->sock, coso->ifname, &range) >= 0);
89 wrq.u.data.pointer = NULL;
91 wrq.u.data.length = 0;
93 if(iw_set_ext(coso->sock, coso->ifname, SIOCSIWSCAN, &wrq) < 0) {
95 message = "Interface doesn't support scanning";
100 timeout -= tv.tv_usec;
110 ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);
113 if(errno == EAGAIN || errno == EINTR) continue;
116 message = "Unknown scanning error";
122 unsigned char* newbuf;
125 newbuf = (unsigned char*) realloc(buffer, buflen);
128 if(buffer) free(buffer);
129 message = "Memory allocation failure in scan";
135 wrq.u.data.pointer = buffer;
136 wrq.u.data.flags = 0;
137 wrq.u.data.length = buflen;
139 if(iw_get_ext(coso->sock, coso->ifname, SIOCGIWSCAN, &wrq) < 0) {
140 if((errno == E2BIG)) {
141 if(wrq.u.data.length > buflen) buflen = wrq.u.data.length;
147 if(errno == EAGAIN) {
150 timeout -= tv.tv_usec;
152 if(timeout > 0) continue;
157 message = "Unable to read scan data";
167 if(wrq.u.data.length) {
171 void* scan_dict = NULL;
173 iw_init_event_stream(&stream, (char*)(buffer), wrq.u.data.length);
175 scan = (ScanInfo**) malloc( 25 * sizeof(ScanInfo *) );
176 memset(scan, 0, 25 * sizeof(ScanInfo *) );
179 for (i=0; i<25; i++) *(scan+i) = NULL;
184 ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled);
187 int sr = WirelessInterface_ScanItem(&iwe, &sc);
198 message = "Unknown error";
207 static void refresh(WirelessInterface* coso) {
210 iw_get_basic_config(coso->sock, coso->ifname, &(coso->info.b));
211 iw_get_range_info(coso->sock, coso->ifname, &(coso->info.range));
213 iw_get_ext(coso->sock, coso->ifname, SIOCGIWRATE, &wrq);
214 memcpy(&(coso->info.bitrate), &wrq.u.bitrate, sizeof(iwparam));
216 iw_get_ext(coso->sock, coso->ifname, SIOCGIWAP, &wrq);
217 memcpy(&(coso->info.ap_addr), &wrq.u.ap_addr, sizeof (sockaddr));
220 coso->sock, coso->ifname, &(coso->info.stats),
221 &(coso->info.range), coso->info.has_range
225 /* Application UI data struct */
226 typedef struct _AppData AppData;
228 WirelessInterface iface;
229 osso_context_t *osso_context;
233 static GMainLoop *event_loop = NULL;
235 static short int start_flags = 0;
237 /* Callback for normal D-BUS messages */
238 gint dbus_req_handler(const gchar * interface, const gchar * method,
239 GArray * arguments, gpointer data,
243 appdata = (AppData *) data;
245 retval->type = DBUS_TYPE_STRING;
246 retval->value.s = (gchar*) malloc( sizeof(gchar *) );
247 retval->value.s[0] = '\0';
249 if ( strcmp(method,"wakeup")==0 ) {
250 retval->value.s = (gchar *) realloc(retval->value.s,16*sizeof(gchar *));
251 snprintf(retval->value.s,16,"WifiScand ready");
255 if ( strcmp(method,"start")==0 ) {
257 if( (appdata->iface.sock=iw_sockets_open()) < 0) {
258 retval->value.s = (gchar *) realloc(retval->value.s,33*sizeof(gchar *));
259 snprintf(retval->value.s,33,"Failure in socket initialization");
264 strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ);
265 if(ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) {
266 retval->value.s = (gchar *) realloc(retval->value.s,28*sizeof(gchar *));
267 snprintf(retval->value.s,28,"Cannot get interface status");
271 start_flags = frq.ifr_flags;
272 frq.ifr_flags |= IFF_UP | IFF_RUNNING;
274 if(ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq)) {
275 retval->value.s = (gchar *) realloc(retval->value.s,27*sizeof(gchar *));
276 snprintf(retval->value.s,27,"Cannot set interface state");
280 refresh(&appdata->iface);
281 retval->value.s = (gchar *) realloc(retval->value.s,22*sizeof(gchar *));
282 snprintf(retval->value.s,22,"Interface initialized");
286 if ( strcmp(method,"stop")==0 ) {
288 strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ);
289 if(!ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) {
290 frq.ifr_flags = start_flags;
291 if(!ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq))
292 refresh(&appdata->iface);
294 iw_sockets_close(appdata->iface.sock);
295 appdata->iface.sock = 0;
297 osso_deinitialize(appdata->osso_context);
299 dbus_deinitialize(appdata->osso_context);
301 /* Instead of exiting, signaling finish to main loop could be better
302 retval->value.s = (gchar *) realloc(retval->value.s,34*sizeof(gchar *));
303 snprintf(retval->value.s,34,"Interface moved to original state");
308 if ( strcmp(method,"scan")==0 ) {
310 ScanInfo **scan = (ScanInfo **) makeScan(&appdata->iface,retval->value.s);
312 retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *));
313 snprintf(retval->value.s,64,"ERROR");
318 for (i=0; i<25&&*(scan+i)!=NULL; i++) {
319 ScanInfo* sc = *(scan+i);
320 retval->value.s = (gchar *) realloc(retval->value.s,23*(i+1)*sizeof(gchar *));
321 if ( retval->value.s == NULL ) {
322 retval->value.s = "Error allocating memory";
325 sprintf(retval->value.s+strlen(retval->value.s),"%s:%d ",sc->mac,sc->rssi);
328 retval->value.s[strlen(retval->value.s)-1] = '\0';
332 retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *));
333 snprintf(retval->value.s,64,"Unknown method");
338 static DBusObjectPathVTable *vtable = NULL;
340 int dbus_set_cb_f( DBusConnection *context,
341 const char *service, const char *object,
342 const char *interface, void *handler, // FIXME : Set proper type for handler
345 /* First, we prepare the complex dbus handler structures */
346 DBusObjectPathVTable *vtable = malloc( sizeof(DBusObjectPathVTable) );
347 memset(vtable , '\0', sizeof(DBusObjectPathVTable) );
348 vtable->message_function = (DBusObjectPathMessageFunction) handler; // FIXME : Aqui va el nuevo handler/wrapper
350 if (!dbus_connection_register_fallback(context, object, vtable, user_data)) {
355 dbus_error_init(&error);
357 dbus_bus_request_name (context, service, 0, &error);
358 if ( dbus_error_is_set(&error) ) {
359 dbus_error_free (&error);
363 dbus_error_free (&error);
367 void dbus_deinitialize( DBusConnection *context ) {
368 free(vtable); vtable = NULL;
369 dbus_connection_unref(context);
373 static DBusHandlerResult handler_wrapper (DBusConnection *connection,
374 DBusMessage *message,
378 osso_rpc_t *retval = malloc(sizeof(osso_rpc_t));
380 if ( dbus_message_get_type(message) == DBUS_MESSAGE_TYPE_METHOD_CALL ) {
381 retcode = dbus_req_handler(dbus_message_get_interface(message),
382 dbus_message_get_member(message),
385 if ( retval->value.s != NULL ) {
386 DBusMessage *reply = dbus_message_new_method_return (message);
389 if (!dbus_message_append_args (reply, DBUS_TYPE_STRING, &retval->value.s, DBUS_TYPE_INVALID))
391 if (!dbus_connection_send (connection, reply, NULL))
393 dbus_message_unref (reply);
398 return DBUS_HANDLER_RESULT_HANDLED;
405 osso_context_t *osso_context;
410 /* Initialize maemo application */
412 osso_context = osso_initialize(OSSO_NAME, WIFISCAND_VERSION_STRING, TRUE, NULL);
414 dbus_error_init(&error);
415 osso_context = dbus_bus_get(DBUS_BUS_STARTER, &error);
418 /* Check that initialization was ok */
419 if (osso_context == NULL) {
421 fprintf (stderr, "*** Failed to open connection to activating message bus: %s\n", error.message);
422 dbus_error_free (&error);
429 appdata = g_new0(AppData, 1);
430 appdata->osso_context = osso_context;
432 memset(&(appdata->iface.info), 0, sizeof(wireless_info));
433 appdata->iface.ifname = "wlan0";
434 appdata->iface.sock = 0;
436 /* Add handler for hello D-BUS messages */
438 osso_return_t result = osso_rpc_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, dbus_req_handler, appdata);
440 int result = dbus_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, handler_wrapper, appdata);
443 if (result != OSSO_OK) {
445 osso_system_note_infoprint(appdata->osso_context, "Failure while setting OSSO callback", NULL);
450 /* INITIALIZATION FINISH */
453 event_loop = g_main_loop_new(NULL, FALSE);
454 g_main_loop_run(event_loop);
456 while (dbus_connection_read_write_dispatch (osso_context, -1)) {}
459 /* Deinitialize OSSO */
461 osso_deinitialize(osso_context);
463 dbus_deinitialize(osso_context);