Wi-Fi اور بہت سے دوسرے مخففات۔ اینڈرائیڈ ایپلیکیشن میں وائی فائی نوڈس کے بارے میں ڈیٹا سوجائے بغیر کیسے حاصل کیا جائے۔

ایک دن مجھے اینڈرائیڈ ایپلی کیشنز سے وائی فائی نیٹ ورکس کو اسکین کرنے اور رسائی پوائنٹس کے بارے میں تفصیلی ڈیٹا حاصل کرنے کی ضرورت تھی۔

یہاں ہمیں کئی مشکلات کا سامنا کرنا پڑا: بند۔ اینڈرائیڈ دستاویزات بیان کردہ بہت سی کلاسیں فرسودہ ہو گئیں (API لیول > 26)، جو اس میں ظاہر نہیں ہوئی تھی۔ دستاویزات میں کچھ چیزوں کی تفصیل کم سے کم ہے (مثال کے طور پر، کلاس کی صلاحیتوں کا میدان اسکین نتیجہ لکھنے کے وقت، تقریباً کچھ بھی بیان نہیں کیا جاتا، حالانکہ اس میں بہت سارے اہم ڈیٹا ہوتے ہیں)۔ تیسری مشکل اس حقیقت میں پڑ سکتی ہے کہ جب آپ پہلی بار وائی فائی کے قریب پہنچتے ہیں، تھیوری کو پڑھنے اور لوکل ہوسٹ کے ذریعے راؤٹر کو ترتیب دینے کے علاوہ، آپ کو متعدد مخففات سے نمٹنا پڑتا ہے جو انفرادی طور پر قابل فہم لگتے ہیں۔ لیکن یہ واضح نہیں ہوسکتا ہے کہ ان سے کس طرح تعلق اور تشکیل کیا جائے (فیصلہ ساپیکش ہے اور پچھلے تجربے پر منحصر ہے)۔

یہ مضمون بحث کرتا ہے کہ این ڈی کے، ہیکس کے بغیر اینڈرائیڈ کوڈ سے وائی فائی ماحول کے بارے میں جامع ڈیٹا کیسے حاصل کیا جائے، لیکن صرف اینڈرائیڈ API کا استعمال کیا جائے اور اس کی تشریح کیسے کی جائے۔

آئیے تاخیر نہ کریں اور کوڈ لکھنا شروع کریں۔

1. ایک پروجیکٹ بنائیں

یہ نوٹ ان لوگوں کے لیے ہے جنہوں نے ایک سے زیادہ بار اینڈرائیڈ پروجیکٹ بنایا ہے، اس لیے ہم اس آئٹم کی تفصیلات کو چھوڑ دیتے ہیں۔ ذیل کا کوڈ کوٹلن، minSdkVersion=23 میں پیش کیا جائے گا۔

2. رسائی کی اجازت

ایپلی کیشن سے وائی فائی کے ساتھ کام کرنے کے لیے، آپ کو صارف سے متعدد اجازتیں حاصل کرنے کی ضرورت ہوگی۔ بمطابق دستاویزات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 سے فرسودہ کے طور پر نشان زد کیا گیا ہے، لیکن بند ہے۔ رہنمائی اسے استعمال کرنے کی تجویز کرتا ہے۔

مجموعی طور پر، ہمیں اشیاء کی ایک فہرست موصول ہوئی ہے۔ اسکین نتیجہ.

4. ScanResult دیکھیں اور شرائط کو سمجھیں۔

آئیے اس کلاس کے کچھ شعبوں کو دیکھیں اور بیان کریں کہ ان کا کیا مطلب ہے:

SSID - سروس سیٹ شناخت کنندہ نیٹ ورک کا نام ہے۔

بی ایس ایس آئی ڈی - بنیادی سروس سیٹ شناخت کنندہ - نیٹ ورک اڈاپٹر کا میک ایڈریس (وائی فائی پوائنٹ)

سطح — موصول ہونے والے سگنل کی طاقت کا اشارہ [dBm (Russian dBm) — ڈیسیبل، ریفرنس پاور 1 میگاواٹ۔] — موصول ہونے والے سگنل کی طاقت کا اشارہ۔ 0 سے -100 تک کی قدر لیتا ہے، 0 سے جتنا آگے، Wi-Fi پوائنٹ سے آپ کے آلے کے راستے میں سگنل کی طاقت اتنی ہی ختم ہو جاتی ہے۔ مزید تفصیلات مل سکتی ہیں، مثال کے طور پر، پر وکیپیڈیا. یہاں میں آپ کو بتاؤں گا کہ اینڈرائیڈ کلاس کا استعمال کرتے ہوئے۔ وائی ​​فائی مینجر آپ اپنے منتخب کردہ قدم میں بہترین سے خوفناک تک کے پیمانے پر سگنل کی سطح کیلیبریٹ کر سکتے ہیں:

        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 گیگا ہرٹز کی فریکوئنسی والے پوائنٹس کے لیے فریکوئنسی ویلیو سے چینل نمبر کا حساب لگانے کی اجازت دیتا ہے:


    /* по частоте определяем номер канала */
    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 (سسکو سنٹرلائزڈ کی مینجمنٹ) کے ساتھ ایک آپشن ہو سکتا ہے، لیکن میں نے اسے کبھی نہیں دیکھا۔

ممکن ہے رسائی پوائنٹ کو میک ایڈریس کے ذریعے تصدیق کرنے کے لیے ترتیب دیا گیا ہو۔ یا، اگر رسائی پوائنٹ پرانے WEP الگورتھم کا استعمال کرتے ہوئے ڈیٹا فراہم کرتا ہے، تو اصل میں کوئی تصدیق نہیں ہوتی (یہاں خفیہ کلید انکرپشن کی ہے)۔ ہم اس طرح کے اختیارات کو دوسرے کے طور پر درجہ بندی کرتے ہیں۔
ایک ایسا طریقہ بھی ہے جو عوامی وائی فائی میں پوشیدہ کیپٹیو پورٹل ڈیٹیکشن کے ساتھ مقبول ہے - براؤزر کے ذریعے تصدیق کی درخواست۔ اس طرح کے رسائی پوائنٹس اسکینر کو کھلے کے طور پر ظاہر ہوتے ہیں (جو وہ جسمانی تعلق کے نقطہ نظر سے ہیں)۔ لہذا، ہم انہیں اوپن کے طور پر درجہ بندی کرتے ہیں۔

دوسری قدر کو بطور اشارہ کیا جاسکتا ہے۔ کلیدی انتظام الگورتھم. یہ اوپر بیان کردہ تصدیق کے طریقہ کار کا ایک پیرامیٹر ہے۔ بالکل اس بارے میں بات کرتا ہے کہ کس طرح انکرپشن کیز کا تبادلہ ہوتا ہے۔ آئیے ممکنہ اختیارات پر غور کریں۔ EAP - مذکور WPA-Enterprice میں استعمال کیا جاتا ہے، درج کردہ تصدیقی ڈیٹا کی تصدیق کے لیے ڈیٹا بیس کا استعمال کرتا ہے۔ SAE - اعلی درجے کی WPA3 میں استعمال کیا جاتا ہے، بروٹ فورس کے خلاف زیادہ مزاحم۔ PSK - سب سے عام آپشن میں پاس ورڈ درج کرنا اور اسے خفیہ کردہ شکل میں منتقل کرنا شامل ہے۔ IEEE8021X - ایک بین الاقوامی معیار کے مطابق (WPA فیملی کے تعاون سے اس سے مختلف)۔ OWE (موقع پرست وائرلیس انکرپشن) پوائنٹس کے لیے IEEE 802.11 اسٹینڈرڈ کی ایک توسیع ہے جسے ہم نے OPEN کے طور پر درجہ بندی کیا ہے۔ OWE کسی غیر محفوظ نیٹ ورک پر منتقل ہونے والے ڈیٹا کو انکرپٹ کرکے اس کی حفاظت کو یقینی بناتا ہے۔ ایک آپشن بھی ممکن ہے جب رسائی کی چابیاں نہ ہوں، آئیے اس آپشن کو NONE کہتے ہیں۔

تیسرا پیرامیٹر نام نہاد ہے۔ خفیہ کاری کی اسکیمیں - منتقل شدہ ڈیٹا کی حفاظت کے لیے سائفر کو کس طرح استعمال کیا جاتا ہے۔ آئیے اختیارات کی فہرست بنائیں۔ WEP - ایک RC4 سٹریم سائفر استعمال کرتا ہے، خفیہ کلید خفیہ کاری کی کلید ہے، جسے جدید خفیہ نگاری کی دنیا میں ناقابل قبول سمجھا جاتا ہے۔ TKIP - WPA میں استعمال کیا جاتا ہے، CKIP - WPA2 میں۔ TKIP+CKIP - پسماندہ مطابقت کے لیے WPA اور WPA2 کے قابل پوائنٹس میں بیان کیا جا سکتا ہے۔

تین عناصر کے بجائے، آپ کو تنہا WEP نشان مل سکتا ہے:

[WEP]

جیسا کہ ہم نے اوپر بات کی ہے، یہ کلیدوں کے استعمال کے لیے الگورتھم کی وضاحت نہ کرنے کے لیے کافی ہے، جو موجود نہیں ہے، اور انکرپشن کا طریقہ، جو پہلے سے ایک جیسا ہے۔

اب اس بریکٹ پر غور کریں:

[ESS]

یہ وائی ​​فائی آپریٹنگ موڈ یا وائی ​​فائی نیٹ ورک ٹوپولوجی. آپ کو BSS (بنیادی سروس سیٹ) موڈ کا سامنا ہو سکتا ہے - جب ایک رسائی پوائنٹ ہو جس کے ذریعے منسلک آلات بات چیت کرتے ہیں۔ مقامی نیٹ ورکس پر پایا جا سکتا ہے۔ ایک اصول کے طور پر، مختلف مقامی نیٹ ورکس سے آلات کو جوڑنے کے لیے رسائی پوائنٹس کی ضرورت ہوتی ہے، اس لیے وہ توسیعی سروس سیٹس - ESS کا حصہ ہیں۔ IBSSs (آزاد بنیادی سروس سیٹس) کی قسم اس بات کی نشاندہی کرتی ہے کہ آلہ ایک پیر ٹو پیر نیٹ ورک کا حصہ ہے۔

آپ WPS پرچم بھی دیکھ سکتے ہیں:

[WPS]

ڈبلیو پی ایس (وائی فائی پروٹیکٹڈ سیٹ اپ) وائی فائی نیٹ ورک کے نیم خودکار آغاز کے لیے ایک پروٹوکول ہے۔ شروع کرنے کے لیے، صارف یا تو 8-حروف کا پاس ورڈ داخل کرتا ہے یا روٹر پر ایک بٹن دباتا ہے۔ اگر آپ کا ایکسیس پوائنٹ پہلی قسم کا ہے اور یہ چیک باکس آپ کے ایکسیس پوائنٹ کے نام کے ساتھ ظاہر ہوتا ہے، تو آپ کو ایڈمن پینل پر جانے اور WPS رسائی کو غیر فعال کرنے کا مشورہ دیا جاتا ہے۔ حقیقت یہ ہے کہ اکثر MAC ایڈریس کے ذریعے 8 ہندسوں کا PIN معلوم کیا جا سکتا ہے، یا اسے قریب ترین وقت میں ترتیب دیا جا سکتا ہے، جس سے کوئی بے ایمانی سے فائدہ اٹھا سکتا ہے۔

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

نیا تبصرہ شامل کریں