From b3b47d66706018b821d459cc700bb4abb5076b78 Mon Sep 17 00:00:00 2001 From: Mateo Gianolio Date: Tue, 23 Jan 2024 16:46:35 +0100 Subject: [PATCH] fix(#35): apply patch from issue to fix scanWifiList issue (#36) * fix(#35): apply patch from issue to fix scanWifiList issue * fix(ios): fix parameter name typo * fix(android,ios): more typo fixes * fix(android): add check if already connected * fix(android): cleanup unused params --- .../EspIdfProvisioningModule.kt | 128 ++++++------------ android/src/oldarch/EspIdfProvisioningSpec.kt | 2 +- ios/EspIdfProvisioning.mm | 2 +- ios/EspIdfProvisioning.swift | 8 +- src/NativeEspIdfProvisioning.ts | 2 +- src/index.tsx | 4 +- 6 files changed, 54 insertions(+), 92 deletions(-) diff --git a/android/src/main/java/com/espidfprovisioning/EspIdfProvisioningModule.kt b/android/src/main/java/com/espidfprovisioning/EspIdfProvisioningModule.kt index 50cf284..3db7966 100644 --- a/android/src/main/java/com/espidfprovisioning/EspIdfProvisioningModule.kt +++ b/android/src/main/java/com/espidfprovisioning/EspIdfProvisioningModule.kt @@ -30,6 +30,14 @@ import java.lang.Exception import java.util.ArrayList import java.util.Base64 +fun BluetoothDevice.isAlreadyConnected(): Boolean { + return try { + javaClass.getMethod("isConnected").invoke(this) as? Boolean? ?: false + } catch (e: Throwable) { + false + } +} + class EspIdfProvisioningModule internal constructor(context: ReactApplicationContext?) : EspIdfProvisioningSpec(context) { override fun getName(): String { return NAME @@ -45,33 +53,18 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon private fun hasBluetoothPermissions(): Boolean { if (Build.VERSION.SDK_INT <= 30) { - if ( - ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED && - ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED - ) { - return true - } else { - return false - } - } - else if ( - ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED && - ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED - ) { - return true + return ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.BLUETOOTH) == PackageManager.PERMISSION_GRANTED && + ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.BLUETOOTH_ADMIN) == PackageManager.PERMISSION_GRANTED } - return false + + return ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED && + ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED } private fun hasWifiPermission(): Boolean { - if ( - ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.CHANGE_WIFI_STATE) == PackageManager.PERMISSION_GRANTED && - ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.ACCESS_WIFI_STATE) == PackageManager.PERMISSION_GRANTED && - ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.ACCESS_NETWORK_STATE) == PackageManager.PERMISSION_GRANTED - ) { - return true - } - return false + return ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.CHANGE_WIFI_STATE) == PackageManager.PERMISSION_GRANTED && + ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.ACCESS_WIFI_STATE) == PackageManager.PERMISSION_GRANTED && + ContextCompat.checkSelfPermission(reactApplicationContext, Manifest.permission.ACCESS_NETWORK_STATE) == PackageManager.PERMISSION_GRANTED } private fun hasFineLocationPermission(): Boolean { @@ -82,10 +75,7 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon @ReactMethod override fun searchESPDevices(devicePrefix: String, transport: String, security: Int, promise: Promise?) { // Permission checks - if ( - hasBluetoothPermissions() == false || - hasFineLocationPermission() == false - ) { + if (!hasBluetoothPermissions() || !hasFineLocationPermission()) { promise?.reject(Error("Missing one of the following permissions: BLUETOOTH, BLUETOOTH_ADMIN, BLUETOOTH_CONNECT, BLUETOOTH_SCAN, ACCESS_FINE_LOCATION")) return } @@ -103,8 +93,6 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon } espDevices.clear() - - val invoked = false espProvisionManager.searchBleEspDevices(devicePrefix, object : BleScanListener { override fun scanStartFailed() { promise?.reject(Error("Scan could not be started.")) @@ -123,11 +111,7 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon return } - var serviceUuid: String? = null - if (scanResult.scanRecord?.serviceUuids != null && scanResult.scanRecord?.serviceUuids?.size!! > 0) { - serviceUuid = scanResult.scanRecord?.serviceUuids?.get(0).toString() - } - + val serviceUuid = scanResult.scanRecord?.serviceUuids?.getOrNull(0)?.toString() if (serviceUuid != null && !espDevices.containsKey(deviceName)) { val espDevice = ESPDevice(reactApplicationContext, transportEnum, securityEnum) espDevice.bluetoothDevice = device @@ -148,13 +132,8 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon espDevices.values.forEach { espDevice -> val resultMap = Arguments.createMap() resultMap.putString("name", espDevice.deviceName) - resultMap.putArray("capabilities", Arguments.fromList(espDevice.deviceCapabilities)) - resultMap.putInt("security", security) resultMap.putString("transport", transport) - resultMap.putString("username", espDevice.userName) - resultMap.putString("versionInfo", espDevice.versionInfo) - resultMap.putString("address", espDevice.bluetoothDevice.address) - resultMap.putString("primaryServiceUuid", espDevice.primaryServiceUuid) + resultMap.putInt("security", security) resultArray.pushMap(resultMap) } @@ -172,10 +151,7 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon @ReactMethod override fun stopESPDevicesSearch() { // Permission checks - if ( - hasBluetoothPermissions() == false || - hasFineLocationPermission() == false - ) { + if (!hasBluetoothPermissions() || !hasFineLocationPermission()) { // If we don't have permissions we are probably not scanning either, so just return return } @@ -195,7 +171,7 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon promise: Promise? ) { // Permission checks - if (hasBluetoothPermissions() == false) { + if (!hasBluetoothPermissions()) { promise?.reject(Error("Missing one of the following permissions: BLUETOOTH, BLUETOOTH_ADMIN, BLUETOOTH_CONNECT, BLUETOOTH_SCAN")) return } @@ -212,49 +188,32 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon else -> ESPConstants.SecurityType.SECURITY_2 } - if (espDevices[deviceName] != null) { - val result = Arguments.createMap() - result.putString("name", espDevices[deviceName]?.deviceName) - result.putArray("capabilities", Arguments.fromList(espDevices[deviceName]?.deviceCapabilities)) - result.putInt("security", security) - result.putString("transport", transport) - result.putString("username", espDevices[deviceName]?.userName) - result.putString("versionInfo", espDevices[deviceName]?.versionInfo) - - promise?.resolve(result) - return - } - // If no ESP device found in list (no scan has been performed), create a new one - val espDevice = espProvisionManager.createESPDevice(transportEnum, securityEnum) - var bleDevice = espDevice?.bluetoothDevice + var espDevice = espDevices[deviceName]; + if (espDevice == null) { + espDevice = espProvisionManager.createESPDevice(transportEnum, securityEnum) + espDevice.deviceName = deviceName + espDevices[deviceName] = espDevice + } - // If the bluetooth device does not contain service uuids, try using the bonded - // one (if it exists) - if (bleDevice?.uuids == null) { - bleDevice = bluetoothAdapter.bondedDevices.find { - bondedDevice -> bondedDevice.name == deviceName + // If the bluetooth device does not exist, try using the bonded one (if it exists) + if (espDevice?.bluetoothDevice == null) { + espDevice?.bluetoothDevice = bluetoothAdapter.bondedDevices.find { + bondedDevice -> bondedDevice.name == deviceName } } - // If the bluetooth device exists and contains service uuids, we will be able to connect to it - if (bleDevice?.uuids != null) { - espDevice.bluetoothDevice = bleDevice - espDevice.deviceName = deviceName + // If the bluetooth device exists and we have a primary service uuid, we will be able to connect to it + if (espDevice?.bluetoothDevice != null && espDevice.primaryServiceUuid != null) { espDevice.proofOfPossession = proofOfPossession if (username != null) { espDevice.userName = username } - espDevices[deviceName] = espDevice - val result = Arguments.createMap() result.putString("name", espDevice.deviceName) - result.putArray("capabilities", Arguments.fromList(espDevice.deviceCapabilities)) - result.putInt("security", security) result.putString("transport", transport) - result.putString("username", espDevice.userName) - result.putString("versionInfo", espDevice.versionInfo) + result.putInt("security", security) promise?.resolve(result) return @@ -276,11 +235,8 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon val result = Arguments.createMap() result.putString("name", espDevices[deviceName]?.deviceName) - result.putArray("capabilities", Arguments.fromList(espDevices[deviceName]?.deviceCapabilities)) - result.putInt("security", security) result.putString("transport", transport) - result.putString("username", espDevices[deviceName]?.userName) - result.putString("versionInfo", espDevices[deviceName]?.versionInfo) + result.putInt("security", security) promise?.resolve(result) } @@ -338,15 +294,21 @@ class EspIdfProvisioningModule internal constructor(context: ReactApplicationCon if (espDevices[deviceName]?.transportType == ESPConstants.TransportType.TRANSPORT_SOFTAP) { // Permission checks - if ( - hasWifiPermission() == false || - hasFineLocationPermission() == false - ) { + if (!hasWifiPermission() || !hasFineLocationPermission()) { promise?.reject(Error("Missing one of the following permissions: CHANGE_WIFI_STATE, ACCESS_WIFI_STATE, ACCESS_NETWORK_STATE, ACCESS_FINE_LOCATION")) return } } + // If device is already connected, exit early + if (espDevices[deviceName]?.transportType == ESPConstants.TransportType.TRANSPORT_BLE && + espDevices[deviceName]?.bluetoothDevice?.isAlreadyConnected() == true) { + val result = Arguments.createMap() + result.putString("status", "connected") + promise?.resolve(result) + return + } + espDevices[deviceName]?.connectToDevice() EventBus.getDefault().register(object { diff --git a/android/src/oldarch/EspIdfProvisioningSpec.kt b/android/src/oldarch/EspIdfProvisioningSpec.kt index d3e6164..9e2d736 100644 --- a/android/src/oldarch/EspIdfProvisioningSpec.kt +++ b/android/src/oldarch/EspIdfProvisioningSpec.kt @@ -7,7 +7,7 @@ import com.facebook.react.bridge.ReactContextBaseJavaModule abstract class EspIdfProvisioningSpec(context: ReactApplicationContext?) : ReactContextBaseJavaModule(context) { abstract fun searchESPDevices(devicePrefix: String, transport: String, security: Int, promise: Promise?) abstract fun stopESPDevicesSearch() - abstract fun createESPDevice(deviceName: String, transport: String, security: Int, proofOfPossesion: String?, softAPPassword: String?, username: String?, promise: Promise?) + abstract fun createESPDevice(deviceName: String, transport: String, security: Int, proofOfPossession: String?, softAPPassword: String?, username: String?, promise: Promise?) abstract fun connect(deviceName: String, promise: Promise?) abstract fun sendData(deviceName: String, path: String, data: String, promise: Promise?) abstract fun getProofOfPossession(deviceName: String, promise: Promise?) diff --git a/ios/EspIdfProvisioning.mm b/ios/EspIdfProvisioning.mm index 54aa1eb..c86d70d 100644 --- a/ios/EspIdfProvisioning.mm +++ b/ios/EspIdfProvisioning.mm @@ -30,7 +30,7 @@ @interface RCT_EXTERN_MODULE(EspIdfProvisioning, NSObject) RCT_EXTERN_METHOD(isSessionEstablished:(NSString *)deviceName) - RCT_EXTERN_METHOD(getProofOfPossesion:(NSString *)deviceName + RCT_EXTERN_METHOD(getProofOfPossession:(NSString *)deviceName resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) diff --git a/ios/EspIdfProvisioning.swift b/ios/EspIdfProvisioning.swift index 6108ea7..1285463 100644 --- a/ios/EspIdfProvisioning.swift +++ b/ios/EspIdfProvisioning.swift @@ -150,19 +150,19 @@ class EspIdfProvisioning: NSObject { return self.espDevices[deviceName]!.isSessionEstablished() } - @objc(getProofOfPossesion:resolve:reject:) - func getProofOfPossesion(deviceName: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { + @objc(getProofOfPossession:resolve:reject:) + func getProofOfPossession(deviceName: String, resolve: @escaping RCTPromiseResolveBlock, reject: @escaping RCTPromiseRejectBlock) { if self.espDevices[deviceName] == nil { reject("error", "No ESP device found. Call createESPDevice first.", nil) return } var invoked = false - self.espDevices[deviceName]!.delegate?.getProofOfPossesion(forDevice: self.espDevices[deviceName]!, completionHandler: { proofOfPossesion in + self.espDevices[deviceName]!.delegate?.getProofOfPossesion(forDevice: self.espDevices[deviceName]!, completionHandler: { proofOfPossession in // Prevent multiple callback invokation error guard !invoked else { return } - resolve(proofOfPossesion) + resolve(proofOfPossession) invoked = true }) } diff --git a/src/NativeEspIdfProvisioning.ts b/src/NativeEspIdfProvisioning.ts index 598f680..b8beb6a 100644 --- a/src/NativeEspIdfProvisioning.ts +++ b/src/NativeEspIdfProvisioning.ts @@ -58,7 +58,7 @@ export interface Spec extends TurboModule { deviceName: string, transport: ESPTransport, security: ESPSecurity, - proofOfPossesion?: string, + proofOfPossession?: string, softAPPassword?: string, username?: string ): Promise; diff --git a/src/index.tsx b/src/index.tsx index f6adeb4..c14bb83 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -47,7 +47,7 @@ export class ESPDevice implements ESPDeviceInterface { } async connect( - proofOfPossesion: string | null = null, + proofOfPossession: string | null = null, softAPPassword: string | null = null, username: string | null = null ): Promise { @@ -55,7 +55,7 @@ export class ESPDevice implements ESPDeviceInterface { this.name, this.transport, this.security, - proofOfPossesion, + proofOfPossession, softAPPassword, username );