Egun batean Android aplikazioetatik Wi-Fi sareak eskaneatu eta sarbide puntuei buruzko datu zehatzak lortu behar izan nituen.
Hemen hainbat zailtasunei aurre egin behar izan diegu:
Artikulu honek Wi-Fi inguruneari buruzko datu integralak nola lortu aztertzen du Android kodetik NDK, hackik gabe, baina Android APIa erabiliz soilik eta nola interpretatu ulertzen.
Ez gaitezen atzeratu eta has gaitezen kodea idazten.
1. Proiektu bat sortu
Ohar hau Android proiektu bat behin baino gehiagotan sortu dutenentzat pentsatuta dago, beraz, elementu honen xehetasunak baztertzen ditugu. Beheko kodea Kotlin-en aurkeztuko da, minSdkVersion=23.
2. Sarbide-baimenak
Aplikaziotik Wi-Fi-arekin lan egiteko, erabiltzailearen hainbat baimen lortu beharko dituzu. -ren arabera
Beraz, AndroidManifest.xml-n gehituko dugu:
<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"/>
Eta uneko Jarduerarako esteka duen kodean:
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. Sortu Broadcast Receiver eta harpidetu Wi-Fi sarearen ingurunea eskaneatzeari buruzko datuak eguneratzeko ekitaldietara.
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
}
Dokumentazioko WiFiManager.startScan metodoa deskargatu gisa markatuta dago APIaren 28 bertsiotik, baina desaktibatuta dago.
Guztira, objektuen zerrenda jaso dugu
4. Begiratu ScanResult-i eta ulertu terminoak
Ikus ditzagun klase honetako eremu batzuk eta deskriba ditzagun zer esan nahi duten:
SSID β Service Set Identifier sarearen izena da
BSSID - Oinarrizko zerbitzu multzoaren identifikatzailea - sare-egokitzailearen MAC helbidea (Wi-Fi puntua)
maila β Jasotako seinalearen indarraren adierazlea [dBm (errusiako dBm) β Dezibelioa, erreferentzia-potentzia 1 mW.] β Jasotako seinalearen indarraren adierazlea. 0tik -100 arteko balioa hartzen du, zenbat eta 0tik urrunago, orduan eta seinale potentzia gehiago galdu da Wi-Fi puntutik zure gailurako bidean. Xehetasun gehiago aurki daitezke, adibidez, helbidean
val wifiManager = context.applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
val numberOfLevels = 5
val level = WifiManager.calculateSignalLevel(level, numberOfLevels)
maiztasuna β Wi-Fi puntuaren funtzionamendu-maiztasuna [Hz]. Maiztasunaz gain, kanala deiturikoa interesatzen zaizu. Puntu bakoitzak bere funtzionamendu-garbitasuna du. Idazteko unean, Wi-Fi puntuen gamarik ezagunena 2.4 GHz da. Baina, zehatzago esateko, puntuak zure telefonora igortzen du informazioa izena duenetik hurbil dagoen zenbakidun maiztasun batean. Kanal kopurua eta dagozkion maiztasunak
/* ΠΏΠΎ ΡΠ°ΡΡΠΎΡΠ΅ ΠΎΠΏΡΠ΅Π΄Π΅Π»ΡΠ΅ΠΌ Π½ΠΎΠΌΠ΅Ρ ΠΊΠ°Π½Π°Π»Π° */
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
}
}
gaitasun - analisirako arlorik interesgarriena, denbora asko behar izan duen lana. Hemen puntuaren "gaitasunak" lerroan idatzita daude. Kasu honetan, ez duzu dokumentazioan kateen interpretazioaren xehetasunak bilatu beharrik. Hona hemen lerro honetan egon daitekeenaren adibide batzuk:
[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. Laburdurak eta analizatzeko gaitasunak ulertzea
Aipatzekoa da Android.net.wifi.* paketearen klaseak Linux utilitate batek kaputxa azpian erabiltzen dituela.
Koherentziaz jokatuko dugu. Har dezagun lehenik parentesi barruko elementuak β-β zeinu batez bereizten diren formatu baten irteera:
[WPA-PSK-TKIP+CCMP]
[WPA2-PSK-CCMP]
Lehenengo esanahiak deiturikoak deskribatzen ditu. autentifikazio metodoa. Hau da, zer ekintzen sekuentzia egin behar duten gailuak eta sarbide-puntuak sarbide-puntuak bere burua erabiltzeko eta nola enkriptatu karga erabilgarria izateko. Post hau idazteko momentuan, aukerarik ohikoenak WPA eta WPA2 dira, zeinetan konektatutako gailu bakoitza zuzenean edo deitzen denaren bidez. RADIUS zerbitzariak (WPA-Enterprice) enkriptatutako kanal baten bidez ematen du pasahitza. Seguruenik, zure etxeko sarguneak eskema honen araberako konexioa eskaintzen du. Bigarren bertsioaren eta lehenengoaren arteko aldea zifratze indartsuagoa duela da: AES versus TKIP segurua. WPA3 ere, konplexuagoa eta aurreratuagoa dena, pixkanaka sartzen ari da. Teorian, aukera bat egon daiteke CCKM (Cisco Centralized Key Management) enterprice irtenbidearekin, baina ez dut inoiz topatu.
Baliteke sarbide-puntua MAC helbidearen bidez autentifikatzeko konfiguratuta egotea. Edo, sarbide-puntuak WEP algoritmo zaharkitua erabiliz datuak ematen baditu, egia esan ez dago autentifikaziorik (gako sekretua hemen enkriptatze-gakoa da). Bestelako aukerak bezala sailkatzen ditugu.
Wi-fi publikoan ezaguna den metodo bat ere badago ezkutuko Atari Gatibuen Detekzioarekin: arakatzaile baten bidez autentifikazio eskaera. Sarbide horiek irekita agertzen zaizkio eskanerari (konexio fisikoaren ikuspuntutik dira). Horregatik, IREKI gisa sailkatzen ditugu.
Bigarren balioa honela adieraz daiteke gakoak kudeatzeko algoritmoa. Hau goian deskribatutako autentifikazio metodoaren parametro bat da. Zifratze-gakoak nola trukatzen diren zehatz-mehatz hitz egiten du. Azter ditzagun aukera posibleak. EAP - aipatutako WPA-Enterprice-n erabiltzen dena, datu-base bat erabiltzen du sartutako autentifikazio-datuak egiaztatzeko. SAE - WPA3 aurreratuan erabiltzen da, indar gordinaren aurrean erresistenteagoa. PSK - aukerarik ohikoena, pasahitz bat sartu eta enkriptatutako forman transmititzea dakar. IEEE8021X - nazioarteko estandar baten arabera (WPA familiak onartzen duenaren ezberdina). OWE (Opportunistic Wireless Encryption) IEEE 802.11 estandarraren luzapena da OPEN gisa sailkatu ditugun puntuetarako. OWE-k segurtasunik gabeko sare baten bidez transmititzen diren datuen segurtasuna bermatzen du, enkriptatuz. Aukera bat ere posible da sarbide-gakorik ez dagoenean, dei diezaiogun EZER aukera honi.
Hirugarren parametroa izenekoa da. enkriptatzeko eskemak β nola erabiltzen den zifratua transmititutako datuak babesteko. Zerrenda ditzagun aukerak. WEP - RC4 korronte zifratua erabiltzen du, gako sekretua enkriptatze-gakoa da, kriptografia modernoaren munduan onartezina dena. TKIP - WPAn erabiltzen da, CKIP - WPA2n. TKIP+CKIP - WPA eta WPA2 gai diren puntuetan zehaztu daiteke atzerako bateragarritasunerako.
Hiru elementuren ordez, WEP marka bakarti bat aurki dezakezu:
[WEP]
Goian aipatu dugun bezala, nahikoa da gakoak erabiltzeko algoritmoa, existitzen ez dena, eta enkriptatzeko metodoa, lehenespenez berdina dena.
Orain kontuan hartu parentesi hau:
[ESS]
It Wi-Fi funtzionamendu modua edo Wi-Fi sarearen topologia. BSS (Oinarrizko Zerbitzu multzoa) modua aurki dezakezu - konektatutako gailuak komunikatzeko sarbide puntu bat dagoenean. Sare lokaletan aurki daiteke. Oro har, sarbide-puntuak behar dira sare lokal ezberdinetako gailuak konektatzeko, beraz, Zerbitzu Hedatuen Multzoen - ESSren parte dira. IBSSak (Independent Basic Service Sets) motak adierazten du gailua Peer-to-Peer sare baten parte dela.
WPS bandera ere ikus dezakezu:
[WPS]
WPS (Wi-Fi Protected Setup) Wi-Fi sare baten hasierako hasierako protokoloa da. Hasieratzeko, erabiltzaileak 8 karaktereko pasahitza sartzen du edo bideratzailearen botoi bat sakatzen du. Zure sarbide-puntua lehen motakoa bada eta kontrol-lauki hau zure sarbide-puntuaren izenaren ondoan agertzen bada, gomendagarria da administrazio panelera joatea eta WPS sarbidea desgaitzea. Kontua da askotan 8 digituko PINa MAC helbidearen bidez aurki daitekeela, edo aurreikusten den denbora batean konpondu daitekeela, norbaitek desleialki aprobetxa dezakeela.
6. Sortu eredua eta analisi-funtzioa
Goian aurkitu dugunaren arabera, datu klaseak erabiliz gertatutakoa deskribatuko dugu:
/* ΡΡ
Π΅ΠΌΠ° Π°ΡΡΠ΅Π½ΡΠΈΡΠΈΠΊΠ°ΡΠΈΠΈ */
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.
}
Orain idatz dezagun gaitasunen eremua analizatuko duen funtzio bat:
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. Ikusi emaitza
Sarea eskaneatu eta aurkitu dudana erakutsiko dizut. Log.d bidezko irteera sinplearen emaitzak erakusten dira:
Capability of Home-Home [WPA2-PSK-CCMP][ESS][WPS]
...
capabilities=[Capability(authScheme=WPA2, keyManagementAlgorithm=PSK, cipherMethod=CCMP)], topologyMode=ESS, availableWps=true
Aplikazio-kodetik sarera konektatzearen arazoa aztertu gabe geratu zen. Bakarrik esango dut gailu mugikor baten OStik gordetako pasahitzak irakurtzeko, root eskubideak eta wpa_supplicant.conf irakurtzeko fitxategi-sisteman arakatzeko borondatea behar dituzula. Aplikazioaren logikak kanpotik pasahitz bat sartzea eskatzen badu, konexioa klasearen bidez egin daiteke
Eskerrik asko
Zerbait gehitu edo zuzendu behar dela uste baduzu, idatzi iruzkinetan :)
Iturria: www.habr.com