6 #define WIFISCAND_VERSION_STRING "1.0"
8 #define OSSO_NAME "wifiscan"
9 #define OSSO_SERVICE "org.javiplx."OSSO_NAME
10 #define OSSO_OBJECT "/org/javiplx/"OSSO_NAME
11 #define OSSO_IFACE "org.javiplx."OSSO_NAME
21 /* --------------------------------------------------------------------------- WirelessInterface */
28 /* ------------------------------------------------------------------ WirelessInterface_ScanItem */
30 static int WirelessInterface_ScanItem(struct iw_event* event, ScanInfo **scaninfo) {
36 *scaninfo = (ScanInfo*) malloc( sizeof(ScanInfo) );
37 memset(*scaninfo, 0, sizeof(ScanInfo) );
39 iw_ether_ntop( (const struct ether_addr*)(event->u.ap_addr.sa_data), (*scaninfo)->mac);
44 (*scaninfo)->rssi = event->u.qual.level - 0x100;
54 /* ---------------------------------------------------------------------- */
56 void* makeScan(WirelessInterface* coso, gchar *message) {
58 unsigned char* buffer = NULL;
59 int buflen = IW_SCAN_MAX_DATA;
63 int timeout = 10000000;
65 ScanInfo **scan = NULL;
67 has_range = (iw_get_range_info(coso->sock, coso->ifname, &range) >= 0);
71 wrq.u.data.pointer = NULL;
73 wrq.u.data.length = 0;
75 if(iw_set_ext(coso->sock, coso->ifname, SIOCSIWSCAN, &wrq) < 0) {
77 message = "Interface doesn't support scanning";
82 timeout -= tv.tv_usec;
92 ret = select(last_fd + 1, &rfds, NULL, NULL, &tv);
95 if(errno == EAGAIN || errno == EINTR) continue;
98 message = "Unknown scanning error";
104 unsigned char* newbuf;
107 newbuf = (unsigned char*) realloc(buffer, buflen);
110 if(buffer) free(buffer);
111 message = "Memory allocation failure in scan";
117 wrq.u.data.pointer = buffer;
118 wrq.u.data.flags = 0;
119 wrq.u.data.length = buflen;
121 if(iw_get_ext(coso->sock, coso->ifname, SIOCGIWSCAN, &wrq) < 0) {
122 if((errno == E2BIG)) {
123 if(wrq.u.data.length > buflen) buflen = wrq.u.data.length;
129 if(errno == EAGAIN) {
132 timeout -= tv.tv_usec;
134 if(timeout > 0) continue;
139 message = "Unable to read scan data";
149 if(wrq.u.data.length) {
153 void* scan_dict = NULL;
155 iw_init_event_stream(&stream, (char*)(buffer), wrq.u.data.length);
157 scan = (ScanInfo**) malloc( 25 * sizeof(ScanInfo *) );
158 memset(scan, 0, 25 * sizeof(ScanInfo *) );
161 for (i=0; i<25; i++) *(scan+i) = NULL;
166 ret = iw_extract_event_stream(&stream, &iwe, range.we_version_compiled);
169 int sr = WirelessInterface_ScanItem(&iwe, &sc);
180 message = "Unknown error";
189 static void refresh(WirelessInterface* coso) {
192 iw_get_basic_config(coso->sock, coso->ifname, &(coso->info.b));
193 iw_get_range_info(coso->sock, coso->ifname, &(coso->info.range));
195 iw_get_ext(coso->sock, coso->ifname, SIOCGIWRATE, &wrq);
196 memcpy(&(coso->info.bitrate), &wrq.u.bitrate, sizeof(iwparam));
198 iw_get_ext(coso->sock, coso->ifname, SIOCGIWAP, &wrq);
199 memcpy(&(coso->info.ap_addr), &wrq.u.ap_addr, sizeof (sockaddr));
202 coso->sock, coso->ifname, &(coso->info.stats),
203 &(coso->info.range), coso->info.has_range
207 /* Application UI data struct */
208 typedef struct _AppData AppData;
210 WirelessInterface iface;
211 osso_context_t *osso_context;
214 static GMainLoop *event_loop = NULL;
215 static short int start_flags = 0;
217 /* Callback for normal D-BUS messages */
218 gint dbus_req_handler(const gchar * interface, const gchar * method,
219 GArray * arguments, gpointer data,
223 appdata = (AppData *) data;
225 retval->type = DBUS_TYPE_STRING;
226 retval->value.s = (gchar*) malloc( sizeof(gchar *) );
227 retval->value.s[0] = '\0';
229 if ( strcmp(method,"wakeup")==0 ) {
230 retval->value.s = (gchar *) realloc(retval->value.s,16*sizeof(gchar *));
231 snprintf(retval->value.s,16,"WifiScand ready");
235 if ( strcmp(method,"start")==0 ) {
237 if( (appdata->iface.sock=iw_sockets_open()) < 0) {
238 retval->value.s = (gchar *) realloc(retval->value.s,33*sizeof(gchar *));
239 snprintf(retval->value.s,33,"Failure in socket initialization");
244 strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ);
245 if(ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) {
246 retval->value.s = (gchar *) realloc(retval->value.s,28*sizeof(gchar *));
247 snprintf(retval->value.s,28,"Cannot get interface status");
251 start_flags = frq.ifr_flags;
252 frq.ifr_flags |= IFF_UP | IFF_RUNNING;
254 if(ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq)) {
255 retval->value.s = (gchar *) realloc(retval->value.s,27*sizeof(gchar *));
256 snprintf(retval->value.s,27,"Cannot set interface state");
260 refresh(&appdata->iface);
261 retval->value.s = (gchar *) realloc(retval->value.s,22*sizeof(gchar *));
262 snprintf(retval->value.s,22,"Interface initialized");
266 if ( strcmp(method,"stop")==0 ) {
268 strncpy(frq.ifr_name, appdata->iface.ifname, IFNAMSIZ);
269 if(!ioctl(appdata->iface.sock, SIOCGIFFLAGS, &frq)) {
270 frq.ifr_flags = start_flags;
271 if(!ioctl(appdata->iface.sock, SIOCSIFFLAGS, &frq))
272 refresh(&appdata->iface);
274 iw_sockets_close(appdata->iface.sock);
275 appdata->iface.sock = 0;
276 osso_deinitialize(appdata->osso_context);
277 /* Instead of exiting, signaling finish to main loop could be better
278 retval->value.s = (gchar *) realloc(retval->value.s,34*sizeof(gchar *));
279 snprintf(retval->value.s,34,"Interface moved to original state");
284 if ( strcmp(method,"scan")==0 ) {
286 ScanInfo **scan = (ScanInfo **) makeScan(&appdata->iface,retval->value.s);
288 retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *));
289 snprintf(retval->value.s,64,"ERROR");
294 for (i=0; i<25&&*(scan+i)!=NULL; i++) {
295 ScanInfo* sc = *(scan+i);
296 retval->value.s = (gchar *) realloc(retval->value.s,23*(i+1)*sizeof(gchar *));
297 if ( retval->value.s == NULL ) {
298 retval->value.s = "Error allocating memory";
301 sprintf(retval->value.s+strlen(retval->value.s),"%s:%d ",sc->mac,sc->rssi);
304 retval->value.s[strlen(retval->value.s)-1] = '\0';
308 retval->value.s = (gchar *) realloc(retval->value.s,64*sizeof(gchar *));
309 snprintf(retval->value.s,64,"Unknown method");
316 osso_context_t *osso_context;
318 /* Initialize maemo application */
319 osso_context = osso_initialize(OSSO_NAME, WIFISCAND_VERSION_STRING, TRUE, NULL);
321 /* Check that initialization was ok */
322 if (osso_context == NULL) {
328 appdata = g_new0(AppData, 1);
329 appdata->osso_context = osso_context;
331 memset(&(appdata->iface.info), 0, sizeof(wireless_info));
332 appdata->iface.ifname = "wlan0";
333 appdata->iface.sock = 0;
335 /* Add handler for hello D-BUS messages */
336 osso_return_t result = osso_rpc_set_cb_f(osso_context, OSSO_SERVICE, OSSO_OBJECT, OSSO_IFACE, dbus_req_handler, appdata);
337 if (result != OSSO_OK) {
338 osso_system_note_infoprint(appdata->osso_context, "Failure while setting OSSO callback", NULL);
342 /* INITIALIZATION FINISH */
344 event_loop = g_main_loop_new(NULL, FALSE);
345 g_main_loop_run(event_loop);
347 /* Deinitialize OSSO */
348 osso_deinitialize(osso_context);