From 1ae2a7444157ed16c12ffa3f1e76f0f099e7409d Mon Sep 17 00:00:00 2001 From: Vikas Chandra Date: Wed, 24 Mar 2021 01:18:45 +0530 Subject: [PATCH] Bugfix: Handled flow for device with no pop in capability. Made callback for getting proof of possession asynchronous in SDK. - Other minor bug fixes. --- ESPProvision.podspec | 2 +- ESPProvision/ESPDevice.swift | 26 ++- .../project.pbxproj | 8 +- .../BLE/BLELandingViewController.swift | 60 +++-- .../Base.lproj/Main.storyboard | 209 +++++++++--------- ...ller.swift => ConnectViewController.swift} | 41 ++-- .../Provision/ScannerViewController.swift | 4 +- .../SoftAP/SoftAPLandingViewController.swift | 79 +++++-- README.md | 10 + 9 files changed, 262 insertions(+), 177 deletions(-) rename Example/ESPProvisionSample/ESPProvisionSample/Provision/{ClaimViewController.swift => ConnectViewController.swift} (71%) diff --git a/ESPProvision.podspec b/ESPProvision.podspec index 0470e78..e1a977b 100644 --- a/ESPProvision.podspec +++ b/ESPProvision.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |spec| spec.name = "ESPProvision" - spec.version = "2.0.9" + spec.version = "2.0.10" spec.summary = "ESP-IDF provisioning in Swift" spec.description = "It provides mechanism to provide network credentials and/or custom data to an ESP32, ESP32-S2 or ESP8266 devices" spec.homepage = "https://github.com/espressif/esp-idf-provisioning-ios" diff --git a/ESPProvision/ESPDevice.swift b/ESPProvision/ESPDevice.swift index 06bc9ee..1382f4d 100644 --- a/ESPProvision/ESPDevice.swift +++ b/ESPProvision/ESPDevice.swift @@ -45,9 +45,10 @@ public enum ESPProvisionStatus { public protocol ESPDeviceConnectionDelegate { /// Get Proof of possession for an `ESPDevice` from object conforming `ESPDeviceConnectionDelegate` protocol. /// - /// - Parameter forDevice: `ESPDevice`for which Proof of possession is needed. - /// - Returns: Proof of possesion string. - func getProofOfPossesion(forDevice: ESPDevice) -> String? + /// - Parameters: + /// - forDevice: `ESPDevice`for which Proof of possession is needed. + /// - completionHandler: Call this method to return POP needed for initialting session with the device. + func getProofOfPossesion(forDevice: ESPDevice, completionHandler: @escaping (String) -> Void) } /// The `ESPDevice` class is the main inteface for managing a device. It encapsulates method and properties @@ -202,7 +203,7 @@ public class ESPDevice { /// - completionHandler: The completion handler that is called when data transmission is successful. /// Parameter of block include response received from the HTTP request or error if any. public func sendData(path:String, data:Data, completionHandler: @escaping (Data?, ESPSessionError?) -> Swift.Void) { - if session == nil, !session.isEstablished { + if session == nil || !session.isEstablished { completionHandler(nil,.sessionNotEstablished) } else { self.sendDataToDevice(path: path, data: data, retryOnce: true, completionHandler: completionHandler) @@ -398,20 +399,27 @@ public class ESPDevice { case .secure: var pop:String! if let capability = self.capabilities, capability.contains(ESPConstants.noProofCapability) { - pop = "" + initSecureSession(pop: "", completionHandler: completionHandler) } else { if self.proofOfPossession == nil { - pop = delegate?.getProofOfPossesion(forDevice: self) ?? "" + delegate?.getProofOfPossesion(forDevice: self, completionHandler: { popString in + self.initSecureSession(pop: popString, completionHandler: completionHandler) + }) } else { pop = self.proofOfPossession ?? "" + self.initSecureSession(pop: pop, completionHandler: completionHandler) } } - ESPLog.log("Initialise session security 1") - securityLayer = ESPSecurity1(proofOfPossession: pop) case .unsecure: ESPLog.log("Initialise session security 0") securityLayer = ESPSecurity0() + initSession(completionHandler: completionHandler) } + } + + private func initSecureSession(pop: String, completionHandler: @escaping (ESPSessionStatus) -> Void) { + ESPLog.log("Initialise session security 1") + securityLayer = ESPSecurity1(proofOfPossession: pop) initSession(completionHandler: completionHandler) } @@ -437,7 +445,7 @@ public class ESPDevice { } } - /// Get device version information`. + /// Get device version information. /// /// - Parameter completionHandler: Invoked when error is encountered while getting device version. private func getDeviceVersionInfo(completionHandler: @escaping (ESPSessionStatus) -> Void) { diff --git a/Example/ESPProvisionSample/ESPProvisionSample.xcodeproj/project.pbxproj b/Example/ESPProvisionSample/ESPProvisionSample.xcodeproj/project.pbxproj index 3191664..65ba9d9 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample.xcodeproj/project.pbxproj +++ b/Example/ESPProvisionSample/ESPProvisionSample.xcodeproj/project.pbxproj @@ -30,7 +30,7 @@ F1A0A47424A27E5000CB347C /* SoftAPLandingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A0A47324A27E5000CB347C /* SoftAPLandingViewController.swift */; }; F1A0A47724A287E800CB347C /* NetworkExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1A0A47624A287E800CB347C /* NetworkExtension.framework */; }; F1A0A47A24A29C9900CB347C /* GitVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A0A47924A29C9800CB347C /* GitVersion.swift */; }; - F1A3DBCA24A0E934005AF0ED /* ClaimViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A3DBC924A0E934005AF0ED /* ClaimViewController.swift */; }; + F1A3DBCA24A0E934005AF0ED /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A3DBC924A0E934005AF0ED /* ConnectViewController.swift */; }; F1A3DBCC24A1072E005AF0ED /* ESPAppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1A3DBCB24A1072E005AF0ED /* ESPAppSettings.swift */; }; /* End PBXBuildFile section */ @@ -93,7 +93,7 @@ F1A0A47524A287DD00CB347C /* ESP BLE PROV.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "ESP BLE PROV.entitlements"; sourceTree = ""; }; F1A0A47624A287E800CB347C /* NetworkExtension.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = NetworkExtension.framework; path = System/Library/Frameworks/NetworkExtension.framework; sourceTree = SDKROOT; }; F1A0A47924A29C9800CB347C /* GitVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GitVersion.swift; sourceTree = ""; }; - F1A3DBC924A0E934005AF0ED /* ClaimViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClaimViewController.swift; sourceTree = ""; }; + F1A3DBC924A0E934005AF0ED /* ConnectViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = ""; }; F1A3DBCB24A1072E005AF0ED /* ESPAppSettings.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPAppSettings.swift; sourceTree = ""; }; F48E37150E222A0F06AED170 /* Pods-ESPProvisionSampleTests.softap.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ESPProvisionSampleTests.softap.xcconfig"; path = "Target Support Files/Pods-ESPProvisionSampleTests/Pods-ESPProvisionSampleTests.softap.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ @@ -247,7 +247,7 @@ F1A0A48A24A5DB5900CB347C /* Provision */ = { isa = PBXGroup; children = ( - F1A3DBC924A0E934005AF0ED /* ClaimViewController.swift */, + F1A3DBC924A0E934005AF0ED /* ConnectViewController.swift */, F19AEBD8249FD0D50078E5A1 /* WifiListTableViewCell.swift */, F19AEBDA249FD8C10078E5A1 /* DeviceTypeViewController.swift */, F19AEBD2249B926F0078E5A1 /* ScannerViewController.swift */, @@ -514,7 +514,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - F1A3DBCA24A0E934005AF0ED /* ClaimViewController.swift in Sources */, + F1A3DBCA24A0E934005AF0ED /* ConnectViewController.swift in Sources */, F19AEBD7249BAB4D0078E5A1 /* StatusViewController.swift in Sources */, F19AEBDF249FE1310078E5A1 /* BLEDeviceListViewCell.swift in Sources */, F1A3DBCC24A1072E005AF0ED /* ESPAppSettings.swift in Sources */, diff --git a/Example/ESPProvisionSample/ESPProvisionSample/BLE/BLELandingViewController.swift b/Example/ESPProvisionSample/ESPProvisionSample/BLE/BLELandingViewController.swift index a138bf7..e3cdb7d 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample/BLE/BLELandingViewController.swift +++ b/Example/ESPProvisionSample/ESPProvisionSample/BLE/BLELandingViewController.swift @@ -125,12 +125,6 @@ class BLELandingViewController: UIViewController, UITableViewDelegate, UITableVi // MARK: - Helper Methods - func goToClaimVC(device: ESPDevice) { - let claimVC = storyboard?.instantiateViewController(withIdentifier: "claimVC") as! ClaimViewController - claimVC.espDevice = device - navigationController?.pushViewController(claimVC, animated: true) - } - func goToProvision(device: ESPDevice) { DispatchQueue.main.async { Utility.hideLoader(view: self.view) @@ -139,15 +133,40 @@ class BLELandingViewController: UIViewController, UITableViewDelegate, UITableVi self.navigationController?.pushViewController(provisionVC, animated: true) } } - - private func showBusy(isBusy: Bool, message: String = "") { - DispatchQueue.main.async { - if isBusy { - let loader = MBProgressHUD.showAdded(to: self.view, animated: true) - loader.mode = MBProgressHUDMode.indeterminate - loader.label.text = message - } else { - MBProgressHUD.hide(for: self.view, animated: true) + + private func showAlert(error: String, action: UIAlertAction) { + let alertController = UIAlertController(title: "Error!", message: error, preferredStyle: .alert) + alertController.addAction(action) + self.present(alertController, animated: true, completion: nil) + } + + private func connectDevice(device:ESPDevice) { + device.connect(delegate: self) { status in + DispatchQueue.main.async { + Utility.hideLoader(view: self.view) + } + switch status { + case .connected: + DispatchQueue.main.async { + self.goToProvision(device: device) + } + case let .failedToConnect(error): + DispatchQueue.main.async { + var errorDescription = "" + switch error { + case .securityMismatch, .versionInfoError: + errorDescription = error.description + default: + errorDescription = error.description + "\nCheck if POP is correct." + } + let action = UIAlertAction(title: "Retry", style: .default, handler: nil) + self.showAlert(error: errorDescription, action: action) + } + default: + DispatchQueue.main.async { + let action = UIAlertAction(title: "Retry", style: .default, handler: nil) + self.showAlert(error: "Device disconnected", action: action) + } } } } @@ -177,7 +196,7 @@ class BLELandingViewController: UIViewController, UITableViewDelegate, UITableVi func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { tableView.deselectRow(at: indexPath, animated: true) Utility.showLoader(message: "Connecting to device", view: self.view) - self.goToClaimVC(device: self.bleDevices![indexPath.row]) + self.connectDevice(device: self.bleDevices![indexPath.row]) } } @@ -188,3 +207,12 @@ extension BLELandingViewController: UITextFieldDelegate { return false } } + +extension BLELandingViewController: ESPDeviceConnectionDelegate { + func getProofOfPossesion(forDevice: ESPDevice, completionHandler: @escaping (String) -> Void) { + let connectVC = self.storyboard?.instantiateViewController(withIdentifier: "connectVC") as! ConnectViewController + connectVC.espDevice = forDevice + connectVC.popHandler = completionHandler + self.navigationController?.pushViewController(connectVC, animated: true) + } +} diff --git a/Example/ESPProvisionSample/ESPProvisionSample/Base.lproj/Main.storyboard b/Example/ESPProvisionSample/ESPProvisionSample/Base.lproj/Main.storyboard index adc60e9..98055cc 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample/Base.lproj/Main.storyboard +++ b/Example/ESPProvisionSample/ESPProvisionSample/Base.lproj/Main.storyboard @@ -1,9 +1,9 @@ - - + + - + @@ -14,20 +14,20 @@ - + - + - + @@ -141,7 +141,7 @@ - + @@ -167,20 +167,20 @@ - + - +