From dcae780f6dafe328e990d379b078f507b4abd0c8 Mon Sep 17 00:00:00 2001 From: region999 Date: Wed, 25 Jun 2025 13:57:41 +0000 Subject: [PATCH 01/17] Start draft PR From 21541a17a7ae0953da1b4b8717c06de296d94b33 Mon Sep 17 00:00:00 2001 From: region999 Date: Wed, 25 Jun 2025 13:57:57 +0000 Subject: [PATCH 02/17] Add .gitignore for Android project --- .gitignore | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..337f7d1 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Android Studio +*.iml +.gradle/ +build/ +.idea/ +local.properties + +# Kotlin/Java compiled files +*.class +*.dex + +# Dependency directories +/node_modules +/app/build + +# Logging files +*.log + +# Sensitive information +.env + +# OS generated files +.DS_Store +Thumbs.db \ No newline at end of file From 0c3ab9c607919ed5029ae5dfd8aa1cd2b65db458 Mon Sep 17 00:00:00 2001 From: region999 Date: Wed, 25 Jun 2025 13:58:12 +0000 Subject: [PATCH 03/17] Implement SecurityTypeDetector with robust error handling for WiFi network security types --- .../network/SecurityTypeDetector.kt | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/main/kotlin/com/wifiscanner/network/SecurityTypeDetector.kt diff --git a/src/main/kotlin/com/wifiscanner/network/SecurityTypeDetector.kt b/src/main/kotlin/com/wifiscanner/network/SecurityTypeDetector.kt new file mode 100644 index 0000000..be183b1 --- /dev/null +++ b/src/main/kotlin/com/wifiscanner/network/SecurityTypeDetector.kt @@ -0,0 +1,72 @@ +package com.wifiscanner.network + +import android.net.wifi.ScanResult +import android.util.Log + +/** + * Enum representing WiFi security types with error handling capabilities + */ +enum class SecurityType { + OPEN, + WEP, + WPA, + WPA2, + WPA3, + UNKNOWN +} + +/** + * Handles detection of WiFi network security types with robust error management + */ +class SecurityTypeDetector { + companion private const val TAG = "SecurityTypeDetector" + + /** + * Detect security type of a WiFi network with comprehensive error handling + * @param scanResult The WiFi scan result to analyze + * @return Detected security type, defaults to UNKNOWN if detection fails + */ + fun detectSecurityType(scanResult: ScanResult?): SecurityType { + // Handle null input gracefully + if (scanResult == null) { + Log.w(TAG, "Null ScanResult provided. Returning UNKNOWN security type.") + return SecurityType.UNKNOWN + } + + return try { + when { + // Check for specific security capabilities + scanResult.capabilities.contains("WPA3", ignoreCase = true) -> SecurityType.WPA3 + scanResult.capabilities.contains("WPA2", ignoreCase = true) -> SecurityType.WPA2 + scanResult.capabilities.contains("WPA", ignoreCase = true) -> SecurityType.WPA + scanResult.capabilities.contains("WEP", ignoreCase = true) -> SecurityType.WEP + scanResult.capabilities.isEmpty() -> SecurityType.OPEN + else -> { + // Log non-standard or unrecognized security type + Log.i(TAG, "Unrecognized security type: ${scanResult.capabilities}") + SecurityType.UNKNOWN + } + } + } catch (e: Exception) { + // Catch and log any unexpected errors during security type detection + Log.e(TAG, "Error detecting security type: ${e.message}", e) + SecurityType.UNKNOWN + } + } + + /** + * Provides a human-readable description of the security type + * @param securityType The security type to describe + * @return A descriptive string of the security type + */ + fun getSecurityDescription(securityType: SecurityType): String { + return when (securityType) { + SecurityType.OPEN -> "Open Network (No Security)" + SecurityType.WEP -> "WEP Protected Network" + SecurityType.WPA -> "WPA Protected Network" + SecurityType.WPA2 -> "WPA2 Protected Network" + SecurityType.WPA3 -> "WPA3 Protected Network" + SecurityType.UNKNOWN -> "Unknown Security Type" + } + } +} \ No newline at end of file From dc8524ecf7d84d9ac70fb94ad06ffc1a6719de9f Mon Sep 17 00:00:00 2001 From: region999 Date: Wed, 25 Jun 2025 13:58:27 +0000 Subject: [PATCH 04/17] Add comprehensive unit tests for SecurityTypeDetector --- .../network/SecurityTypeDetectorTest.kt | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 src/test/kotlin/com/wifiscanner/network/SecurityTypeDetectorTest.kt diff --git a/src/test/kotlin/com/wifiscanner/network/SecurityTypeDetectorTest.kt b/src/test/kotlin/com/wifiscanner/network/SecurityTypeDetectorTest.kt new file mode 100644 index 0000000..6387e00 --- /dev/null +++ b/src/test/kotlin/com/wifiscanner/network/SecurityTypeDetectorTest.kt @@ -0,0 +1,75 @@ +package com.wifiscanner.network + +import android.net.wifi.ScanResult +import org.junit.Assert.* +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class SecurityTypeDetectorTest { + + private val detector = SecurityTypeDetector() + + @Test + fun `test null scan result returns UNKNOWN`() { + val result = detector.detectSecurityType(null) + assertEquals(SecurityType.UNKNOWN, result) + } + + @Test + fun `test open network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.OPEN, result) + } + + @Test + fun `test WPA3 network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("[WPA3-PSK-CCMP]") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.WPA3, result) + } + + @Test + fun `test WPA2 network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("[WPA2-PSK-CCMP]") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.WPA2, result) + } + + @Test + fun `test WPA network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("[WPA-PSK-CCMP]") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.WPA, result) + } + + @Test + fun `test WEP network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("[WEP]") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.WEP, result) + } + + @Test + fun `test security description mapping`() { + assertEquals("Open Network (No Security)", detector.getSecurityDescription(SecurityType.OPEN)) + assertEquals("WEP Protected Network", detector.getSecurityDescription(SecurityType.WEP)) + assertEquals("WPA Protected Network", detector.getSecurityDescription(SecurityType.WPA)) + assertEquals("WPA2 Protected Network", detector.getSecurityDescription(SecurityType.WPA2)) + assertEquals("WPA3 Protected Network", detector.getSecurityDescription(SecurityType.WPA3)) + assertEquals("Unknown Security Type", detector.getSecurityDescription(SecurityType.UNKNOWN)) + } +} \ No newline at end of file From 9e92b49ec66830d2d65d1b979f93deefce2790c5 Mon Sep 17 00:00:00 2001 From: mexemexe Date: Wed, 25 Jun 2025 14:07:43 +0000 Subject: [PATCH 05/17] Start draft PR From 307e5073db5aba3cb3cdcf5571913ae3d4a5ef6f Mon Sep 17 00:00:00 2001 From: mexemexe Date: Wed, 25 Jun 2025 14:08:01 +0000 Subject: [PATCH 06/17] Add comprehensive .gitignore for Android project --- .gitignore | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..2c1fe7d --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +# Android Studio +.idea/ +*.iml +.gradle/ +build/ +captures/ + +# OS generated files +.DS_Store +Thumbs.db + +# Kotlin/Android specific +*.class +*.log +*.apk +*.aar +*.dex +*.module + +# Dependency directories +/node_modules +/jspm_packages + +# Gradle +gradle/ +gradlew +gradlew.bat + +# Local configuration file +local.properties + +# Log files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +/captures + +# Intellij +*.ipr +*.iws + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Keystore files +*.jks +*.keystore + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +lint/reports/ \ No newline at end of file From 675537bf90b945af55bac043c572dc12431d7a02 Mon Sep 17 00:00:00 2001 From: mexemexe Date: Wed, 25 Jun 2025 14:08:10 +0000 Subject: [PATCH 07/17] Create WiFiSecurityType data class for network security representation --- .../kotlin/com/wifiscanner/models/WiFiSecurity.kt | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt diff --git a/src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt b/src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt new file mode 100644 index 0000000..7c39864 --- /dev/null +++ b/src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt @@ -0,0 +1,14 @@ +package com.wifiscanner.models + +/** + * Represents the security type of a WiFi network. + * + * @property type The human-readable security type + * @property description A detailed description of the security type + * @property level A numeric representation of security strength (higher is more secure) + */ +data class WiFiSecurityType( + val type: String, + val description: String, + val level: Int +) \ No newline at end of file From 1c0b9bf7e54503e52fb415fee27b5751bbf9d14b Mon Sep 17 00:00:00 2001 From: mexemexe Date: Wed, 25 Jun 2025 14:08:24 +0000 Subject: [PATCH 08/17] Create WiFiSecurityMapper for mapping network capabilities to security types --- .../wifiscanner/utils/WiFiSecurityMapper.kt | 72 +++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt diff --git a/src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt b/src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt new file mode 100644 index 0000000..d9a08a7 --- /dev/null +++ b/src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt @@ -0,0 +1,72 @@ +package com.wifiscanner.utils + +import com.wifiscanner.models.WiFiSecurityType + +/** + * Utility class for mapping WiFi network capabilities to security types. + */ +object WiFiSecurityMapper { + /** + * Maps raw network capabilities to a WiFiSecurityType. + * + * @param capabilities Raw network capabilities string + * @return WiFiSecurityType representing the network's security + */ + fun mapSecurityType(capabilities: String?): WiFiSecurityType { + return when { + capabilities.isNullOrBlank() -> WiFiSecurityType( + "Unknown", + "Unable to determine network security", + 0 + ) + capabilities.contains("WPA3", ignoreCase = true) -> WiFiSecurityType( + "WPA3", + "Most advanced WiFi security protocol", + 5 + ) + capabilities.contains("WPA2", ignoreCase = true) -> WiFiSecurityType( + "WPA2", + "Strong encryption with improved security over WPA", + 4 + ) + capabilities.contains("WPA", ignoreCase = true) -> WiFiSecurityType( + "WPA", + "Older security protocol with moderate protection", + 3 + ) + capabilities.contains("WEP", ignoreCase = true) -> WiFiSecurityType( + "WEP", + "Weak and outdated security protocol", + 1 + ) + capabilities.contains("Open", ignoreCase = true) -> WiFiSecurityType( + "Open", + "No encryption, completely unsecured network", + 0 + ) + else -> WiFiSecurityType( + "Other", + "Unrecognized security type", + 2 + ) + } + } + + /** + * Generates a color based on the security level. + * + * @param securityType WiFiSecurityType to determine color for + * @return Color resource ID representing security level + */ + fun getSecurityColor(securityType: WiFiSecurityType): Int { + return when (securityType.level) { + 0 -> android.R.color.holo_red_dark // Open/No Security + 1 -> android.R.color.holo_red_light // Very Weak + 2 -> android.R.color.holo_orange_dark // Weak + 3 -> android.R.color.holo_orange_light // Moderate + 4 -> android.R.color.holo_green_light // Strong + 5 -> android.R.color.holo_green_dark // Most Secure + else -> android.R.color.darker_gray // Unknown + } + } +} \ No newline at end of file From f8c4e58d35293b54e3d62940e6aec45c9a2a005b Mon Sep 17 00:00:00 2001 From: mexemexe Date: Wed, 25 Jun 2025 14:08:39 +0000 Subject: [PATCH 09/17] Add comprehensive tests for WiFiSecurityMapper --- .../utils/WiFiSecurityMapperTest.kt | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt diff --git a/src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt b/src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt new file mode 100644 index 0000000..bff3f64 --- /dev/null +++ b/src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt @@ -0,0 +1,57 @@ +package com.wifiscanner.utils + +import com.wifiscanner.models.WiFiSecurityType +import org.junit.Assert.* +import org.junit.Test + +class WiFiSecurityMapperTest { + + @Test + fun `mapSecurityType should return WPA3 for WPA3 capabilities`() { + val capabilities = "[WPA3-PSK-CCMP]" + val result = WiFiSecurityMapper.mapSecurityType(capabilities) + + assertEquals("WPA3", result.type) + assertEquals("Most advanced WiFi security protocol", result.description) + assertEquals(5, result.level) + } + + @Test + fun `mapSecurityType should return WPA2 for WPA2 capabilities`() { + val capabilities = "[WPA2-PSK-CCMP]" + val result = WiFiSecurityMapper.mapSecurityType(capabilities) + + assertEquals("WPA2", result.type) + assertEquals("Strong encryption with improved security over WPA", result.description) + assertEquals(4, result.level) + } + + @Test + fun `mapSecurityType should return Open for open network`() { + val capabilities = "" + val result = WiFiSecurityMapper.mapSecurityType(capabilities) + + assertEquals("Open", result.type) + assertEquals("No encryption, completely unsecured network", result.description) + assertEquals(0, result.level) + } + + @Test + fun `mapSecurityType should return Unknown for null capabilities`() { + val capabilities = null + val result = WiFiSecurityMapper.mapSecurityType(capabilities) + + assertEquals("Unknown", result.type) + assertEquals("Unable to determine network security", result.description) + assertEquals(0, result.level) + } + + @Test + fun `getSecurityColor returns correct color for different security levels`() { + val openSecurity = WiFiSecurityType("Open", "Unsecured", 0) + val wpa3Security = WiFiSecurityType("WPA3", "Secure", 5) + + assertEquals(android.R.color.holo_red_dark, WiFiSecurityMapper.getSecurityColor(openSecurity)) + assertEquals(android.R.color.holo_green_dark, WiFiSecurityMapper.getSecurityColor(wpa3Security)) + } +} \ No newline at end of file From 620c4bc9b2f94415ff61c8d871423c684b4ac154 Mon Sep 17 00:00:00 2001 From: mexemexe Date: Wed, 25 Jun 2025 14:08:54 +0000 Subject: [PATCH 10/17] Configure project build.gradle with dependencies --- app/build.gradle | 43 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 app/build.gradle diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..3b23d6d --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,43 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdkVersion 30 + defaultConfig { + applicationId "com.wifiscanner" + minSdkVersion 29 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.21" + implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + + // Testing dependencies + testImplementation 'junit:junit:4.13.2' + testImplementation 'org.mockito:mockito-core:3.11.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file From 15266f776fe27b5e9b06fc9bc78ea98ede79497f Mon Sep 17 00:00:00 2001 From: revonetworx Date: Wed, 25 Jun 2025 14:09:41 +0000 Subject: [PATCH 11/17] Create build.gradle configuration for Android/Kotlin project --- build.gradle.kts | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 build.gradle.kts diff --git a/build.gradle.kts b/build.gradle.kts new file mode 100644 index 0000000..055ff78 --- /dev/null +++ b/build.gradle.kts @@ -0,0 +1,28 @@ +plugins { + kotlin("jvm") version "1.9.0" + id("org.jetbrains.kotlin.plugin.serialization") version "1.9.0" +} + +repositories { + mavenCentral() + google() +} + +dependencies { + // Kotlin standard library + implementation("org.jetbrains.kotlin:kotlin-stdlib:1.9.0") + + // Android dependencies + implementation("androidx.core:core-ktx:1.10.1") + implementation("androidx.appcompat:appcompat:1.6.1") + + // Testing dependencies + testImplementation("junit:junit:4.13.2") + testImplementation("org.robolectric:robolectric:4.10.3") + testImplementation("org.mockito:mockito-core:4.11.0") + testImplementation("org.jetbrains.kotlin:kotlin-test:1.9.0") +} + +tasks.test { + useJUnit() +} \ No newline at end of file From 22e45cacb4d8f624408ec93f3f146bacca220be0 Mon Sep 17 00:00:00 2001 From: revonetworx Date: Wed, 25 Jun 2025 14:10:07 +0000 Subject: [PATCH 12/17] Start draft PR From b30d08e48661f91435c779d022c69b2118d5f1df Mon Sep 17 00:00:00 2001 From: SoYan500 Date: Sat, 5 Jul 2025 10:12:13 +0000 Subject: [PATCH 13/17] Add .gitignore for Python project --- .gitignore | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2af16a --- /dev/null +++ b/.gitignore @@ -0,0 +1,12 @@ +__pycache__/ +*.py[cod] +*$py.class +.pytest_cache/ +.coverage +htmlcov/ +dist/ +build/ +*.egg-info/ +.env +.venv/ +venv/ \ No newline at end of file From 266939a939ecf30a3424f7893f75e902f95df81d Mon Sep 17 00:00:00 2001 From: SoYan500 Date: Sat, 5 Jul 2025 10:12:26 +0000 Subject: [PATCH 14/17] Start draft PR From b447a4883d598d9b030b687bc6a5b69285158efb Mon Sep 17 00:00:00 2001 From: SoYan500 Date: Sat, 5 Jul 2025 10:12:39 +0000 Subject: [PATCH 15/17] Implement IterationTracker with comprehensive iteration management --- .gitignore | 29 ++- src/iteration_tracker.py | 173 ++++++++++++++++++ .../network/SecurityTypeDetector.kt | 72 ++++++++ .../network/SecurityTypeDetectorTest.kt | 75 ++++++++ 4 files changed, 348 insertions(+), 1 deletion(-) create mode 100644 src/iteration_tracker.py create mode 100644 src/main/kotlin/com/wifiscanner/network/SecurityTypeDetector.kt create mode 100644 src/test/kotlin/com/wifiscanner/network/SecurityTypeDetectorTest.kt diff --git a/.gitignore b/.gitignore index c2af16a..9281142 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +<<<<<<< HEAD __pycache__/ *.py[cod] *$py.class @@ -9,4 +10,30 @@ build/ *.egg-info/ .env .venv/ -venv/ \ No newline at end of file +venv/ +======= +# Android Studio +*.iml +.gradle/ +build/ +.idea/ +local.properties + +# Kotlin/Java compiled files +*.class +*.dex + +# Dependency directories +/node_modules +/app/build + +# Logging files +*.log + +# Sensitive information +.env + +# OS generated files +.DS_Store +Thumbs.db +>>>>>>> pr-1-souravg77-scanmywifi diff --git a/src/iteration_tracker.py b/src/iteration_tracker.py new file mode 100644 index 0000000..10f8000 --- /dev/null +++ b/src/iteration_tracker.py @@ -0,0 +1,173 @@ +from __future__ import annotations +from typing import Optional, Dict, Any +from dataclasses import dataclass, field +from enum import Enum, auto +import logging + +class IterationStatus(Enum): + """Enum representing the status of an iteration.""" + INITIALIZED = auto() + IN_PROGRESS = auto() + COMPLETED = auto() + FAILED = auto() + TERMINATED = auto() + +@dataclass +class IterationState: + """Tracks the state and metadata of learning iterations.""" + current_iteration: int = 0 + max_iterations: Optional[int] = None + status: IterationStatus = IterationStatus.INITIALIZED + metadata: Dict[str, Any] = field(default_factory=dict) + + def increment(self) -> None: + """ + Increment the iteration count and update status. + + Raises: + StopIteration: If maximum iterations are reached. + """ + self.current_iteration += 1 + + if self.max_iterations is not None and self.current_iteration >= self.max_iterations: + self.status = IterationStatus.COMPLETED + raise StopIteration("Maximum iterations reached") + + self.status = IterationStatus.IN_PROGRESS + + def reset(self) -> None: + """Reset the iteration state to initial conditions.""" + self.current_iteration = 0 + self.status = IterationStatus.INITIALIZED + self.metadata.clear() + + def set_status(self, status: IterationStatus) -> None: + """ + Set the current iteration status. + + Args: + status (IterationStatus): New status to set + """ + self.status = status + + def add_metadata(self, key: str, value: Any) -> None: + """ + Add metadata to the current iteration. + + Args: + key (str): Metadata key + value (Any): Metadata value + """ + self.metadata[key] = value + + @property + def is_complete(self) -> bool: + """ + Check if iteration is complete. + + Returns: + bool: True if iteration is completed, False otherwise + """ + return self.status in {IterationStatus.COMPLETED, IterationStatus.TERMINATED, IterationStatus.FAILED} + +class IterationTracker: + """ + Manages the iteration tracking process for the Adaptive Learning Process. + + Provides comprehensive tracking of iterations with configurable maximum + iterations and detailed state management. + """ + + def __init__(self, max_iterations: Optional[int] = None, logger: Optional[logging.Logger] = None): + """ + Initialize the iteration tracker. + + Args: + max_iterations (Optional[int], optional): Maximum number of iterations. Defaults to None. + logger (Optional[logging.Logger], optional): Logger instance. Defaults to None. + """ + self._state = IterationState(max_iterations=max_iterations) + self._logger = logger or logging.getLogger(__name__) + + def start(self) -> None: + """Start the iteration tracking process.""" + self._state.reset() + self._logger.info("Iteration tracking started") + + def next_iteration(self) -> int: + """ + Move to the next iteration. + + Returns: + int: Current iteration number + + Raises: + StopIteration: If maximum iterations are reached + """ + try: + self._state.increment() + self._logger.info(f"Starting iteration {self._state.current_iteration}") + return self._state.current_iteration + except StopIteration: + self._logger.info("Maximum iterations reached") + raise + + def mark_iteration_complete(self, metadata: Optional[Dict[str, Any]] = None) -> None: + """ + Mark the current iteration as complete. + + Args: + metadata (Optional[Dict[str, Any]], optional): Additional metadata about the iteration. Defaults to None. + """ + if metadata: + for key, value in metadata.items(): + self._state.add_metadata(key, value) + + self._state.set_status(IterationStatus.COMPLETED) + self._logger.info(f"Iteration {self._state.current_iteration} completed") + + def mark_iteration_failed(self, error: Optional[Exception] = None) -> None: + """ + Mark the current iteration as failed. + + Args: + error (Optional[Exception], optional): Error that caused the failure. Defaults to None. + """ + self._state.set_status(IterationStatus.FAILED) + + if error: + self._logger.error(f"Iteration {self._state.current_iteration} failed: {error}") + self._state.add_metadata('error', str(error)) + + def terminate(self, reason: Optional[str] = None) -> None: + """ + Terminate the iteration process. + + Args: + reason (Optional[str], optional): Reason for termination. Defaults to None. + """ + self._state.set_status(IterationStatus.TERMINATED) + + if reason: + self._logger.warning(f"Iteration process terminated: {reason}") + self._state.add_metadata('termination_reason', reason) + + @property + def current_iteration(self) -> int: + """ + Get the current iteration number. + + Returns: + int: Current iteration number + """ + return self._state.current_iteration + + @property + def is_complete(self) -> bool: + """ + Check if iteration process is complete. + + Returns: + bool: True if iterations are complete, False otherwise + """ + return self._state.is_complete \ No newline at end of file diff --git a/src/main/kotlin/com/wifiscanner/network/SecurityTypeDetector.kt b/src/main/kotlin/com/wifiscanner/network/SecurityTypeDetector.kt new file mode 100644 index 0000000..be183b1 --- /dev/null +++ b/src/main/kotlin/com/wifiscanner/network/SecurityTypeDetector.kt @@ -0,0 +1,72 @@ +package com.wifiscanner.network + +import android.net.wifi.ScanResult +import android.util.Log + +/** + * Enum representing WiFi security types with error handling capabilities + */ +enum class SecurityType { + OPEN, + WEP, + WPA, + WPA2, + WPA3, + UNKNOWN +} + +/** + * Handles detection of WiFi network security types with robust error management + */ +class SecurityTypeDetector { + companion private const val TAG = "SecurityTypeDetector" + + /** + * Detect security type of a WiFi network with comprehensive error handling + * @param scanResult The WiFi scan result to analyze + * @return Detected security type, defaults to UNKNOWN if detection fails + */ + fun detectSecurityType(scanResult: ScanResult?): SecurityType { + // Handle null input gracefully + if (scanResult == null) { + Log.w(TAG, "Null ScanResult provided. Returning UNKNOWN security type.") + return SecurityType.UNKNOWN + } + + return try { + when { + // Check for specific security capabilities + scanResult.capabilities.contains("WPA3", ignoreCase = true) -> SecurityType.WPA3 + scanResult.capabilities.contains("WPA2", ignoreCase = true) -> SecurityType.WPA2 + scanResult.capabilities.contains("WPA", ignoreCase = true) -> SecurityType.WPA + scanResult.capabilities.contains("WEP", ignoreCase = true) -> SecurityType.WEP + scanResult.capabilities.isEmpty() -> SecurityType.OPEN + else -> { + // Log non-standard or unrecognized security type + Log.i(TAG, "Unrecognized security type: ${scanResult.capabilities}") + SecurityType.UNKNOWN + } + } + } catch (e: Exception) { + // Catch and log any unexpected errors during security type detection + Log.e(TAG, "Error detecting security type: ${e.message}", e) + SecurityType.UNKNOWN + } + } + + /** + * Provides a human-readable description of the security type + * @param securityType The security type to describe + * @return A descriptive string of the security type + */ + fun getSecurityDescription(securityType: SecurityType): String { + return when (securityType) { + SecurityType.OPEN -> "Open Network (No Security)" + SecurityType.WEP -> "WEP Protected Network" + SecurityType.WPA -> "WPA Protected Network" + SecurityType.WPA2 -> "WPA2 Protected Network" + SecurityType.WPA3 -> "WPA3 Protected Network" + SecurityType.UNKNOWN -> "Unknown Security Type" + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/wifiscanner/network/SecurityTypeDetectorTest.kt b/src/test/kotlin/com/wifiscanner/network/SecurityTypeDetectorTest.kt new file mode 100644 index 0000000..6387e00 --- /dev/null +++ b/src/test/kotlin/com/wifiscanner/network/SecurityTypeDetectorTest.kt @@ -0,0 +1,75 @@ +package com.wifiscanner.network + +import android.net.wifi.ScanResult +import org.junit.Assert.* +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mockito +import org.mockito.junit.MockitoJUnitRunner + +@RunWith(MockitoJUnitRunner::class) +class SecurityTypeDetectorTest { + + private val detector = SecurityTypeDetector() + + @Test + fun `test null scan result returns UNKNOWN`() { + val result = detector.detectSecurityType(null) + assertEquals(SecurityType.UNKNOWN, result) + } + + @Test + fun `test open network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.OPEN, result) + } + + @Test + fun `test WPA3 network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("[WPA3-PSK-CCMP]") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.WPA3, result) + } + + @Test + fun `test WPA2 network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("[WPA2-PSK-CCMP]") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.WPA2, result) + } + + @Test + fun `test WPA network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("[WPA-PSK-CCMP]") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.WPA, result) + } + + @Test + fun `test WEP network detection`() { + val mockScanResult = Mockito.mock(ScanResult::class.java) + Mockito.`when`(mockScanResult.capabilities).thenReturn("[WEP]") + + val result = detector.detectSecurityType(mockScanResult) + assertEquals(SecurityType.WEP, result) + } + + @Test + fun `test security description mapping`() { + assertEquals("Open Network (No Security)", detector.getSecurityDescription(SecurityType.OPEN)) + assertEquals("WEP Protected Network", detector.getSecurityDescription(SecurityType.WEP)) + assertEquals("WPA Protected Network", detector.getSecurityDescription(SecurityType.WPA)) + assertEquals("WPA2 Protected Network", detector.getSecurityDescription(SecurityType.WPA2)) + assertEquals("WPA3 Protected Network", detector.getSecurityDescription(SecurityType.WPA3)) + assertEquals("Unknown Security Type", detector.getSecurityDescription(SecurityType.UNKNOWN)) + } +} \ No newline at end of file From 59645575b429b8e7343b303f8a6d445db939f037 Mon Sep 17 00:00:00 2001 From: SoYan500 Date: Sat, 5 Jul 2025 10:12:48 +0000 Subject: [PATCH 16/17] Add tests for IterationTracker --- tests/test_iteration_tracker.py | 54 +++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 tests/test_iteration_tracker.py diff --git a/tests/test_iteration_tracker.py b/tests/test_iteration_tracker.py new file mode 100644 index 0000000..c32e1a1 --- /dev/null +++ b/tests/test_iteration_tracker.py @@ -0,0 +1,54 @@ +import pytest +import logging +from src.iteration_tracker import IterationTracker, IterationStatus + +def test_iteration_tracker_initialization(): + tracker = IterationTracker() + assert tracker.current_iteration == 0 + assert not tracker.is_complete + +def test_iteration_tracker_with_max_iterations(): + tracker = IterationTracker(max_iterations=3) + + tracker.start() + assert tracker.next_iteration() == 1 + assert tracker.next_iteration() == 2 + assert tracker.next_iteration() == 3 + + with pytest.raises(StopIteration): + tracker.next_iteration() + +def test_iteration_tracker_mark_complete(): + tracker = IterationTracker() + tracker.start() + + iteration = tracker.next_iteration() + tracker.mark_iteration_complete({'result': 'success'}) + + assert iteration == 1 + +def test_iteration_tracker_mark_failed(): + tracker = IterationTracker() + tracker.start() + + iteration = tracker.next_iteration() + tracker.mark_iteration_failed(ValueError("Test error")) + + assert iteration == 1 + +def test_iteration_tracker_terminate(): + tracker = IterationTracker() + tracker.start() + + tracker.terminate("Test termination") + assert tracker.is_complete + +def test_iteration_tracker_metadata(): + tracker = IterationTracker() + tracker.start() + + tracker.next_iteration() + tracker.mark_iteration_complete({'metric': 0.95, 'converged': True}) + + # Note: Actual metadata validation would require more complex mocking/inspection + assert tracker.current_iteration == 1 \ No newline at end of file From e057d490a9beb250dc0b8d80116fcd4e80b42e89 Mon Sep 17 00:00:00 2001 From: SoYan500 Date: Sat, 5 Jul 2025 10:13:15 +0000 Subject: [PATCH 17/17] Update max_iterations check to allow exact max number of iterations --- .gitignore | 63 ++++++++++++++++ app/build.gradle | 43 +++++++++++ src/iteration_tracker.py | 2 +- .../com/wifiscanner/models/WiFiSecurity.kt | 14 ++++ .../wifiscanner/utils/WiFiSecurityMapper.kt | 72 +++++++++++++++++++ .../utils/WiFiSecurityMapperTest.kt | 57 +++++++++++++++ 6 files changed, 250 insertions(+), 1 deletion(-) create mode 100644 app/build.gradle create mode 100644 src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt create mode 100644 src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt create mode 100644 src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt diff --git a/.gitignore b/.gitignore index 9281142..fdd46a6 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ <<<<<<< HEAD +<<<<<<< HEAD __pycache__/ *.py[cod] *$py.class @@ -32,8 +33,70 @@ local.properties # Sensitive information .env +======= +# Android Studio +.idea/ +*.iml +.gradle/ +build/ +captures/ +>>>>>>> pr-4-souravg77-scanmywifi # OS generated files .DS_Store Thumbs.db +<<<<<<< HEAD >>>>>>> pr-1-souravg77-scanmywifi +======= + +# Kotlin/Android specific +*.class +*.log +*.apk +*.aar +*.dex +*.module + +# Dependency directories +/node_modules +/jspm_packages + +# Gradle +gradle/ +gradlew +gradlew.bat + +# Local configuration file +local.properties + +# Log files +*.log + +# Android Studio Navigation editor temp files +.navigation/ + +# Android Studio captures folder +/captures + +# Intellij +*.ipr +*.iws + +# External native build folder generated in Android Studio 2.2 and later +.externalNativeBuild +.cxx/ + +# Keystore files +*.jks +*.keystore + +# Google Services (e.g. APIs or Firebase) +google-services.json + +# Lint +lint/intermediates/ +lint/generated/ +lint/outputs/ +lint/tmp/ +lint/reports/ +>>>>>>> pr-4-souravg77-scanmywifi diff --git a/app/build.gradle b/app/build.gradle new file mode 100644 index 0000000..3b23d6d --- /dev/null +++ b/app/build.gradle @@ -0,0 +1,43 @@ +plugins { + id 'com.android.application' + id 'kotlin-android' +} + +android { + compileSdkVersion 30 + defaultConfig { + applicationId "com.wifiscanner" + minSdkVersion 29 + targetSdkVersion 30 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + kotlinOptions { + jvmTarget = '1.8' + } +} + +dependencies { + implementation "org.jetbrains.kotlin:kotlin-stdlib:1.5.21" + implementation 'androidx.core:core-ktx:1.6.0' + implementation 'androidx.appcompat:appcompat:1.3.1' + implementation 'com.google.android.material:material:1.4.0' + + // Testing dependencies + testImplementation 'junit:junit:4.13.2' + testImplementation 'org.mockito:mockito-core:3.11.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/src/iteration_tracker.py b/src/iteration_tracker.py index 10f8000..56c18cf 100644 --- a/src/iteration_tracker.py +++ b/src/iteration_tracker.py @@ -29,7 +29,7 @@ def increment(self) -> None: """ self.current_iteration += 1 - if self.max_iterations is not None and self.current_iteration >= self.max_iterations: + if self.max_iterations is not None and self.current_iteration > self.max_iterations: self.status = IterationStatus.COMPLETED raise StopIteration("Maximum iterations reached") diff --git a/src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt b/src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt new file mode 100644 index 0000000..7c39864 --- /dev/null +++ b/src/main/kotlin/com/wifiscanner/models/WiFiSecurity.kt @@ -0,0 +1,14 @@ +package com.wifiscanner.models + +/** + * Represents the security type of a WiFi network. + * + * @property type The human-readable security type + * @property description A detailed description of the security type + * @property level A numeric representation of security strength (higher is more secure) + */ +data class WiFiSecurityType( + val type: String, + val description: String, + val level: Int +) \ No newline at end of file diff --git a/src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt b/src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt new file mode 100644 index 0000000..d9a08a7 --- /dev/null +++ b/src/main/kotlin/com/wifiscanner/utils/WiFiSecurityMapper.kt @@ -0,0 +1,72 @@ +package com.wifiscanner.utils + +import com.wifiscanner.models.WiFiSecurityType + +/** + * Utility class for mapping WiFi network capabilities to security types. + */ +object WiFiSecurityMapper { + /** + * Maps raw network capabilities to a WiFiSecurityType. + * + * @param capabilities Raw network capabilities string + * @return WiFiSecurityType representing the network's security + */ + fun mapSecurityType(capabilities: String?): WiFiSecurityType { + return when { + capabilities.isNullOrBlank() -> WiFiSecurityType( + "Unknown", + "Unable to determine network security", + 0 + ) + capabilities.contains("WPA3", ignoreCase = true) -> WiFiSecurityType( + "WPA3", + "Most advanced WiFi security protocol", + 5 + ) + capabilities.contains("WPA2", ignoreCase = true) -> WiFiSecurityType( + "WPA2", + "Strong encryption with improved security over WPA", + 4 + ) + capabilities.contains("WPA", ignoreCase = true) -> WiFiSecurityType( + "WPA", + "Older security protocol with moderate protection", + 3 + ) + capabilities.contains("WEP", ignoreCase = true) -> WiFiSecurityType( + "WEP", + "Weak and outdated security protocol", + 1 + ) + capabilities.contains("Open", ignoreCase = true) -> WiFiSecurityType( + "Open", + "No encryption, completely unsecured network", + 0 + ) + else -> WiFiSecurityType( + "Other", + "Unrecognized security type", + 2 + ) + } + } + + /** + * Generates a color based on the security level. + * + * @param securityType WiFiSecurityType to determine color for + * @return Color resource ID representing security level + */ + fun getSecurityColor(securityType: WiFiSecurityType): Int { + return when (securityType.level) { + 0 -> android.R.color.holo_red_dark // Open/No Security + 1 -> android.R.color.holo_red_light // Very Weak + 2 -> android.R.color.holo_orange_dark // Weak + 3 -> android.R.color.holo_orange_light // Moderate + 4 -> android.R.color.holo_green_light // Strong + 5 -> android.R.color.holo_green_dark // Most Secure + else -> android.R.color.darker_gray // Unknown + } + } +} \ No newline at end of file diff --git a/src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt b/src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt new file mode 100644 index 0000000..bff3f64 --- /dev/null +++ b/src/test/kotlin/com/wifiscanner/utils/WiFiSecurityMapperTest.kt @@ -0,0 +1,57 @@ +package com.wifiscanner.utils + +import com.wifiscanner.models.WiFiSecurityType +import org.junit.Assert.* +import org.junit.Test + +class WiFiSecurityMapperTest { + + @Test + fun `mapSecurityType should return WPA3 for WPA3 capabilities`() { + val capabilities = "[WPA3-PSK-CCMP]" + val result = WiFiSecurityMapper.mapSecurityType(capabilities) + + assertEquals("WPA3", result.type) + assertEquals("Most advanced WiFi security protocol", result.description) + assertEquals(5, result.level) + } + + @Test + fun `mapSecurityType should return WPA2 for WPA2 capabilities`() { + val capabilities = "[WPA2-PSK-CCMP]" + val result = WiFiSecurityMapper.mapSecurityType(capabilities) + + assertEquals("WPA2", result.type) + assertEquals("Strong encryption with improved security over WPA", result.description) + assertEquals(4, result.level) + } + + @Test + fun `mapSecurityType should return Open for open network`() { + val capabilities = "" + val result = WiFiSecurityMapper.mapSecurityType(capabilities) + + assertEquals("Open", result.type) + assertEquals("No encryption, completely unsecured network", result.description) + assertEquals(0, result.level) + } + + @Test + fun `mapSecurityType should return Unknown for null capabilities`() { + val capabilities = null + val result = WiFiSecurityMapper.mapSecurityType(capabilities) + + assertEquals("Unknown", result.type) + assertEquals("Unable to determine network security", result.description) + assertEquals(0, result.level) + } + + @Test + fun `getSecurityColor returns correct color for different security levels`() { + val openSecurity = WiFiSecurityType("Open", "Unsecured", 0) + val wpa3Security = WiFiSecurityType("WPA3", "Secure", 5) + + assertEquals(android.R.color.holo_red_dark, WiFiSecurityMapper.getSecurityColor(openSecurity)) + assertEquals(android.R.color.holo_green_dark, WiFiSecurityMapper.getSecurityColor(wpa3Security)) + } +} \ No newline at end of file