connectionMgr/src/scanThread.c File Reference

#include <string.h>
#include <stdlib.h>
#include "connectionMgrLog.h"
#include "connectionMgr.h"
#include "scanThread.h"

Go to the source code of this file.

Defines

#define MAX_NETWORKS   50

Functions

static int compare_networks (const void *p1, const void *p2)
static int quality_to_integer (const char *string)
static gpointer scanThread (gpointer arg)
gboolean scanThread_start (scan_thread_parms *scan_parms)
gboolean scanThread_stop ()
gboolean scanThread_wait (int timeout_sec)
gboolean scanThread_stopped (void)
void free_network_spec (network_spec_t *pNetwork)
network_spec_tdup_network_spec (network_spec_t *pNetwork)

Variables

static volatile GThread * g_scan_thread = NULL
static volatile gboolean g_scan_abort = FALSE


Define Documentation

#define MAX_NETWORKS   50

Definition at line 33 of file scanThread.c.


Function Documentation

static int compare_networks ( const void *  p1,
const void *  p2 
) [static]

Definition at line 323 of file scanThread.c.

00324 {
00325     const network_spec_t* left  = p1;
00326     const network_spec_t* right = p2;
00327     int   ret = 0;
00328 
00329     if (left->quality != right->quality)
00330     {
00331         // 1st sort key: signal quality
00332         ret = left->quality - right->quality;
00333     }
00334     else if (left->encryption != right->encryption)
00335     {
00336         // 2st sort key: encryption type
00337         if (left->encryption == encr_none_t)
00338         {
00339             ret = -1;
00340         }
00341         if (right->encryption == encr_none_t)
00342         {
00343             ret = 1;
00344         }
00345 
00346         if (left->encryption == encr_wep_t)
00347         {
00348             ret = -1;
00349         }
00350         if (right->encryption == encr_wep_t)
00351         {
00352             ret = 1;
00353         }
00354 
00355         if (left->encryption == encr_wpa_t)
00356         {
00357             ret = -1;
00358         }
00359         if (right->encryption == encr_wpa_t)
00360         {
00361             ret = 1;
00362         }
00363         
00364         if (left->encryption == encr_undefined_t)
00365         {
00366             ret = -1;
00367         }
00368         if (right->encryption == encr_undefined_t)
00369         {
00370             ret = 1;
00371         }
00372     }
00373     else
00374     {
00375         // 3rd sort key: network name
00376         ret = g_ascii_strcasecmp(left->ssid, right->ssid);
00377     }
00378    
00379     CN_LOGPRINTF("ret=%d", ret);
00380 
00381     // make the result of qsort to be descending
00382     ret = 0 - ret; 
00383     return ret;
00384 }

network_spec_t* dup_network_spec ( network_spec_t pNetwork  ) 

Definition at line 437 of file scanThread.c.

00438 {
00439     network_spec_t *pDupNetwork = NULL;
00440     if (pNetwork)
00441     {
00442         pDupNetwork = g_new0(network_spec_t, 1);
00443         if (pDupNetwork)
00444         {
00445             pDupNetwork->ssid = g_strdup(pNetwork->ssid);
00446             pDupNetwork->encryption = pNetwork->encryption;
00447             pDupNetwork->quality = pNetwork->quality;
00448         }
00449     }
00450     return pDupNetwork;
00451 }

void free_network_spec ( network_spec_t pNetwork  ) 

Definition at line 428 of file scanThread.c.

00429 {
00430     if (pNetwork)
00431     {
00432         g_free(pNetwork->ssid);
00433         g_free(pNetwork);
00434     }
00435 }

static int quality_to_integer ( const char *  string  )  [static]

Definition at line 387 of file scanThread.c.

00388 {
00389     char *cp, *cpx, *cpy=NULL;
00390     int   x,  y=0;
00391     int   integer;
00392     
00393     integer = 0;
00394     if (string)
00395     {
00396         cpx = g_strdup(string);
00397         if (cpx)
00398         {
00399             cp = strchr(cpx, '/');
00400             if (cp)
00401             {
00402                 cp[0] = '\0';
00403                 cpy = &cp[1];
00404             }
00405             
00406             x = atoi(cpx);
00407             if (cpy)
00408             {
00409                 y = atoi(cpy);
00410             }
00411 
00412             CN_LOGPRINTF("x=%d,y=%d", x, y); 
00413             
00414             if (y != 0)
00415             {
00416                 integer = x * 100 / y;
00417             }
00418            
00419             g_free(cpx);
00420             cpx = NULL;
00421         }
00422     }
00423 
00424     CN_LOGPRINTF("string[%s]-->integer[%d]", string, integer);
00425     return integer;
00426 }

static gpointer scanThread ( gpointer  arg  )  [static]

Definition at line 42 of file scanThread.c.

00043 {
00044     int      i;
00045     char*    cp;
00046     char*    line;
00047     gboolean b;
00048     gchar*   p_stdout = NULL;
00049     guint    networks_found = 0;
00050 
00051     scan_thread_parms* parms = (scan_thread_parms*)arg;
00052     network_spec_t*    networks = NULL;
00053 
00054 
00055     CN_LOGPRINTF("entry");
00056 
00057     gdk_threads_enter();
00058     {
00059         // clean networks table, just to be sure
00060         for (i = 0 ; i < parms->networks_num ; i++)
00061         {
00062             g_free(parms->networks[i].ssid);
00063         }
00064         parms->networks_found = 0;
00065 
00066         // local array of networks found
00067         networks = g_new0(network_spec_t, MAX_NETWORKS);
00068         g_assert(networks != NULL);
00069 
00070         // tell GTK thread we are starting
00071         gtk_label_set_text(GTK_LABEL(parms->scanStatus), "scan-started");
00072     }
00073     gdk_threads_leave();
00074 
00075     // scan for networks
00076     fflush(stdout);
00077 
00078     char cmd[100];
00079     snprintf(cmd, sizeof(cmd), "%s \"%s\"", 
00080             COMMAND_SCAN_WIRELESS, parms->ssid);
00081 
00082     b = g_spawn_command_line_sync(cmd, &p_stdout, NULL, NULL, NULL);
00083     if (b == FALSE)
00084     {
00085         CN_ERRORPRINTF("g_spawn_command_line_sync failed on command [%s]", 
00086                        cmd);
00087     }
00088     else
00089     {
00090         for ( line = strtok(p_stdout, "\n") ;
00091               line != NULL ;
00092               line = strtok(NULL, "\n")      )
00093         {
00094             CN_LOGPRINTF("line [%s]", line);
00095 
00096             // One line received specifying a wireless network, syntax:
00097             // Network: "<ssid-string>" <security-type> <quality>
00098             char *ssid = NULL;
00099             char *security = NULL;
00100             char *quality = NULL;
00101             wireless_encr_type_t encr_type = encr_none_t;
00102 
00103             // precaution because string functions probably not thread-safe
00104             gdk_threads_enter();
00105             {
00106                 // parse string into tokens
00107                 // line = 1st token = 'Networks:'
00108                 cp = strchr(line, ' ');
00109                 if (cp  &&  cp[1] == '"')
00110                 {
00111                     *cp = '\0';
00112                     
00113                     // ssid = 2nd token = '"<ssid-string>"'
00114                     // Note: "<ssid-string>" 
00115                     //       may contain white-space characters
00116                     // Note: strip quotes from "<ssid-string>"
00117                     ssid = cp + 2;
00118                     cp = strchr(ssid, '"');
00119                     if (cp  &&  cp[1] == ' ')
00120                     {
00121                         *cp = '\0';
00122 
00123                         // security = 3rd token = '[free|wep|wpa]'
00124                         security = cp + 2;
00125                         cp = strchr(security, ' ');
00126                         if (cp)
00127                         {
00128                             *cp = '\0';
00129                             if (strcmp(security, "free") == 0)
00130                             {
00131                                 encr_type = encr_none_t;
00132                             }
00133                             else if (strcmp(security, "wep") == 0)
00134                             {
00135                                 encr_type = encr_wep_t;
00136                             }
00137                             else if (strcmp(security, "wpa") == 0)
00138                             {
00139                                 encr_type = encr_wpa_t;
00140                             }
00141                             else
00142                             {
00143                                 encr_type = encr_undefined_t;
00144                             }
00145 
00146                             // quality = 4th token = 'xx/yy'
00147                             quality = cp + 1;
00148                             cp = strchr(quality, ' ');
00149                             if (cp)
00150                             {
00151                                 *cp = '\0';
00152                             }
00153                         }
00154                     }
00155                 }
00156                 
00157                 // check syntax and store network details
00158                 if (   strcmp(line, "Network:") == 0
00159                     && ssid     != NULL
00160                     && security != NULL
00161                     && quality  != NULL )
00162                 {
00163                     i = networks_found++;
00164                     if (i < MAX_NETWORKS)
00165                     {
00166                         networks[i].ssid = strdup(ssid);
00167                         networks[i].encryption = encr_type;
00168                         networks[i].quality = quality_to_integer(quality);
00169                         CN_LOGPRINTF("Network: ssid [%s] "
00170                                      "security [%s] [%d] quality [%s]", 
00171                                      ssid, security, encr_type, quality);
00172                     }
00173                     else
00174                     {
00175                         // oops
00176                         networks_found--;
00177                         CN_LOGPRINTF("Too many networks: "
00178                                      "MAX_NETWORKS = [%d] "
00179                                      "networks_found = [%d]", 
00180                                      MAX_NETWORKS, networks_found);
00181                     }
00182                 }
00183             }
00184             gdk_threads_leave();
00185         }
00186 
00187         // sort networks and report to GTK thread
00188         qsort(networks, 
00189               networks_found, 
00190               sizeof(networks[0]), 
00191               compare_networks);
00192         for (i = 0 ; i < networks_found && i < parms->networks_num ; i++)
00193         {
00194             parms->networks[i] = networks[i];
00195             parms->networks_found++;
00196         }
00197         for ( ; i < networks_found ; i++)
00198         {
00199             g_free(networks[i].ssid);
00200         }
00201     }
00202     g_free(p_stdout);
00203     p_stdout = NULL;
00204 
00205     // tell GTK thread we are done ...
00206     gdk_threads_enter();
00207     {
00208         g_scan_thread = NULL;
00209         if (gtk_main_level() == 0)
00210         {
00211             CN_WARNPRINTF("    -- oops, gtk_main has quit!");
00212         }
00213         else
00214         {
00215             if (g_scan_abort)
00216             {
00217                 gtk_label_set_text(GTK_LABEL(parms->scanStatus), 
00218                                    "scan-done-abort");
00219             }
00220             else
00221             {
00222                 gtk_label_set_text(GTK_LABEL(parms->scanStatus), 
00223                                    "scan-done-ok");
00224             }
00225         }
00226     }
00227     gdk_threads_leave();
00228     
00229     // ... and quit
00230     CN_LOGPRINTF("exit");
00231     g_free(networks);
00232     return 0;
00233 }

Here is the call graph for this function:

gboolean scanThread_start ( scan_thread_parms scan_parms  ) 

Definition at line 236 of file scanThread.c.

00237 {
00238     GThread* thread = NULL;
00239     GError*  error = NULL;
00240 
00241     CN_LOGPRINTF("entry");
00242     if (g_scan_thread)
00243     {
00244         CN_ERRORPRINTF("scan thread already running");
00245         return FALSE;
00246     }
00247 
00248     // create the scan thread
00249     g_scan_abort = FALSE;
00250     thread = g_thread_create(scanThread, scan_parms, FALSE, &error);
00251     if (error != NULL)
00252     {
00253         CN_ERRORPRINTF("Failed to create scan thread - %s [%d]", 
00254                        error->message, error->code);
00255         g_free(error);
00256         error = NULL;
00257     }
00258     else
00259     {
00260         g_scan_thread = thread;
00261     }
00262 
00263     return TRUE;
00264 }

Here is the call graph for this function:

gboolean scanThread_stop ( void   ) 

Definition at line 267 of file scanThread.c.

00268 {
00269     CN_LOGPRINTF("entry");
00270 
00271     if (g_scan_thread)
00272     {
00273         // stop the scan thread
00274         g_scan_abort = TRUE;
00275 
00276         return TRUE;
00277     }
00278     else
00279     {
00280         CN_ERRORPRINTF("scan thread not running");
00281         return FALSE;
00282     }
00283 }

gboolean scanThread_stopped ( void   ) 

Definition at line 309 of file scanThread.c.

00310 {
00311     CN_LOGPRINTF("entry");
00312 
00313     if (g_scan_thread)
00314     {
00315         return FALSE;
00316     }
00317     else
00318     {
00319         return TRUE;
00320     }
00321 }

gboolean scanThread_wait ( int  timeout_sec  ) 

Definition at line 286 of file scanThread.c.

00287 {
00288     int max_ticks = 2 * timeout_sec;
00289 
00290     CN_LOGPRINTF("entry");
00291     if (g_scan_thread)
00292     {
00293         // sorry don't like busy-wait, 
00294         // but g_thread_join has no timeout option
00295         while (g_scan_thread  &&  --max_ticks >= 0)
00296         {
00297             g_usleep(500*1000L);
00298         }
00299 
00300         return TRUE;
00301     }
00302     else
00303     {
00304         CN_ERRORPRINTF("scan thread not running");
00305         return FALSE;
00306     }
00307 }


Variable Documentation

volatile gboolean g_scan_abort = FALSE [static]

Definition at line 36 of file scanThread.c.

volatile GThread* g_scan_thread = NULL [static]

Definition at line 35 of file scanThread.c.


Generated on Sun Dec 14 17:16:44 2008 by  doxygen 1.5.6