00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00026 #include <string.h>
00027 #include <stdlib.h>
00028 
00029 #include "connectionMgrLog.h"
00030 #include "connectionMgr.h"
00031 #include "scanThread.h"
00032 
00033 #define MAX_NETWORKS  50
00034 
00035 static volatile GThread* g_scan_thread = NULL;
00036 static volatile gboolean g_scan_abort  = FALSE;
00037 
00038 
00039 static int compare_networks(const void* p1, const void* p2);
00040 static int quality_to_integer(const char*string);
00041 
00042 static gpointer scanThread(gpointer arg)
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         
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         
00067         networks = g_new0(network_spec_t, MAX_NETWORKS);
00068         g_assert(networks != NULL);
00069 
00070         
00071         gtk_label_set_text(GTK_LABEL(parms->scanStatus), "scan-started");
00072     }
00073     gdk_threads_leave();
00074 
00075     
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             
00097             
00098             char *ssid = NULL;
00099             char *security = NULL;
00100             char *quality = NULL;
00101             wireless_encr_type_t encr_type = encr_none_t;
00102 
00103             
00104             gdk_threads_enter();
00105             {
00106                 
00107                 
00108                 cp = strchr(line, ' ');
00109                 if (cp  &&  cp[1] == '"')
00110                 {
00111                     *cp = '\0';
00112                     
00113                     
00114                     
00115                     
00116                     
00117                     ssid = cp + 2;
00118                     cp = strchr(ssid, '"');
00119                     if (cp  &&  cp[1] == ' ')
00120                     {
00121                         *cp = '\0';
00122 
00123                         
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                             
00147                             quality = cp + 1;
00148                             cp = strchr(quality, ' ');
00149                             if (cp)
00150                             {
00151                                 *cp = '\0';
00152                             }
00153                         }
00154                     }
00155                 }
00156                 
00157                 
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                         
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         
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     
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     
00230     CN_LOGPRINTF("exit");
00231     g_free(networks);
00232     return 0;
00233 }
00234 
00235 
00236 gboolean scanThread_start(scan_thread_parms* scan_parms)
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     
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 }
00265 
00266 
00267 gboolean scanThread_stop()
00268 {
00269     CN_LOGPRINTF("entry");
00270 
00271     if (g_scan_thread)
00272     {
00273         
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 }
00284 
00285 
00286 gboolean scanThread_wait(int timeout_sec)
00287 {
00288     int max_ticks = 2 * timeout_sec;
00289 
00290     CN_LOGPRINTF("entry");
00291     if (g_scan_thread)
00292     {
00293         
00294         
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 }
00308 
00309 gboolean scanThread_stopped(void)
00310 {
00311     CN_LOGPRINTF("entry");
00312 
00313     if (g_scan_thread)
00314     {
00315         return FALSE;
00316     }
00317     else
00318     {
00319         return TRUE;
00320     }
00321 }
00322 
00323 static int compare_networks(const void* p1, const void* p2)
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         
00332         ret = left->quality - right->quality;
00333     }
00334     else if (left->encryption != right->encryption)
00335     {
00336         
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         
00376         ret = g_ascii_strcasecmp(left->ssid, right->ssid);
00377     }
00378    
00379     CN_LOGPRINTF("ret=%d", ret);
00380 
00381     
00382     ret = 0 - ret; 
00383     return ret;
00384 }
00385 
00386 
00387 static int quality_to_integer(const char*string)
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 }
00427 
00428 void free_network_spec(network_spec_t* pNetwork)
00429 {
00430     if (pNetwork)
00431     {
00432         g_free(pNetwork->ssid);
00433         g_free(pNetwork);
00434     }
00435 }
00436 
00437 network_spec_t *dup_network_spec(network_spec_t* pNetwork)
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 }
00452