Wi-Fi සහ තවත් බොහෝ කෙටි යෙදුම්. ඉදිමුමකින් තොරව Android යෙදුමක Wi-Fi නෝඩ් පිළිබඳ දත්ත ලබා ගන්නේ කෙසේද

දිනක් මට Android යෙදුම් වලින් Wi-Fi ජාල පරිලෝකනය කිරීමට සහ ප්‍රවේශ ස්ථාන පිළිබඳ සවිස්තර දත්ත ලබා ගැනීමට අවශ්‍ය විය.

මෙහිදී අපට දුෂ්කරතා කිහිපයකට මුහුණ දීමට සිදු විය: off.Android ලියකියවිලි විස්තර කරන ලද බොහෝ පන්ති අත්හරින ලදී (API මට්ටම > 26), එය පිළිබිඹු නොවීය; ප්‍රලේඛනයේ සමහර දේවල් පිළිබඳ විස්තරය අවම වේ (උදාහරණයක් ලෙස, පන්තියේ හැකියාවන් ක්ෂේත්‍රය ස්කෑන් ප්‍රතිඵලය වැදගත් දත්ත රාශියක් අඩංගු වුවද ලියන අවස්ථාවේදී කිසිවක් පාහේ විස්තර කර නොමැත). තුන්වන දුෂ්කරතාවය වනුයේ ඔබ මුලින්ම Wi-Fi වෙත සමීප වූ විට, න්‍යාය කියවීම සහ localhost හරහා රවුටරය සැකසීම හැර, ඔබට තනි තනිව තේරුම් ගත හැකි යැයි පෙනෙන කෙටි යෙදුම් ගණනාවක් සමඟ කටයුතු කිරීමට සිදුවනු ඇත. නමුත් ඒවා සම්බන්ධ කරන්නේ කෙසේද සහ ව්‍යුහගත කරන්නේ කෙසේද යන්න පැහැදිලි නොවිය හැකිය (විනිශ්චය ආත්මීය වන අතර පෙර අත්දැකීම් මත රඳා පවතී).

මෙම ලිපියෙන් සාකච්ඡා කරන්නේ NDK, හැක් කිරීම් නොමැතිව Android කේතයෙන් Wi-Fi පරිසරය පිළිබඳ සවිස්තරාත්මක දත්ත ලබා ගන්නේ කෙසේද, නමුත් Android API භාවිතයෙන් පමණක් සහ එය අර්ථ නිරූපණය කරන්නේ කෙසේද යන්න තේරුම් ගැනීමයි.

අපි ප්‍රමාද නොවී කේතය ලිවීම ආරම්භ කරමු.

1. ව්යාපෘතියක් සාදන්න

මෙම සටහන එක් වරකට වඩා Android ව්‍යාපෘතියක් නිර්මාණය කර ඇති අය සඳහා අදහස් කෙරේ, එබැවින් අපි මෙම අයිතමයේ විස්තර මඟ හරිමු. පහත කේතය Kotlin, minSdkVersion=23 හි ඉදිරිපත් කෙරේ.

2. ප්‍රවේශ අවසර

යෙදුමෙන් Wi-Fi සමඟ වැඩ කිරීමට, ඔබ පරිශීලකයාගෙන් අවසර කිහිපයක් ලබා ගැනීමට අවශ්ය වනු ඇත. අනුකූලව ලේඛනගත කිරීම, 8.0 ට පසු OS අනුවාද සහිත උපාංගවල ජාලය පරිලෝකනය කිරීම සඳහා, ජාල පරිසරයේ තත්ත්වය බැලීම සඳහා ප්‍රවේශයට අමතරව, ඔබට උපාංගයේ Wi-Fi මොඩියුලයේ තත්ත්වය වෙනස් කිරීමට ප්‍රවේශය අවශ්‍ය වේ, නැතහොත් ඛණ්ඩාංක වෙත ප්‍රවේශය (ආසන්න වශයෙන් හෝ හරියටම). 9.0 අනුවාදයෙන් පටන් ගෙන, ඔබ දෙකම සඳහා පරිශීලකයාගෙන් විමසිය යුතු අතර, ස්ථාන සේවා ක්‍රියාත්මක කිරීමට පරිශීලකයාගෙන් පැහැදිලිවම ඉල්ලා සිටිය යුතුය. මෙය ගූගල්ගේ අභිමතය පරිදි මිස ඔහු ගැන ඔත්තු බැලීමට අපගේ ආශාව නොවන බව පරිශීලකයාට නිර්භීත ලෙස පැහැදිලි කිරීමට අමතක නොකරන්න :)

එබැවින්, AndroidManifest.xml හි අපි එකතු කරන්නෙමු:

    <uses-permission android_name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android_name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android_name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android_name="android.permission.ACCESS_FINE_LOCATION"/>

සහ වත්මන් ක්‍රියාකාරකම් වෙත සබැඳියක් අඩංගු කේතයේ:

import android.app.Activity
import android.content.Context
import android.location.LocationManager
import androidx.core.app.ActivityCompat

....

if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            ActivityCompat.requestPermissions(
                activity,
                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.CHANGE_WIFI_STATE),
                1
            )
            makeEnableLocationServices(activity.applicationContext)
        } else {
            ActivityCompat.requestPermissions(
                activity,
                arrayOf(Manifest.permission.CHANGE_WIFI_STATE),
                1
            )
        }

    /* включает экран включения службы по определению местоположения */
    fun makeEnableLocationServices(context: Context) {
        // TODO: перед вызовом этой функции надо рассказать пользователю, зачем Вам доступ к местоположению
        val lm: LocationManager =
            context.applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager

        val gpsEnabled: Boolean = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
        val networkEnabled: Boolean = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        if (!gpsEnabled && !networkEnabled) {
            context.startActivity(Intent(ACTION_LOCATION_SOURCE_SETTINGS));
        }
    }

3. බ්‍රෝඩ්කාස්ට් ග්‍රාහකයක් සාදන්න සහ Wi-Fi ජාල පරිසරය පරිලෝකනය කිරීම පිළිබඳ දත්ත යාවත්කාලීන සිදුවීම් සඳහා දායක වන්න

val wifiManager = context.getSystemService(Context.WIFI_SERVICE) as WifiManager

val wifiScanReceiver = object : BroadcastReceiver() {

  override fun onReceive(context: Context, intent: Intent) {
    val success = intent.getBooleanExtra(WifiManager.EXTRA_RESULTS_UPDATED, false)
    if (success) {
      scanSuccess()
    } 
  }
}

val intentFilter = IntentFilter()
/* подписываемся на сообщения о получении новых результатов сканирования */
intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)
context.registerReceiver(wifiScanReceiver, intentFilter)

val success = wifiManager.startScan()
if (!success) {
  /* что-то не получилось при запуске сканирования, проверьте выданые разрешения */
}

....

private fun scanSuccess() {
 /* вот они, результаты сканирования */
  val results: List<ScanResult> = wifiManager.scanResults
}

ප්‍රලේඛනයේ WiFiManager.startScan ක්‍රමය API අනුවාදය 28 සිට depricated ලෙස සලකුණු කර ඇත, නමුත් අක්‍රියයි. මඟ පෙන්වීමක් එය භාවිතා කිරීමට යෝජනා කරයි.

සමස්තයක් වශයෙන්, අපට වස්තූන් ලැයිස්තුවක් ලැබුණි ස්කෑන් ප්‍රතිඵලය.

4. ScanResult බලන්න සහ නියමයන් තේරුම් ගන්න

මෙම පන්තියේ සමහර ක්ෂේත්‍ර දෙස බලා ඒවායින් අදහස් කරන දේ විස්තර කරමු:

SSID — Service Set Identifier යනු ජාලයේ නමයි

BSSID - මූලික සේවා කට්ටල හඳුනාගැනීම - ජාල ඇඩැප්ටරයේ MAC ලිපිනය (Wi-Fi ලක්ෂ්‍යය)

මට්ටමින් - ලැබුණු සංඥා ශක්තිය දර්ශකය [dBm (රුසියානු dBm) - Decibel, යොමු බලය 1 mW.] - ලැබුණු සංඥා ශක්තියේ දර්ශකයකි. 0 සිට -100 දක්වා අගයක් ගනී, 0 සිට තව දුරටත්, Wi-Fi ලක්ෂ්‍යයේ සිට ඔබේ උපාංගයට යන ගමනේදී වැඩි සංඥා බලයක් අහිමි විය. වැඩි විස්තර සොයා ගත හැක, උදාහරණයක් ලෙස, දී විකිපීඩියා. මෙන්න මම Android පන්තිය භාවිතා කරන බව ඔබට කියමි වයිෆයි මැනේජර් ඔබ තෝරා ගන්නා පියවරේදී ඔබට සංඥා මට්ටම විශිෂ්ට සිට භයානක දක්වා පරිමාණයෙන් ක්‍රමාංකනය කළ හැක:

        val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
        val numberOfLevels = 5
        val level = WifiManager.calculateSignalLevel(level, numberOfLevels)

සංඛ්යාත - Wi-Fi ලක්ෂ්‍යයේ [Hz] මෙහෙයුම් සංඛ්‍යාතය. සංඛ්යාතයට අමතරව, ඔබ ඊනියා නාලිකාව ගැන උනන්දු විය හැකිය. සෑම ලක්ෂයකටම තමන්ගේම මෙහෙයුම් සංශුද්ධතාවය ඇත. ලියන අවස්ථාව වන විට, Wi-Fi ලක්ෂ්‍යවල වඩාත් ජනප්‍රිය පරාසය 2.4 GHz වේ. නමුත්, වඩාත් නිවැරදිව කිවහොත්, ලක්ෂ්‍යය ඔබගේ දුරකථනයට නම් කරන ලද සංඛ්‍යාතයට ආසන්න සංඛ්‍යාතයකින් තොරතුරු සම්ප්‍රේෂණය කරයි. නාලිකා ගණන සහ අනුරූප සංඛ්යාත සම්මත කර ඇත. මෙය සිදු කරනු ලබන්නේ අසල ඇති ස්ථාන විවිධ සංඛ්‍යාතවල ක්‍රියාත්මක වන අතර එමඟින් එකිනෙකාට බාධා නොවන අතර සම්ප්‍රේෂණයේ වේගය සහ ගුණාත්මකභාවය අන්‍යෝන්‍ය වශයෙන් අඩු නොවේ. මෙම අවස්ථාවෙහිදී, ලක්ෂ්ය එක් සංඛ්යාතයක නොව, සංඛ්යාත පරාසයක් (පරාමිතිය නාලිකා පළල), නාලිකා පළල ලෙස හැඳින්වේ. එනම්, යාබද (සහ යාබදව පමණක් නොව, ඔවුන්ගෙන් 3 ක් පවා) ක්‍රියාත්මක වන ලකුණු එකිනෙකට බාධා කරයි. 2.4 සහ 5 Ghz සංඛ්‍යාතයක් සහිත ලක්ෂ්‍ය සඳහා සංඛ්‍යාත අගයෙන් නාලිකා අංකය ගණනය කිරීමට ඔබට ඉඩ සලසන මෙම සරල කේතය ඔබට ප්‍රයෝජනවත් විය හැකිය:


    /* по частоте определяем номер канала */
    val channel: Int
        get() {
            return if (frequency in 2412..2484) {
                (frequency - 2412) / 5 + 1
            } else if (frequency in 5170..5825) {
                (frequency - 5170) / 5 + 34
            } else {
                -1
            }
        }

හැකියාවන් - විශ්ලේෂණය සඳහා වඩාත්ම සිත්ගන්නා ක්ෂේත්‍රය, බොහෝ කාලයක් අවශ්‍ය වන වැඩ. මෙහිදී ලක්ෂ්යයේ "හැකියාවන්" රේඛාවේ ලියා ඇත. මෙම අවස්ථාවෙහිදී, ඔබ ලේඛනවල තන්තු අර්ථකථනය පිළිබඳ විස්තර සෙවීමට අවශ්ය නොවේ. මෙම පේළියේ විය හැකි දේ පිළිබඳ උදාහරණ කිහිපයක් මෙන්න:

[WPA-PSK-TKIP+CCMP][WPA2-PSK-TKIP+CCMP][WPS][ESS]
[WPA2-PSK-CCMP][ESS]
[WPA2-PSK-CCMP+TKIP][ESS]
[WPA-PSK-CCMP+TKIP][WPA2-PSK-CCMP+TKIP][ESS]
[ESS][WPS]

5. කෙටි යෙදුම් සහ විග්‍රහ කිරීමේ හැකියාවන් අවබෝධ කර ගැනීම

android.net.wifi.* පැකේජයේ පන්ති ලිනක්ස් උපයෝගිතා මඟින් ආවරණය යටතේ භාවිතා කරන බව සඳහන් කිරීම වටී. wpa_ඉල්ලුම්කරු සහ හැකියාවන් ක්ෂේත්රයේ ප්රතිදාන ප්රතිඵලය ස්කෑන් කිරීමේදී කොඩි ක්ෂේත්රයේ පිටපතකි.

අපි නොකඩවා ක්‍රියා කරන්නෙමු. අපි පළමුව වරහන් තුළ ඇති මූලද්‍රව්‍ය “-“ ලකුණකින් වෙන් කර ඇති ආකෘතියක ප්‍රතිදානය සලකා බලමු:

[WPA-PSK-TKIP+CCMP]
[WPA2-PSK-CCMP]

පළමු අර්ථය ඊනියා විස්තර කරයි. සත්යාපන ක්රමය. එනම්, ප්‍රවේශ ලක්ෂ්‍යය භාවිතා කිරීමට ඉඩ ලබා දීම සඳහා උපාංගය සහ ප්‍රවේශ ලක්ෂ්‍යය සිදු කළ යුතු ක්‍රියා අනුපිළිවෙල කුමක්ද සහ ගෙවුම් භාරය සංකේතනය කරන්නේ කෙසේද යන්නයි. මෙම සටහන ලියන අවස්ථාවේදී, වඩාත් පොදු විකල්ප වන්නේ WPA සහ WPA2 වන අතර, එක් එක් සම්බන්ධිත උපාංගය සෘජුව හෝ ඊනියා හරහා ය. RADIUS සේවාදායකය (WPA-Enterprice) සංකේතනය කළ නාලිකාවක් හරහා මුරපදය සපයයි. බොහෝ දුරට ඉඩ ඇති පරිදි, ඔබගේ නිවසේ ඇති ප්රවේශ ලක්ෂ්යය මෙම යෝජනා ක්රමයට අනුව සම්බන්ධතාවයක් සපයයි. දෙවන අනුවාදය සහ පළමු අනුවාදය අතර වෙනස වන්නේ එය ශක්තිමත් කේතාංකයක් තිබීමයි: AES එදිරිව අනාරක්ෂිත TKIP. වඩාත් සංකීර්ණ සහ දියුණු WPA3 ද ක්‍රමයෙන් හඳුන්වා දෙනු ලැබේ. න්‍යායාත්මකව, ව්‍යවසාය විසඳුම CCKM (සිස්කෝ මධ්‍යගත යතුරු කළමනාකරණය) සමඟ විකල්පයක් තිබිය හැකි නමුත් මම එය කිසි විටෙකත් හමු වී නැත.

MAC ලිපිනය මගින් සත්‍යාපනය කිරීමට ප්‍රවේශ ලක්ෂ්‍යය වින්‍යාස කර තිබිය හැක. නැතහොත්, ප්‍රවේශ ලක්ෂ්‍යය යල් පැන ගිය WEP ඇල්ගොරිතම භාවිතයෙන් දත්ත සපයන්නේ නම්, ඇත්ත වශයෙන්ම සත්‍යාපනයක් නොමැත (මෙහි රහස් යතුර සංකේතාංකන යතුරයි). අපි එවැනි විකල්ප OTHER ලෙස වර්ග කරන්නෙමු.
සැඟවුණු Captive Portal Detection සමඟ public wi-fi තුළ ජනප්‍රිය වූ ක්‍රමයක් ද ඇත - බ්‍රවුසරයක් හරහා සත්‍යාපන ඉල්ලීමක්. එවැනි ප්‍රවේශ ස්ථාන ස්කෑනරයට විවෘත ලෙස දිස්වේ (ඒවා භෞතික සම්බන්ධතාවයේ දෘෂ්ටි කෝණයෙන්). එබැවින්, අපි ඒවා විවෘත ලෙස වර්ගීකරණය කරමු.

දෙවන අගය ලෙස දැක්විය හැක ප්රධාන කළමනාකරණ ඇල්ගොරිතම. මෙය ඉහත විස්තර කර ඇති සත්‍යාපන ක්‍රමයේ පරාමිතියකි. සංකේතාංකන යතුරු හුවමාරු කරන ආකාරය ගැන හරියටම කතා කරයි. හැකි විකල්ප සලකා බලමු. EAP - සඳහන් කරන ලද WPA-Enterprice හි භාවිතා වේ, ඇතුළත් කළ සත්‍යාපන දත්ත සත්‍යාපනය කිරීමට දත්ත සමුදායක් භාවිතා කරයි. SAE - උසස් WPA3 හි භාවිතා වේ, තිරිසන් බලයට වඩා ප්‍රතිරෝධී වේ. PSK - වඩාත් පොදු විකල්පය, මුරපදයක් ඇතුළත් කිරීම සහ එය සංකේතාත්මක ආකාරයෙන් සම්ප්රේෂණය කිරීම ඇතුළත් වේ. IEEE8021X - ජාත්‍යන්තර ප්‍රමිතියකට අනුව (WPA පවුල විසින් සහාය දක්වන ඒවාට වඩා වෙනස්). OWE (Opportunistic Wireless Encryption) යනු අපි OPEN ලෙස වර්ග කළ ලකුණු සඳහා IEEE 802.11 ප්‍රමිතියේ දිගුවකි. OWE විසින් අනාරක්ෂිත ජාලයක් හරහා සම්ප්‍රේෂණය වන දත්ත සංකේතනය කිරීමෙන් එහි ආරක්ෂාව සහතික කරයි. ප්‍රවේශ යතුරු නොමැති විට විකල්පයක් ද හැකි ය, අපි මෙම විකල්පය NONE ලෙස හඳුන්වමු.

තුන්වන පරාමිතිය ඊනියා වේ. සංකේතාංකන යෝජනා ක්රම - සම්ප්‍රේෂණය කරන ලද දත්ත ආරක්ෂා කිරීම සඳහා කේතාංකය හරියටම භාවිතා කරන්නේ කෙසේද? අපි විකල්ප ලැයිස්තුගත කරමු. WEP - RC4 ප්‍රවාහ කේතාංකයක් භාවිතා කරයි, රහස් යතුර සංකේතාංකන යතුරයි, එය නවීන ගුප්තකේතන ලෝකයේ පිළිගත නොහැකි යැයි සැලකේ. TKIP - WPA හි භාවිතා වේ, CKIP - WPA2 හි. TKIP+CKIP - පසුගාමී ගැළපුම සඳහා WPA සහ WPA2 හැකියාව ඇති ලකුණු වලින් දැක්විය හැක.

මූලද්රව්ය තුනක් වෙනුවට, ඔබට හුදකලා WEP සලකුණක් සොයාගත හැකිය:

[WEP]

අප ඉහත සාකච්ඡා කළ පරිදි, නොපවතින යතුරු භාවිතා කිරීම සඳහා ඇල්ගොරිතම සහ පෙරනිමියෙන් සමාන වන සංකේතාංකන ක්‍රමය සඳහන් නොකිරීමට මෙය ප්‍රමාණවත් වේ.

දැන් මෙම වරහන සලකා බලන්න:

[ESS]

මෙම Wi-Fi මෙහෙයුම් ආකාරය හෝ Wi-Fi ජාල ස්ථලකය. ඔබට BSS (මූලික සේවා කට්ටලය) මාදිලිය හමුවිය හැකිය - සම්බන්ධිත උපාංග සන්නිවේදනය කරන එක් ප්‍රවේශ ස්ථානයක් ඇති විට. දේශීය ජාල වල සොයා ගත හැක. රීතියක් ලෙස, විවිධ දේශීය ජාල වලින් උපාංග සම්බන්ධ කිරීම සඳහා ප්‍රවේශ ස්ථාන අවශ්‍ය වේ, එබැවින් ඒවා විස්තීරණ සේවා කට්ටලවල කොටසකි - ESS. IBSSs (ස්වාධීන මූලික සේවා කට්ටල) වර්ගය පෙන්නුම් කරන්නේ උපාංගය Peer-to-Peer ජාලයක කොටසක් බවයි.

ඔබට WPS ධජය ද දැකිය හැකිය:

[WPS]

WPS (Wi-Fi ආරක්ෂිත සැකසුම) යනු Wi-Fi ජාලයක් අර්ධ ස්වයංක්‍රීයව ආරම්භ කිරීම සඳහා වන ප්‍රොටෝකෝලයකි. ආරම්භ කිරීම සඳහා, පරිශීලකයා අක්ෂර 8 ක මුරපදයක් ඇතුළත් කරයි හෝ රවුටරයේ බොත්තමක් ඔබන්න. ඔබගේ ප්‍රවේශ ලක්ෂ්‍යය පළමු වර්ගයේ නම් සහ මෙම පිරික්සුම් කොටුව ඔබගේ ප්‍රවේශ ලක්ෂ්‍යයේ නමට යාබදව දිස්වේ නම්, ඔබ පරිපාලක පැනලය වෙත ගොස් WPS ප්‍රවේශය අක්‍රිය කරන ලෙස තරයේ නිර්දේශ කරනු ලැබේ. කාරණය නම්, බොහෝ විට ඉලක්කම් 8 ක PIN අංකය MAC ලිපිනයෙන් සොයාගත හැකි අතර, එය අපේක්ෂා කළ හැකි කාලයකදී නිරාකරණය කර ගත හැකි අතර, එය වංක ලෙස ප්‍රයෝජන ගත හැකිය.

6. ආකෘතියක් සහ විග්‍රහ කිරීමේ කාර්යයක් සාදන්න

අප ඉහත සොයාගත් දේ මත පදනම්ව, දත්ත පන්ති භාවිතයෙන් සිදු වූ දේ අපි විස්තර කරන්නෙමු:

/* схема аутентификации */
enum class AuthMethod {
    WPA3,
    WPA2,
    WPA, // Wi-Fi Protected Access
    OTHER, // включает в себя Shared Key Authentication и др. использующие mac-address-based и WEP
    CCKM, // Cisco
    OPEN // Open Authentication. Может быть со скрытым Captive Portal Detection - запрос аутентификации через браузер
}

/* алгоритм ввода ключей */
enum class KeyManagementAlgorithm {
    IEEE8021X, // по стандарту
    EAP, // Extensible Authentication Protocol, расширяемый протокол аутентификации
    PSK, // Pre-Shared Key — каждый узел вводит пароль для доступа к сети
    WEP, // в WEP пароль является ключом шифрования (No auth key)
    SAE, // Simultaneous Authentication of Equals - может быть в WPA3
    OWE, // Opportunistic Wireless Encryption - в роутерах новых поколений, публичных сетях типа OPEN
    NONE // может быть без шифрования в OPEN, OTHER
}

/* метод шифрования */
enum class CipherMethod {
    WEP, // Wired Equivalent Privacy, Аналог шифрования трафика в проводных сетях
    TKIP, // Temporal Key Integrity Protocol
    CCMP, // Counter Mode with Cipher Block Chaining Message Authentication Code Protocol,
    // протокол блочного шифрования с кодом аутентичности сообщения и режимом сцепления блоков и счетчика
    // на основе AES
    NONE // может быть без шифрования в OPEN, OTHER
}

/* набор методов шифрования и протоколов, по которым может работать точка */
data class Capability(
    var authScheme: AuthMethod? = null,
    var keyManagementAlgorithm: KeyManagementAlgorithm? = null,
    var cipherMethod: CipherMethod? = null
)

/* Режим работы WiFi (или топология сетей WiFi) */
enum class TopologyMode {
    IBSS, // Эпизодическая сеть (Ad-Hoc или IBSS – Independent Basic Service Set).
    BSS, // Основная зона обслуживания Basic Service Set (BSS) или Infrastructure Mode.
    ESS // Расширенная зона обслуживания ESS – Extended Service Set.
}

දැන් අපි හැකියාවන් ක්ෂේත්‍රය විග්‍රහ කරන ශ්‍රිතයක් ලියන්නෙමු:


private fun parseCapabilities(capabilitiesString: String): List < Capability > {
    val capabilities: List < Capability > = capabilitiesString
        .splitByBrackets()
        .filter {
            !it.isTopology() && !it.isWps()
        }
        .flatMap {
            parseCapability(it)
        }
    return
        if (!capabilities.isEmpty()) {
            capabilities
        } else {
            listOf(Capability(AuthMethod.OPEN, KeyManagementAlgorithm.NONE, CipherMethod.NONE))
        }
}

private fun parseCapability(part: String): List < Capability > {
    if (part.contains("WEP")) {
        return listOf(Capability(
            AuthMethod.OTHER,
            KeyManagementAlgorithm.WEP,
            CipherMethod.WEP
        ))
    }

    val authScheme = when {
        part.contains("WPA3") - > AuthMethod.WPA3
        part.contains("WPA2") - > AuthMethod.WPA2
        part.contains("WPA") - > AuthMethod.WPA
        else - > null
    }

    val keyManagementAlgorithm = when {
        part.contains("OWE") - > KeyManagementAlgorithm.OWE
        part.contains("SAE") - > KeyManagementAlgorithm.SAE
        part.contains("IEEE802.1X") - > KeyManagementAlgorithm.IEEE8021X
        part.contains("EAP") - > KeyManagementAlgorithm.EAP
        part.contains("PSK") - > KeyManagementAlgorithm.PSK
        else - > null
    }

    val capabilities = ArrayList < Capability > ()
    if (part.contains("TKIP") || part.contains("CCMP")) {
        if (part.contains("TKIP")) {
            capabilities.add(Capability(
                authScheme ? : AuthMethod.OPEN,
                keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
                CipherMethod.TKIP
            ))
        }
        if (part.contains("CCMP")) {
            capabilities.add(Capability(
                authScheme ? : AuthMethod.OPEN,
                keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
                CipherMethod.CCMP
            ))
        }
    } else if (authScheme != null || keyManagementAlgorithm != null) {
        capabilities.add(Capability(
            authScheme ? : AuthMethod.OPEN,
            keyManagementAlgorithm ? : KeyManagementAlgorithm.NONE,
            CipherMethod.NONE
        ))
    }

    return capabilities
}

private fun parseTopologyMode(capabilitiesString: String): TopologyMode ? {
    return capabilitiesString
        .splitByBrackets()
        .mapNotNull {
            when {
                it.contains("ESS") - > TopologyMode.ESS
                it.contains("BSS") - > TopologyMode.BSS
                it.contains("IBSS") - > TopologyMode.IBSS
                else - > null
            }
        }
        .firstOrNull()
}

private fun parseWPSAvailable(capabilitiesString: String): Boolean {
    return capabilitiesString
        .splitByBrackets()
        .any {
            it.isWps()
        }
}

private fun String.splitByBrackets(): List < String > {
    val m = Pattern.compile("[(.*?)]").matcher(this)
    val parts = ArrayList < String > ()
    while (m.find()) {
        parts.add(m.group().replace("[", "").replace("]", ""))
    }
    return parts
}

private fun String.isTopology(): Boolean {
    return TopologyMode.values().any {
        this == it.name
    }
}

private fun String.isWps(): Boolean {
    return this == "WPS"
}

8. ප්රතිඵලය බලන්න

මම ජාලය ස්කෑන් කර මා සොයාගත් දේ ඔබට පෙන්වන්නම්. Log.d හරහා සරල ප්‍රතිදානයේ ප්‍රතිඵල පෙන්වා ඇත:

Capability of Home-Home [WPA2-PSK-CCMP][ESS][WPS]
...
capabilities=[Capability(authScheme=WPA2, keyManagementAlgorithm=PSK, cipherMethod=CCMP)], topologyMode=ESS, availableWps=true

යෙදුම් කේතයෙන් ජාලයට සම්බන්ධ වීමේ ගැටලුව නොවිසඳී පැවතුනි. ජංගම උපාංගයක OS වෙතින් සුරකින ලද මුරපද කියවීම සඳහා, ඔබට මූල අයිතිවාසිකම් සහ wpa_supplicant.conf කියවීමට ගොනු පද්ධතිය හරහා ගමන් කිරීමට කැමැත්තක් අවශ්‍ය බව පමණක් මම කියමි. යෙදුම් තර්කයට පිටතින් මුරපදයක් ඇතුළත් කිරීමට අවශ්‍ය නම්, සම්බන්ධතාවය පන්තිය හරහා සිදු කළ හැක android.net.wifi.WifiManager.

ස්තුතියි ඊගෝර් පොනොමරෙව් වටිනා එකතු කිරීම් සඳහා.

යමක් එකතු කිරීමට හෝ නිවැරදි කිරීමට අවශ්‍ය යැයි ඔබ සිතන්නේ නම්, අදහස් දැක්වීමේදී ලියන්න :)

මූලාශ්රය: www.habr.com

අදහස් එක් කරන්න