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