#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_t * | dup_network_spec (network_spec_t *pNetwork) |
Variables | |
static volatile GThread * | g_scan_thread = NULL |
static volatile gboolean | g_scan_abort = FALSE |
#define MAX_NETWORKS 50 |
Definition at line 33 of file scanThread.c.
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 }
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 }
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 }
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.