@@ -891,7 +891,13 @@ public void setScanType(boolean active) {
891891 * TODO: doc
892892 */
893893 public List <ScanResult > syncGetScanResultsList () {
894- return mScanResults ;
894+ synchronized (mScanResultCache ) {
895+ List <ScanResult > scanList = new ArrayList <ScanResult >();
896+ for (ScanResult result : mScanResults ) {
897+ scanList .add (new ScanResult (result ));
898+ }
899+ return scanList ;
900+ }
895901 }
896902
897903 /**
@@ -1357,131 +1363,103 @@ private void setWifiApState(int wifiApState) {
13571363 mContext .sendStickyBroadcast (intent );
13581364 }
13591365
1366+ private static final String BSSID_STR = "bssid=" ;
1367+ private static final String FREQ_STR = "freq=" ;
1368+ private static final String LEVEL_STR = "level=" ;
1369+ private static final String TSF_STR = "tsf=" ;
1370+ private static final String FLAGS_STR = "flags=" ;
1371+ private static final String SSID_STR = "ssid=" ;
1372+ private static final String DELIMITER_STR = "====" ;
13601373 /**
1361- * Parse the scan result line passed to us by wpa_supplicant (helper).
1362- * @param line the line to parse
1363- * @return the {@link ScanResult} object
1374+ * Format:
1375+ * bssid=68:7f:76:d7:1a:6e
1376+ * freq=2412
1377+ * level=-44
1378+ * tsf=1344626243700342
1379+ * flags=[WPA2-PSK-CCMP][WPS][ESS]
1380+ * ssid=zfdy
1381+ * ====
1382+ * bssid=68:5f:74:d7:1a:6f
1383+ * freq=5180
1384+ * level=-73
1385+ * tsf=1344626243700373
1386+ * flags=[WPA2-PSK-CCMP][WPS][ESS]
1387+ * ssid=zuby
1388+ * ====
13641389 */
1365- private ScanResult parseScanResult (String line ) {
1366- ScanResult scanResult = null ;
1367- if (line != null ) {
1368- /*
1369- * Cache implementation (LinkedHashMap) is not synchronized, thus,
1370- * must synchronized here!
1371- */
1372- synchronized (mScanResultCache ) {
1373- String [] result = scanResultPattern .split (line );
1374- if (3 <= result .length && result .length <= 5 ) {
1375- String bssid = result [0 ];
1376- // bssid | frequency | level | flags | ssid
1377- int frequency ;
1378- int level ;
1390+ private void setScanResults (String scanResults ) {
1391+ String bssid = "" ;
1392+ int level = 0 ;
1393+ int freq = 0 ;
1394+ long tsf = 0 ;
1395+ String flags = "" ;
1396+ String ssid = "" ;
1397+
1398+ if (scanResults == null ) {
1399+ return ;
1400+ }
1401+
1402+ synchronized (mScanResultCache ) {
1403+ mScanResults = new ArrayList <ScanResult >();
1404+ String [] lines = scanResults .split ("\n " );
1405+
1406+ for (String line : lines ) {
1407+ if (line .startsWith (BSSID_STR )) {
1408+ bssid = line .substring (BSSID_STR .length ());
1409+ } else if (line .startsWith (FREQ_STR )) {
13791410 try {
1380- frequency = Integer .parseInt (result [1 ]);
1381- level = Integer .parseInt (result [2 ]);
1411+ freq = Integer .parseInt (line .substring (FREQ_STR .length ()));
1412+ } catch (NumberFormatException e ) {
1413+ freq = 0 ;
1414+ }
1415+ } else if (line .startsWith (LEVEL_STR )) {
1416+ try {
1417+ level = Integer .parseInt (line .substring (LEVEL_STR .length ()));
13821418 /* some implementations avoid negative values by adding 256
13831419 * so we need to adjust for that here.
13841420 */
13851421 if (level > 0 ) level -= 256 ;
1386- } catch (NumberFormatException e ) {
1387- frequency = 0 ;
1422+ } catch (NumberFormatException e ) {
13881423 level = 0 ;
13891424 }
1390-
1391- /*
1392- * The formatting of the results returned by
1393- * wpa_supplicant is intended to make the fields
1394- * line up nicely when printed,
1395- * not to make them easy to parse. So we have to
1396- * apply some heuristics to figure out which field
1397- * is the SSID and which field is the flags.
1398- */
1399- String ssid ;
1400- String flags ;
1401- if (result .length == 4 ) {
1402- if (result [3 ].charAt (0 ) == '[' ) {
1403- flags = result [3 ];
1404- ssid = "" ;
1425+ } else if (line .startsWith (TSF_STR )) {
1426+ try {
1427+ tsf = Long .parseLong (line .substring (TSF_STR .length ()));
1428+ } catch (NumberFormatException e ) {
1429+ tsf = 0 ;
1430+ }
1431+ } else if (line .startsWith (FLAGS_STR )) {
1432+ flags = line .substring (FLAGS_STR .length ());
1433+ } else if (line .startsWith (SSID_STR )) {
1434+ ssid = line .substring (SSID_STR .length ());
1435+ if (ssid == null ) ssid = "" ;
1436+ } else if (line .startsWith (DELIMITER_STR )) {
1437+ if (bssid != null ) {
1438+ String key = bssid + ssid ;
1439+ ScanResult scanResult = mScanResultCache .get (key );
1440+ if (scanResult != null ) {
1441+ scanResult .level = level ;
1442+ scanResult .SSID = ssid ;
1443+ scanResult .capabilities = flags ;
1444+ scanResult .frequency = freq ;
1445+ scanResult .timestamp = tsf ;
14051446 } else {
1406- flags = "" ;
1407- ssid = result [3 ];
1408- }
1409- } else if (result .length == 5 ) {
1410- flags = result [3 ];
1411- ssid = result [4 ];
1412- } else {
1413- // Here, we must have 3 fields: no flags and ssid
1414- // set
1415- flags = "" ;
1416- ssid = "" ;
1417- }
1418-
1419- // bssid + ssid is the hash key
1420- String key = bssid + ssid ;
1421- scanResult = mScanResultCache .get (key );
1422- if (scanResult != null ) {
1423- scanResult .level = level ;
1424- scanResult .SSID = ssid ;
1425- scanResult .capabilities = flags ;
1426- scanResult .frequency = frequency ;
1427- } else {
1428- // Do not add scan results that have no SSID set
1429- if (0 < ssid .trim ().length ()) {
14301447 scanResult =
14311448 new ScanResult (
1432- ssid , bssid , flags , level , frequency );
1449+ ssid , bssid , flags , level , freq , tsf );
14331450 mScanResultCache .put (key , scanResult );
14341451 }
1435- }
1436- } else {
1437- loge ("Misformatted scan result text with " +
1438- result .length + " fields: " + line );
1439- }
1440- }
1441- }
1442-
1443- return scanResult ;
1444- }
1445-
1446- /**
1447- * scanResults input format
1448- * 00:bb:cc:dd:cc:ee 2427 166 [WPA-EAP-TKIP][WPA2-EAP-CCMP] Net1
1449- * 00:bb:cc:dd:cc:ff 2412 165 [WPA-EAP-TKIP][WPA2-EAP-CCMP] Net2
1450- */
1451- private void setScanResults (String scanResults ) {
1452- if (scanResults == null ) {
1453- return ;
1454- }
1455-
1456- List <ScanResult > scanList = new ArrayList <ScanResult >();
1457-
1458- int lineCount = 0 ;
1459-
1460- int scanResultsLen = scanResults .length ();
1461- // Parse the result string, keeping in mind that the last line does
1462- // not end with a newline.
1463- for (int lineBeg = 0 , lineEnd = 0 ; lineEnd <= scanResultsLen ; ++lineEnd ) {
1464- if (lineEnd == scanResultsLen || scanResults .charAt (lineEnd ) == '\n' ) {
1465- ++lineCount ;
1466-
1467- if (lineCount == 1 ) {
1468- lineBeg = lineEnd + 1 ;
1469- continue ;
1452+ mScanResults .add (scanResult );
1453+ }
1454+ bssid = null ;
1455+ level = 0 ;
1456+ freq = 0 ;
1457+ tsf = 0 ;
1458+ flags = "" ;
1459+ ssid = "" ;
14701460 }
1471- if (lineEnd > lineBeg ) {
1472- String line = scanResults .substring (lineBeg , lineEnd );
1473- ScanResult scanResult = parseScanResult (line );
1474- if (scanResult != null ) {
1475- scanList .add (scanResult );
1476- } else {
1477- //TODO: hidden network handling
1478- }
1479- }
1480- lineBeg = lineEnd + 1 ;
14811461 }
14821462 }
1483-
1484- mScanResults = scanList ;
14851463 }
14861464
14871465 /*
@@ -2828,7 +2806,7 @@ public void exit() {
28282806 if (DBG ) log (getName () + "\n " );
28292807 mIsRunning = false ;
28302808 updateBatteryWorkSource (null );
2831- mScanResults = null ;
2809+ mScanResults = new ArrayList < ScanResult >() ;
28322810
28332811 if (mP2pSupported ) mWifiP2pChannel .sendMessage (WifiStateMachine .CMD_DISABLE_P2P );
28342812 mContext .unregisterReceiver (mScreenReceiver );
0 commit comments