From 38a906134689cf8111183365863f00cfcd47c21e Mon Sep 17 00:00:00 2001 From: Vikas Chandra Date: Sun, 7 May 2023 19:04:46 +0530 Subject: [PATCH] Feature: Adapted the ESPProvision library to be compatible with Swift Package. Enabling its seamless integration as a dependency in Xcode projects. --- .gitignore | 2 + ESPProvision.podspec | 7 +- ESPProvision.xcodeproj/project.pbxproj | 16 +- ESPProvision/Crypto/AESDecryptor.h | 39 - ESPProvision/Crypto/AESDecryptor.m | 98 -- ESPProvision/Crypto/AESDecryptor.swift | 123 +++ ESPProvision/Crypto/CryptoAES.swift | 4 +- ESPProvision/Crypto/ESPSecurity1.swift | 63 +- ESPProvision/ESPProvision.h | 31 - ESPProvision/ESPProvision.swift | 2 +- ESPProvision/Security2/ESPSecurity2.swift | 1 - ESPProvision/Utility/ESPExtensions.swift | 1 + .../project.pbxproj | 917 ++++++++++++++++++ .../ESPProvisionSPMSample/AppDelegate.swift | 46 + .../Base.lproj/LaunchScreen.storyboard | 25 + .../ESPProvisionSPMSample.entitlements | 10 + .../ESPProvisionSPMSample/Info.plist | 46 + .../ESPProvisionSPMSample/SceneDelegate.swift | 63 ++ .../ViewController.swift | 69 ++ .../ESPProvisionSPMSampleTests.swift | 47 + .../ESPProvisionSPMSampleUITests.swift | 52 + ...ProvisionSPMSampleUITestsLaunchTests.swift | 43 + Example/ESPProvisionSPMSample/Podfile | 30 + .../Provision/ConnectViewController.swift | 2 +- .../Provision/ProvisionViewController.swift | 2 +- .../Provision/ScannerViewController.swift | 4 +- .../Settings/SettingsViewController.swift | 1 + .../SoftAP/SoftAPLandingViewController.swift | 1 - .../ESPProvisionSample/Utility.swift | 1 + Package.swift | 33 + Podfile | 9 +- README.md | 18 + 32 files changed, 1578 insertions(+), 228 deletions(-) delete mode 100644 ESPProvision/Crypto/AESDecryptor.h delete mode 100644 ESPProvision/Crypto/AESDecryptor.m create mode 100644 ESPProvision/Crypto/AESDecryptor.swift delete mode 100644 ESPProvision/ESPProvision.h create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSample.xcodeproj/project.pbxproj create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSample/AppDelegate.swift create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSample/Base.lproj/LaunchScreen.storyboard create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSample/ESPProvisionSPMSample.entitlements create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSample/Info.plist create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSample/SceneDelegate.swift create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSample/ViewController.swift create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSampleTests/ESPProvisionSPMSampleTests.swift create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSampleUITests/ESPProvisionSPMSampleUITests.swift create mode 100644 Example/ESPProvisionSPMSample/ESPProvisionSPMSampleUITests/ESPProvisionSPMSampleUITestsLaunchTests.swift create mode 100644 Example/ESPProvisionSPMSample/Podfile create mode 100644 Package.swift diff --git a/.gitignore b/.gitignore index ba81299..e46d506 100644 --- a/.gitignore +++ b/.gitignore @@ -70,3 +70,5 @@ fastlane/screenshots/**/*.png fastlane/test_output EspressifProvision/EspressifProvision/proto/*.swift +Package.resolved +Example/ESPProvisionSPMSample/ESPProvisionSPMSample.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/ESPProvision.podspec b/ESPProvision.podspec index cfc62cb..6566230 100644 --- a/ESPProvision.podspec +++ b/ESPProvision.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |spec| spec.name = "ESPProvision" - spec.version = "2.1.0" + spec.version = "2.1.1" 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" @@ -23,14 +23,13 @@ Pod::Spec.new do |spec| spec.author = "Espressif Systems" spec.platform = :ios, "13.0" - spec.source = { :git => "https://github.com/espressif/esp-idf-provisioning-ios.git", :tag => "lib-#{spec.version}" } + spec.source = { :git => "https://github.com/espressif/esp-idf-provisioning-ios.git", :tag => "#{spec.version}" } - spec.source_files = "ESPProvision", "ESPProvision/**/*.{h,m,swift}" + spec.source_files = "ESPProvision", "ESPProvision/**/*.{swift}" spec.subspec 'Core' do |cs| cs.dependency "SwiftProtobuf", "~> 1.5.0" - cs.dependency "Curve25519", "~> 1.1.0" end spec.swift_versions = ['5.1', '5.2'] diff --git a/ESPProvision.xcodeproj/project.pbxproj b/ESPProvision.xcodeproj/project.pbxproj index fe07678..874b332 100644 --- a/ESPProvision.xcodeproj/project.pbxproj +++ b/ESPProvision.xcodeproj/project.pbxproj @@ -12,6 +12,7 @@ F15B525828AA1794009852DB /* sec2.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = F15B525728AA1794009852DB /* sec2.pb.swift */; }; F15B525A28AA1915009852DB /* ESPSecurity2.swift in Sources */ = {isa = PBXBuildFile; fileRef = F15B525928AA1915009852DB /* ESPSecurity2.swift */; }; F168F2C928E0B97A00E39433 /* Comparable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F168F2C828E0B97A00E39433 /* Comparable.swift */; }; + F177859C2A057F4500C3AE73 /* AESDecryptor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F177859B2A057F4500C3AE73 /* AESDecryptor.swift */; }; F17B313C28476DB50052D80F /* ESPScanStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17B313B28476DB50052D80F /* ESPScanStatus.swift */; }; F183F7EF28B37ADE00CB7E86 /* AuthenticationFailure.swift in Sources */ = {isa = PBXBuildFile; fileRef = F183F7E928B37ADD00CB7E86 /* AuthenticationFailure.swift */; }; F183F7F028B37ADE00CB7E86 /* SRP.swift in Sources */ = {isa = PBXBuildFile; fileRef = F183F7EA28B37ADD00CB7E86 /* SRP.swift */; }; @@ -33,15 +34,12 @@ F183F85028B37D4D00CB7E86 /* String Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = F183F83A28B37D4D00CB7E86 /* String Conversion.swift */; }; F183F85228C5F41500CB7E86 /* ESPScanResult.swift in Sources */ = {isa = PBXBuildFile; fileRef = F183F85128C5F41300CB7E86 /* ESPScanResult.swift */; }; F183F85428C73A8D00CB7E86 /* Bitwise Ops.swift in Sources */ = {isa = PBXBuildFile; fileRef = F183F85328C73A8C00CB7E86 /* Bitwise Ops.swift */; }; - F1C34D30244EEF0000340B04 /* ESPProvision.h in Headers */ = {isa = PBXBuildFile; fileRef = F1C34D22244EEEFF00340B04 /* ESPProvision.h */; settings = {ATTRIBUTES = (Public, ); }; }; F1C34D3C245017C900340B04 /* ESPDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D3B245017C900340B04 /* ESPDevice.swift */; }; F1C34D402451810200340B04 /* ESPCommunicable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D3F2451810200340B04 /* ESPCommunicable.swift */; }; F1C34D4224518F3900340B04 /* ESPSoftAPTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D4124518F3900340B04 /* ESPSoftAPTransport.swift */; }; F1C34D4424518F4B00340B04 /* ESPBleTransport.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D4324518F4B00340B04 /* ESPBleTransport.swift */; }; F1C34D462451B33100340B04 /* ESPCodeable.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D452451B33100340B04 /* ESPCodeable.swift */; }; F1C34D482451F46400340B04 /* ESPSecurity0.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D472451F46400340B04 /* ESPSecurity0.swift */; }; - F1C34D4B2457463700340B04 /* AESDecryptor.m in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D492457463600340B04 /* AESDecryptor.m */; }; - F1C34D4C2457463700340B04 /* AESDecryptor.h in Headers */ = {isa = PBXBuildFile; fileRef = F1C34D4A2457463700340B04 /* AESDecryptor.h */; settings = {ATTRIBUTES = (Public, ); }; }; F1C34D4E2457469D00340B04 /* ESPExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D4D2457469D00340B04 /* ESPExtensions.swift */; }; F1C34D502457479C00340B04 /* CryptoAES.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D4F2457479C00340B04 /* CryptoAES.swift */; }; F1C34D5D24596C8500340B04 /* constants.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = F1C34D5624596C8500340B04 /* constants.pb.swift */; }; @@ -98,6 +96,7 @@ F15B525728AA1794009852DB /* sec2.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = sec2.pb.swift; sourceTree = ""; }; F15B525928AA1915009852DB /* ESPSecurity2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPSecurity2.swift; sourceTree = ""; }; F168F2C828E0B97A00E39433 /* Comparable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Comparable.swift; sourceTree = ""; }; + F177859B2A057F4500C3AE73 /* AESDecryptor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AESDecryptor.swift; sourceTree = ""; }; F17B313B28476DB50052D80F /* ESPScanStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPScanStatus.swift; sourceTree = ""; }; F183F7E928B37ADD00CB7E86 /* AuthenticationFailure.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthenticationFailure.swift; sourceTree = ""; }; F183F7EA28B37ADD00CB7E86 /* SRP.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SRP.swift; sourceTree = ""; }; @@ -120,7 +119,6 @@ F183F85128C5F41300CB7E86 /* ESPScanResult.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPScanResult.swift; sourceTree = ""; }; F183F85328C73A8C00CB7E86 /* Bitwise Ops.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bitwise Ops.swift"; sourceTree = ""; }; F1C34D1F244EEEFF00340B04 /* ESPProvision.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ESPProvision.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - F1C34D22244EEEFF00340B04 /* ESPProvision.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ESPProvision.h; sourceTree = ""; }; F1C34D23244EEEFF00340B04 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; F1C34D3B245017C900340B04 /* ESPDevice.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPDevice.swift; sourceTree = ""; }; F1C34D3F2451810200340B04 /* ESPCommunicable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPCommunicable.swift; sourceTree = ""; }; @@ -128,8 +126,6 @@ F1C34D4324518F4B00340B04 /* ESPBleTransport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPBleTransport.swift; sourceTree = ""; }; F1C34D452451B33100340B04 /* ESPCodeable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPCodeable.swift; sourceTree = ""; }; F1C34D472451F46400340B04 /* ESPSecurity0.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPSecurity0.swift; sourceTree = ""; }; - F1C34D492457463600340B04 /* AESDecryptor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AESDecryptor.m; sourceTree = ""; }; - F1C34D4A2457463700340B04 /* AESDecryptor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AESDecryptor.h; sourceTree = ""; }; F1C34D4D2457469D00340B04 /* ESPExtensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPExtensions.swift; sourceTree = ""; }; F1C34D4F2457479C00340B04 /* CryptoAES.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CryptoAES.swift; sourceTree = ""; }; F1C34D5624596C8500340B04 /* constants.pb.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = constants.pb.swift; sourceTree = ""; }; @@ -263,7 +259,6 @@ F1C34D542459679900340B04 /* Crypto */, F1C34D532459677300340B04 /* Transport */, F15B525F28AB83EF009852DB /* Security2 */, - F1C34D22244EEEFF00340B04 /* ESPProvision.h */, F1C34D23244EEEFF00340B04 /* Info.plist */, F1C34D75245F178E00340B04 /* ESPProvisionManager.swift */, F1C34D692459B3F200340B04 /* ESPSession.swift */, @@ -287,10 +282,9 @@ F1C34D542459679900340B04 /* Crypto */ = { isa = PBXGroup; children = ( + F177859B2A057F4500C3AE73 /* AESDecryptor.swift */, F1C34D452451B33100340B04 /* ESPCodeable.swift */, F1C34D472451F46400340B04 /* ESPSecurity0.swift */, - F1C34D4A2457463700340B04 /* AESDecryptor.h */, - F1C34D492457463600340B04 /* AESDecryptor.m */, F1C34D4F2457479C00340B04 /* CryptoAES.swift */, F1C34D71245C7EEB00340B04 /* ESPSecurity1.swift */, ); @@ -353,8 +347,6 @@ isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( - F1C34D4C2457463700340B04 /* AESDecryptor.h in Headers */, - F1C34D30244EEF0000340B04 /* ESPProvision.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -497,12 +489,12 @@ F1C34D502457479C00340B04 /* CryptoAES.swift in Sources */, F1C34D76245F178E00340B04 /* ESPProvisionManager.swift in Sources */, F1C34D6024596C8500340B04 /* wifi_constants.pb.swift in Sources */, - F1C34D4B2457463700340B04 /* AESDecryptor.m in Sources */, F183F84A28B37D4D00CB7E86 /* Exponentiation.swift in Sources */, F1C34D702459F60900340B04 /* ESPErrors.swift in Sources */, F1C34D5D24596C8500340B04 /* constants.pb.swift in Sources */, F1C34D8124618ACC00340B04 /* ESPWifiNetwork.swift in Sources */, F183F7F228B37ADE00CB7E86 /* Client.swift in Sources */, + F177859C2A057F4500C3AE73 /* AESDecryptor.swift in Sources */, F1C34D6224596C8500340B04 /* sec0.pb.swift in Sources */, F1C34D3C245017C900340B04 /* ESPDevice.swift in Sources */, F183F84E28B37D4D00CB7E86 /* Integer Conversion.swift in Sources */, diff --git a/ESPProvision/Crypto/AESDecryptor.h b/ESPProvision/Crypto/AESDecryptor.h deleted file mode 100644 index 0f8bc31..0000000 --- a/ESPProvision/Crypto/AESDecryptor.h +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright 2020 Espressif Systems -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Encrpyt.h -// EspressifProvision -// - -#import -#import - -NS_ASSUME_NONNULL_BEGIN - -@interface AESDecryptor : NSObject - --(id)initWithKey:(NSData *)key andIV:(NSData *)iv; - -- (NSData *)cryptData:(NSData *)dataIn - operation:(CCOperation)operation // kCC Encrypt, Decrypt - mode:(CCMode)mode // kCCMode ECB, CBC, CFB, CTR, OFB, RC4, CFB8 - algorithm:(CCAlgorithm)algorithm // CCAlgorithm AES DES, 3DES, CAST, RC4, RC2, Blowfish - padding:(CCPadding)padding // cc NoPadding, PKCS7Padding - keyLength:(size_t)keyLength // kCCKeySizeAES 128, 192, 256 - iv:(NSData *)iv // CBC, CFB, CFB8, OFB, CTR - key:(NSData *)key - error:(NSError **)error; -@end - -NS_ASSUME_NONNULL_END diff --git a/ESPProvision/Crypto/AESDecryptor.m b/ESPProvision/Crypto/AESDecryptor.m deleted file mode 100644 index 0b24374..0000000 --- a/ESPProvision/Crypto/AESDecryptor.m +++ /dev/null @@ -1,98 +0,0 @@ -// Copyright 2020 Espressif Systems -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// Encrpyt.m -// EspressifProvision -// - -#import "AESDecryptor.h" -@interface AESDecryptor() { - CCCryptorRef cryptor; -} -@end - -@implementation AESDecryptor - --(id)initWithKey:(NSData *)key andIV:(NSData *)iv { - cryptor = NULL; - CCCryptorStatus ccStatus = 0; - - ccStatus = CCCryptorCreateWithMode(kCCEncrypt, kCCModeCTR, kCCAlgorithmAES, - ccNoPadding, - iv.bytes, key.bytes, - kCCKeySizeAES256, - NULL, 0, 0, // tweak XTS mode, numRounds - kCCModeOptionCTR_BE, // CCModeOptions - &cryptor); - return self; -} -- (NSData *)cryptData:(NSData *)dataIn - operation:(CCOperation)operation // kCC Encrypt, Decrypt - mode:(CCMode)mode // kCCMode ECB, CBC, CFB, CTR, OFB, RC4, CFB8 - algorithm:(CCAlgorithm)algorithm // CCAlgorithm AES DES, 3DES, CAST, RC4, RC2, Blowfish - padding:(CCPadding)padding // cc NoPadding, PKCS7Padding - keyLength:(size_t)keyLength // kCCKeySizeAES 128, 192, 256 - iv:(NSData *)iv // CBC, CFB, CFB8, OFB, CTR - key:(NSData *)key - error:(NSError **)error -{ - if (key.length != keyLength) { - NSLog(@"CCCryptorArgument key.length: %lu != keyLength: %zu", (unsigned long)key.length, keyLength); - if (error) { - *error = [NSError errorWithDomain:@"kArgumentError key length" code:key.length userInfo:nil]; - } - return nil; - } - - size_t dataOutMoved = 0; - size_t dataOutMovedTotal = 0; - CCCryptorStatus ccStatus = 0; - - size_t dataOutLength = CCCryptorGetOutputLength(cryptor, dataIn.length, true); - NSMutableData *dataOut = [NSMutableData dataWithLength:dataOutLength]; - char *dataOutPointer = (char *)dataOut.mutableBytes; - - ccStatus = CCCryptorUpdate(cryptor, - dataIn.bytes, dataIn.length, - dataOutPointer, dataOutLength, - &dataOutMoved); - dataOutMovedTotal += dataOutMoved; - - if (ccStatus != kCCSuccess) { - NSLog(@"CCCryptorUpdate status: %d", ccStatus); - if (error) { - *error = [NSError errorWithDomain:@"kUpdateError" code:ccStatus userInfo:nil]; - } - CCCryptorRelease(cryptor); - return nil; - } - - ccStatus = CCCryptorFinal(cryptor, - dataOutPointer + dataOutMoved, dataOutLength - dataOutMoved, - &dataOutMoved); - if (ccStatus != kCCSuccess) { - NSLog(@"CCCryptorFinal status: %d", ccStatus); - if (error) { - *error = [NSError errorWithDomain:@"kFinalError" code:ccStatus userInfo:nil]; - } - CCCryptorRelease(cryptor); - return nil; - } - - dataOutMovedTotal += dataOutMoved; - dataOut.length = dataOutMovedTotal; - - return dataOut; -} -@end diff --git a/ESPProvision/Crypto/AESDecryptor.swift b/ESPProvision/Crypto/AESDecryptor.swift new file mode 100644 index 0000000..4bd5240 --- /dev/null +++ b/ESPProvision/Crypto/AESDecryptor.swift @@ -0,0 +1,123 @@ +// Copyright 2023 Espressif Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// AppDelegate.swift +// ESPProvisionSample +// + +import CommonCrypto +import Foundation + +class AESDecryptor { + var cryptor: CCCryptorRef? + var ccStatus: CCCryptorStatus = 0 + + init(key: Data, iv: Data) { + cryptor = nil + + ccStatus = CCCryptorCreateWithMode( + CCOperation(kCCEncrypt), + CCMode(kCCModeCTR), + CCAlgorithm(kCCAlgorithmAES), + CCPadding(ccNoPadding), + iv.bytes, key.bytes, + key.count, + nil, 0, 0, // tweak XTS mode, numRounds + CCModeOptions(kCCModeOptionCTR_BE), + &cryptor) + } + + + func cryptData(dataIn: Data, + operation: CCOperation, // kCC Encrypt, Decrypt + mode: CCMode, // kCCMode ECB, CBC, CFB, CTR, OFB, RC4, CFB8 + algorithm: CCAlgorithm, // CCAlgorithm AES DES, 3DES, CAST, RC4, RC2, Blowfish + padding: CCPadding, // cc NoPadding, PKCS7Padding + keyLength: size_t, // kCCKeySizeAES 128, 192, 256 + iv: Data, // CBC, CFB, CFB8, OFB, CTR + key: Data, + error: inout NSError?) -> Data? + { + // Check that the key length is correct + if (key.count != keyLength) { + if (error != nil) { + error = NSError(domain: "kArgumentError key length", code: key.count, userInfo: nil) + } + return nil + } + + var dataOutMoved: size_t = 0 + var dataOutMovedTotal: size_t = 0 + var ccStatus: CCCryptorStatus = 0 + + // Get the output buffer size + let dataOutLength = CCCryptorGetOutputLength(cryptor, dataIn.count, true) + // Allocate the output buffer + var dataOut = NSMutableData(length: dataOutLength)! + let dataOutPointer = dataOut.mutableBytes.assumingMemoryBound(to: CChar.self) + + // Encrypt or decrypt the input data + ccStatus = CCCryptorUpdate( + cryptor!, + dataIn.bytes, dataIn.count, + dataOutPointer, dataOutLength, + &dataOutMoved) + dataOutMovedTotal += dataOutMoved + + if ccStatus != kCCSuccess { + if error != nil { + error = NSError(domain: "kUpdateError", code: Int(ccStatus), userInfo: nil) + } + CCCryptorRelease(cryptor!) + return nil + } + + // Finalize the encryption or decryption + ccStatus = CCCryptorFinal( + cryptor!, + dataOutPointer + dataOutMoved, dataOutLength - dataOutMoved, + &dataOutMoved) + if ccStatus != kCCSuccess { + if error != nil { + error = NSError(domain: "kFinalError", code: Int(ccStatus), userInfo: nil) + } + CCCryptorRelease(cryptor!) + return nil + } + + dataOutMovedTotal += dataOutMoved + dataOut.length = dataOutMovedTotal + + return (dataOut as Data) + } + + /** + Copies the contents of an array of elements starting at a specified index to an UnsafeMutableRawPointer. + + - Parameters: + - to: An UnsafeMutableRawPointer to which the elements will be copied. + - from: An array of elements to copy. + - startIndexAtPointer: The starting index in bytes at which to copy the elements to the destination pointer. + */ + func copyMemoryStartingAtIndex(to umrp: UnsafeMutableRawPointer, from arr: [T], startIndexAtPointer toIndex: Int) { + // Calculate the byte offset from the destination pointer based on the starting index. + let byteOffset = MemoryLayout.stride * toIndex + // Calculate the total number of bytes that need to be copied based on the size of each element in the array. + let byteCount = MemoryLayout.stride * arr.count + + // Use the `copyMemory` method of the destination pointer to copy the bytes from the source array to the destination pointer. + // The `advanced(by:)` method is used to move the pointer to the correct starting index before copying. + umrp.advanced(by: byteOffset).copyMemory(from: arr, byteCount: byteCount) + } +} diff --git a/ESPProvision/Crypto/CryptoAES.swift b/ESPProvision/Crypto/CryptoAES.swift index add264b..d3675ef 100644 --- a/ESPProvision/Crypto/CryptoAES.swift +++ b/ESPProvision/Crypto/CryptoAES.swift @@ -30,13 +30,13 @@ class CryptoAES { public init(key: Data, iv: Data) { self.key = key self.iv = iv - decryptor = AESDecryptor(key: key, andIV: iv) + decryptor = AESDecryptor(key: key, iv: iv) } func encrypt(data: Data) -> Data? { var returnData: Data? var error: NSError? - returnData = decryptor.cryptData(data, operation: CCOperation(kCCEncrypt), mode: CCMode(kCCModeCTR), algorithm: CCAlgorithm(kCCAlgorithmAES), padding: CCPadding(ccNoPadding), keyLength: kCCKeySizeAES256, iv: iv, key: key, error: &error) + returnData = decryptor.cryptData(dataIn: data, operation: CCOperation(kCCEncrypt), mode: CCMode(kCCModeCTR), algorithm: CCAlgorithm(kCCAlgorithmAES), padding: CCPadding(ccNoPadding), keyLength: kCCKeySizeAES256, iv: iv, key: key, error: &error) return returnData } } diff --git a/ESPProvision/Crypto/ESPSecurity1.swift b/ESPProvision/Crypto/ESPSecurity1.swift index 8751817..990b84a 100644 --- a/ESPProvision/Crypto/ESPSecurity1.swift +++ b/ESPProvision/Crypto/ESPSecurity1.swift @@ -16,10 +16,11 @@ // ESPProvision // -import Curve25519 + import Foundation import Security import SwiftProtobuf +import CryptoKit /// Enum type which encapsulates different states of a secured session. enum Security1SessionState: Int { @@ -41,8 +42,8 @@ class ESPSecurity1: ESPCodeable { private var sessionState: Security1SessionState = .Request1 private var proofOfPossession: Data? - private var privateKey: Data? - private var publicKey: Data? + private var privateKey: Curve25519.KeyAgreement.PrivateKey? + private var publicKey: Curve25519.KeyAgreement.PublicKey? private var clientVerify: Data? private var cryptoAES: CryptoAES? @@ -115,26 +116,18 @@ class ESPSecurity1: ESPCodeable { private func generatePrivateKey() -> Data? { ESPLog.log("Generating random private key.") - var keyData = Data(count: 32) - let result = keyData.withUnsafeMutableBytes { - SecRandomCopyBytes(kSecRandomDefault, 32, $0.baseAddress!) - } - if result == errSecSuccess { - return keyData - } else { - ESPLog.log("Error generating random bytes.") - return nil - } + + return Curve25519.Signing.PrivateKey().rawRepresentation } private func generateKeyPair() { ESPLog.log("Generating key pair for encrypting data.") - self.privateKey = generatePrivateKey() - guard let privateKey = self.privateKey else { + self.privateKey = CryptoKit.Curve25519.KeyAgreement.PrivateKey() + guard self.privateKey != nil else { publicKey = nil return } - publicKey = try? Curve25519.publicKey(for: privateKey, basepoint: ESPSecurity1.basePoint) + publicKey = self.privateKey?.publicKey } /// Generate data to send on Step 0 of session request. @@ -146,7 +139,7 @@ class ESPSecurity1: ESPCodeable { } var sessionData = Espressif_SessionData() sessionData.secVer = .secScheme1 - sessionData.sec1.sc0.clientPubkey = publicKey + sessionData.sec1.sc0.clientPubkey = publicKey.rawRepresentation do { return try sessionData.serializedData() } catch { @@ -194,23 +187,25 @@ class ESPSecurity1: ESPCodeable { let devicePublicKey = sessionData.sec1.sr0.devicePubkey let deviceRandom = sessionData.sec1.sr0.deviceRandom do { - var sharedKey = try Curve25519.calculateAgreement(privateKey: privateKey!, publicKey: devicePublicKey) - if let pop = self.proofOfPossession, pop.count > 0 { - let digest = pop.sha256() - sharedKey = HexUtils.xor(first: sharedKey, second: digest) - } - - cryptoAES = CryptoAES(key: sharedKey, iv: deviceRandom) - - let verifyBytes = encrypt(data: devicePublicKey) - - if verifyBytes == nil { - ESPLog.log("Cannot encrypt device key") - throw SecurityError.handshakeError("Cannot encrypt device key") + let sharedKey = try privateKey?.sharedSecretFromKeyAgreement(with: Curve25519.KeyAgreement.PublicKey(rawRepresentation: devicePublicKey)) + if var sharedKeyData = sharedKey?.withUnsafeBytes({Data($0)}) { + if let pop = self.proofOfPossession, pop.count > 0 { + let digest = pop.sha256() + sharedKeyData = HexUtils.xor(first: sharedKeyData, second: digest) + } + + cryptoAES = CryptoAES(key: sharedKeyData, iv: deviceRandom) + + let verifyBytes = encrypt(data: devicePublicKey) + + if verifyBytes == nil { + ESPLog.log("Cannot encrypt device key") + throw SecurityError.handshakeError("Cannot encrypt device key") + } + + ESPLog.log("Step0 response processed.") + clientVerify = verifyBytes } - - ESPLog.log("Step0 response processed.") - clientVerify = verifyBytes } catch { ESPLog.log(error.localizedDescription) } @@ -234,7 +229,7 @@ class ESPSecurity1: ESPCodeable { let deviceVerify = sessionData.sec1.sr1.deviceVerifyData let decryptedDeviceVerify = decrypt(data: deviceVerify) if let decryptedDeviceVerify = decryptedDeviceVerify, - !decryptedDeviceVerify.bytes.elementsEqual(self.publicKey!.bytes) { + !decryptedDeviceVerify.bytes.elementsEqual(self.publicKey!.rawRepresentation.bytes) { ESPLog.log("Key mismatch") throw SecurityError.handshakeError("Key mismatch") } diff --git a/ESPProvision/ESPProvision.h b/ESPProvision/ESPProvision.h deleted file mode 100644 index 11d2849..0000000 --- a/ESPProvision/ESPProvision.h +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright 2020 Espressif Systems -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ESPProvision.h -// ESPProvision -// - -#import -#import -#import "AESDecryptor.h" - -//! Project version number for ESPProvision. -FOUNDATION_EXPORT double ESPProvisionVersionNumber; - -//! Project version string for ESPProvision. -FOUNDATION_EXPORT const unsigned char ESPProvisionVersionString[]; - -// In this header, you should import all the public headers of your framework using statements like #import - - diff --git a/ESPProvision/ESPProvision.swift b/ESPProvision/ESPProvision.swift index cf2045b..72ea9cf 100644 --- a/ESPProvision/ESPProvision.swift +++ b/ESPProvision/ESPProvision.swift @@ -21,7 +21,7 @@ import UIKit /// Provision class which exposes the main API for provisioning /// the device with Wifi credentials. -class ESPProvision { +public class ESPProvision { private let session: ESPSession private let transportLayer: ESPCommunicable private let securityLayer: ESPCodeable diff --git a/ESPProvision/Security2/ESPSecurity2.swift b/ESPProvision/Security2/ESPSecurity2.swift index 0924af7..ac7abef 100644 --- a/ESPProvision/Security2/ESPSecurity2.swift +++ b/ESPProvision/Security2/ESPSecurity2.swift @@ -16,7 +16,6 @@ // ESPProvision // -import Curve25519 import Foundation import Security import SwiftProtobuf diff --git a/ESPProvision/Utility/ESPExtensions.swift b/ESPProvision/Utility/ESPExtensions.swift index cd9f3aa..ff0095b 100644 --- a/ESPProvision/Utility/ESPExtensions.swift +++ b/ESPProvision/Utility/ESPExtensions.swift @@ -18,6 +18,7 @@ // import Foundation +import CommonCrypto extension Data { public init(hex: String) { diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSample.xcodeproj/project.pbxproj b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample.xcodeproj/project.pbxproj new file mode 100644 index 0000000..9e97120 --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample.xcodeproj/project.pbxproj @@ -0,0 +1,917 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 56; + objects = { + +/* Begin PBXBuildFile section */ + 23C230D68A2655CB528BC465 /* Pods_ESPProvisionSPMSample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9C40C5367131610C57F28675 /* Pods_ESPProvisionSPMSample.framework */; }; + 4126D620BA3B66AE8F605048 /* Pods_ESPProvisionSPMSampleTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F1DEB9BE81150EC2318EAFC8 /* Pods_ESPProvisionSPMSampleTests.framework */; }; + A5A3BC646067DCBBC708147A /* Pods_ESPProvisionSPMSample_ESPProvisionSPMSampleUITests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1361DAF7A4B6B0AEDCC30409 /* Pods_ESPProvisionSPMSample_ESPProvisionSPMSampleUITests.framework */; }; + F17611872A076D5E004F381D /* ESPProvision in Frameworks */ = {isa = PBXBuildFile; productRef = F17611862A076D5E004F381D /* ESPProvision */; }; + F176118A2A077080004F381D /* GitVersion.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17611892A077080004F381D /* GitVersion.swift */; }; + F17785AA2A058A3700C3AE73 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785A92A058A3700C3AE73 /* AppDelegate.swift */; }; + F17785AC2A058A3700C3AE73 /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785AB2A058A3700C3AE73 /* SceneDelegate.swift */; }; + F17785AE2A058A3700C3AE73 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785AD2A058A3700C3AE73 /* ViewController.swift */; }; + F17785B62A058A3C00C3AE73 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F17785B42A058A3C00C3AE73 /* LaunchScreen.storyboard */; }; + F17785C12A058A3D00C3AE73 /* ESPProvisionSPMSampleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785C02A058A3D00C3AE73 /* ESPProvisionSPMSampleTests.swift */; }; + F17785CB2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785CA2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests.swift */; }; + F17785CD2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785CC2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITestsLaunchTests.swift */; }; + F17785EB2A058A8100C3AE73 /* BLELandingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785DB2A058A8100C3AE73 /* BLELandingViewController.swift */; }; + F17785EC2A058A8100C3AE73 /* BLEDeviceListViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785DC2A058A8100C3AE73 /* BLEDeviceListViewCell.swift */; }; + F17785ED2A058A8100C3AE73 /* ESPAppSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785DE2A058A8100C3AE73 /* ESPAppSettings.swift */; }; + F17785EE2A058A8100C3AE73 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785DF2A058A8100C3AE73 /* SettingsViewController.swift */; }; + F17785EF2A058A8100C3AE73 /* SoftAPLandingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785E12A058A8100C3AE73 /* SoftAPLandingViewController.swift */; }; + F17785F02A058A8100C3AE73 /* ConnectViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785E32A058A8100C3AE73 /* ConnectViewController.swift */; }; + F17785F12A058A8100C3AE73 /* StatusViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785E42A058A8100C3AE73 /* StatusViewController.swift */; }; + F17785F22A058A8100C3AE73 /* ProvisionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785E52A058A8100C3AE73 /* ProvisionViewController.swift */; }; + F17785F32A058A8100C3AE73 /* WifiListTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785E62A058A8100C3AE73 /* WifiListTableViewCell.swift */; }; + F17785F42A058A8100C3AE73 /* DeviceTypeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785E72A058A8100C3AE73 /* DeviceTypeViewController.swift */; }; + F17785F52A058A8100C3AE73 /* ScannerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785E82A058A8100C3AE73 /* ScannerViewController.swift */; }; + F17785F62A058A8100C3AE73 /* Utility.swift in Sources */ = {isa = PBXBuildFile; fileRef = F17785E92A058A8100C3AE73 /* Utility.swift */; }; + F17785F92A058B1F00C3AE73 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F17785F72A058B1F00C3AE73 /* Main.storyboard */; }; + F17785FD2A058BE800C3AE73 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F17785FC2A058BE800C3AE73 /* Assets.xcassets */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + F17785BD2A058A3D00C3AE73 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F177859E2A058A3700C3AE73 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F17785A52A058A3700C3AE73; + remoteInfo = ESPProvisionSPMSample; + }; + F17785C72A058A3D00C3AE73 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = F177859E2A058A3700C3AE73 /* Project object */; + proxyType = 1; + remoteGlobalIDString = F17785A52A058A3700C3AE73; + remoteInfo = ESPProvisionSPMSample; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 036AB4CEA041C085767F4B50 /* Pods-ESPProvisionSPMSampleTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ESPProvisionSPMSampleTests.release.xcconfig"; path = "Target Support Files/Pods-ESPProvisionSPMSampleTests/Pods-ESPProvisionSPMSampleTests.release.xcconfig"; sourceTree = ""; }; + 08E642D02C6C02218B0CC9D4 /* Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.debug.xcconfig"; path = "Target Support Files/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.debug.xcconfig"; sourceTree = ""; }; + 1361DAF7A4B6B0AEDCC30409 /* Pods_ESPProvisionSPMSample_ESPProvisionSPMSampleUITests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ESPProvisionSPMSample_ESPProvisionSPMSampleUITests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 47AE925B80391866611B2494 /* Pods-ESPProvisionSPMSampleTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ESPProvisionSPMSampleTests.debug.xcconfig"; path = "Target Support Files/Pods-ESPProvisionSPMSampleTests/Pods-ESPProvisionSPMSampleTests.debug.xcconfig"; sourceTree = ""; }; + 65AB3C527E92F2C884829ACE /* Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.release.xcconfig"; path = "Target Support Files/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.release.xcconfig"; sourceTree = ""; }; + 9C40C5367131610C57F28675 /* Pods_ESPProvisionSPMSample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ESPProvisionSPMSample.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B8E795D420B2885052F302B7 /* Pods-ESPProvisionSPMSample.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ESPProvisionSPMSample.release.xcconfig"; path = "Target Support Files/Pods-ESPProvisionSPMSample/Pods-ESPProvisionSPMSample.release.xcconfig"; sourceTree = ""; }; + E5548CCC2B0EE1C57AF00FE6 /* Pods-ESPProvisionSPMSample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ESPProvisionSPMSample.debug.xcconfig"; path = "Target Support Files/Pods-ESPProvisionSPMSample/Pods-ESPProvisionSPMSample.debug.xcconfig"; sourceTree = ""; }; + F17611852A075684004F381D /* esp-idf-provisioning-ios */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = "esp-idf-provisioning-ios"; path = ../..; sourceTree = ""; }; + F17611892A077080004F381D /* GitVersion.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = GitVersion.swift; path = ../../ESPProvisionSample/ESPProvisionSample/GitVersion.swift; sourceTree = ""; }; + F176118B2A078542004F381D /* ESPProvisionSPMSample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = ESPProvisionSPMSample.entitlements; sourceTree = ""; }; + F17785A62A058A3700C3AE73 /* ESPProvisionSPMSample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = ESPProvisionSPMSample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + F17785A92A058A3700C3AE73 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + F17785AB2A058A3700C3AE73 /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; }; + F17785AD2A058A3700C3AE73 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + F17785B52A058A3C00C3AE73 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + F17785B72A058A3C00C3AE73 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + F17785BC2A058A3D00C3AE73 /* ESPProvisionSPMSampleTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ESPProvisionSPMSampleTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + F17785C02A058A3D00C3AE73 /* ESPProvisionSPMSampleTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPProvisionSPMSampleTests.swift; sourceTree = ""; }; + F17785C62A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ESPProvisionSPMSampleUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + F17785CA2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPProvisionSPMSampleUITests.swift; sourceTree = ""; }; + F17785CC2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ESPProvisionSPMSampleUITestsLaunchTests.swift; sourceTree = ""; }; + F17785DB2A058A8100C3AE73 /* BLELandingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BLELandingViewController.swift; sourceTree = ""; }; + F17785DC2A058A8100C3AE73 /* BLEDeviceListViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BLEDeviceListViewCell.swift; sourceTree = ""; }; + F17785DE2A058A8100C3AE73 /* ESPAppSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ESPAppSettings.swift; sourceTree = ""; }; + F17785DF2A058A8100C3AE73 /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = ""; }; + F17785E12A058A8100C3AE73 /* SoftAPLandingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SoftAPLandingViewController.swift; sourceTree = ""; }; + F17785E32A058A8100C3AE73 /* ConnectViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConnectViewController.swift; sourceTree = ""; }; + F17785E42A058A8100C3AE73 /* StatusViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusViewController.swift; sourceTree = ""; }; + F17785E52A058A8100C3AE73 /* ProvisionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProvisionViewController.swift; sourceTree = ""; }; + F17785E62A058A8100C3AE73 /* WifiListTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WifiListTableViewCell.swift; sourceTree = ""; }; + F17785E72A058A8100C3AE73 /* DeviceTypeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DeviceTypeViewController.swift; sourceTree = ""; }; + F17785E82A058A8100C3AE73 /* ScannerViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScannerViewController.swift; sourceTree = ""; }; + F17785E92A058A8100C3AE73 /* Utility.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = Utility.swift; path = ../../ESPProvisionSample/ESPProvisionSample/Utility.swift; sourceTree = ""; }; + F17785F82A058B1F00C3AE73 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = ../../ESPProvisionSample/ESPProvisionSample/Base.lproj/Main.storyboard; sourceTree = ""; }; + F17785FC2A058BE800C3AE73 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Assets.xcassets; path = ../../ESPProvisionSample/ESPProvisionSample/Assets.xcassets; sourceTree = ""; }; + F1DEB9BE81150EC2318EAFC8 /* Pods_ESPProvisionSPMSampleTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_ESPProvisionSPMSampleTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + F17785A32A058A3700C3AE73 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + F17611872A076D5E004F381D /* ESPProvision in Frameworks */, + 23C230D68A2655CB528BC465 /* Pods_ESPProvisionSPMSample.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F17785B92A058A3D00C3AE73 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 4126D620BA3B66AE8F605048 /* Pods_ESPProvisionSPMSampleTests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F17785C32A058A3D00C3AE73 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + A5A3BC646067DCBBC708147A /* Pods_ESPProvisionSPMSample_ESPProvisionSPMSampleUITests.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4CE2E4D81A37A6FFEE54B05A /* Pods */ = { + isa = PBXGroup; + children = ( + E5548CCC2B0EE1C57AF00FE6 /* Pods-ESPProvisionSPMSample.debug.xcconfig */, + B8E795D420B2885052F302B7 /* Pods-ESPProvisionSPMSample.release.xcconfig */, + 08E642D02C6C02218B0CC9D4 /* Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.debug.xcconfig */, + 65AB3C527E92F2C884829ACE /* Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.release.xcconfig */, + 47AE925B80391866611B2494 /* Pods-ESPProvisionSPMSampleTests.debug.xcconfig */, + 036AB4CEA041C085767F4B50 /* Pods-ESPProvisionSPMSampleTests.release.xcconfig */, + ); + path = Pods; + sourceTree = ""; + }; + F1659D582A0597BE004C393B /* Frameworks */ = { + isa = PBXGroup; + children = ( + 9C40C5367131610C57F28675 /* Pods_ESPProvisionSPMSample.framework */, + 1361DAF7A4B6B0AEDCC30409 /* Pods_ESPProvisionSPMSample_ESPProvisionSPMSampleUITests.framework */, + F1DEB9BE81150EC2318EAFC8 /* Pods_ESPProvisionSPMSampleTests.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + F17611842A075683004F381D /* Packages */ = { + isa = PBXGroup; + children = ( + F17611852A075684004F381D /* esp-idf-provisioning-ios */, + ); + name = Packages; + sourceTree = ""; + }; + F177859D2A058A3700C3AE73 = { + isa = PBXGroup; + children = ( + F17611842A075683004F381D /* Packages */, + F17785A82A058A3700C3AE73 /* ESPProvisionSPMSample */, + F17785BF2A058A3D00C3AE73 /* ESPProvisionSPMSampleTests */, + F17785C92A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests */, + F17785A72A058A3700C3AE73 /* Products */, + F1659D582A0597BE004C393B /* Frameworks */, + 4CE2E4D81A37A6FFEE54B05A /* Pods */, + ); + sourceTree = ""; + }; + F17785A72A058A3700C3AE73 /* Products */ = { + isa = PBXGroup; + children = ( + F17785A62A058A3700C3AE73 /* ESPProvisionSPMSample.app */, + F17785BC2A058A3D00C3AE73 /* ESPProvisionSPMSampleTests.xctest */, + F17785C62A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + F17785A82A058A3700C3AE73 /* ESPProvisionSPMSample */ = { + isa = PBXGroup; + children = ( + F176118B2A078542004F381D /* ESPProvisionSPMSample.entitlements */, + F17611892A077080004F381D /* GitVersion.swift */, + F17785FC2A058BE800C3AE73 /* Assets.xcassets */, + F17785F72A058B1F00C3AE73 /* Main.storyboard */, + F17785DA2A058A8100C3AE73 /* BLE */, + F17785E22A058A8100C3AE73 /* Provision */, + F17785DD2A058A8100C3AE73 /* Settings */, + F17785E02A058A8100C3AE73 /* SoftAP */, + F17785E92A058A8100C3AE73 /* Utility.swift */, + F17785A92A058A3700C3AE73 /* AppDelegate.swift */, + F17785AB2A058A3700C3AE73 /* SceneDelegate.swift */, + F17785AD2A058A3700C3AE73 /* ViewController.swift */, + F17785B42A058A3C00C3AE73 /* LaunchScreen.storyboard */, + F17785B72A058A3C00C3AE73 /* Info.plist */, + ); + path = ESPProvisionSPMSample; + sourceTree = ""; + }; + F17785BF2A058A3D00C3AE73 /* ESPProvisionSPMSampleTests */ = { + isa = PBXGroup; + children = ( + F17785C02A058A3D00C3AE73 /* ESPProvisionSPMSampleTests.swift */, + ); + path = ESPProvisionSPMSampleTests; + sourceTree = ""; + }; + F17785C92A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests */ = { + isa = PBXGroup; + children = ( + F17785CA2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests.swift */, + F17785CC2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITestsLaunchTests.swift */, + ); + path = ESPProvisionSPMSampleUITests; + sourceTree = ""; + }; + F17785DA2A058A8100C3AE73 /* BLE */ = { + isa = PBXGroup; + children = ( + F17785DB2A058A8100C3AE73 /* BLELandingViewController.swift */, + F17785DC2A058A8100C3AE73 /* BLEDeviceListViewCell.swift */, + ); + name = BLE; + path = ../../ESPProvisionSample/ESPProvisionSample/BLE; + sourceTree = ""; + }; + F17785DD2A058A8100C3AE73 /* Settings */ = { + isa = PBXGroup; + children = ( + F17785DE2A058A8100C3AE73 /* ESPAppSettings.swift */, + F17785DF2A058A8100C3AE73 /* SettingsViewController.swift */, + ); + name = Settings; + path = ../../ESPProvisionSample/ESPProvisionSample/Settings; + sourceTree = ""; + }; + F17785E02A058A8100C3AE73 /* SoftAP */ = { + isa = PBXGroup; + children = ( + F17785E12A058A8100C3AE73 /* SoftAPLandingViewController.swift */, + ); + name = SoftAP; + path = ../../ESPProvisionSample/ESPProvisionSample/SoftAP; + sourceTree = ""; + }; + F17785E22A058A8100C3AE73 /* Provision */ = { + isa = PBXGroup; + children = ( + F17785E32A058A8100C3AE73 /* ConnectViewController.swift */, + F17785E42A058A8100C3AE73 /* StatusViewController.swift */, + F17785E52A058A8100C3AE73 /* ProvisionViewController.swift */, + F17785E62A058A8100C3AE73 /* WifiListTableViewCell.swift */, + F17785E72A058A8100C3AE73 /* DeviceTypeViewController.swift */, + F17785E82A058A8100C3AE73 /* ScannerViewController.swift */, + ); + name = Provision; + path = ../../ESPProvisionSample/ESPProvisionSample/Provision; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + F17785A52A058A3700C3AE73 /* ESPProvisionSPMSample */ = { + isa = PBXNativeTarget; + buildConfigurationList = F17785D02A058A3D00C3AE73 /* Build configuration list for PBXNativeTarget "ESPProvisionSPMSample" */; + buildPhases = ( + DB4DED6B99DB657F267DF6FB /* [CP] Check Pods Manifest.lock */, + F17785A22A058A3700C3AE73 /* Sources */, + F17785A32A058A3700C3AE73 /* Frameworks */, + F17785A42A058A3700C3AE73 /* Resources */, + F17611882A076F4B004F381D /* ShellScript */, + 6F40B16EB8DA327AC110D356 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = ESPProvisionSPMSample; + packageProductDependencies = ( + F17611862A076D5E004F381D /* ESPProvision */, + ); + productName = ESPProvisionSPMSample; + productReference = F17785A62A058A3700C3AE73 /* ESPProvisionSPMSample.app */; + productType = "com.apple.product-type.application"; + }; + F17785BB2A058A3D00C3AE73 /* ESPProvisionSPMSampleTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F17785D32A058A3D00C3AE73 /* Build configuration list for PBXNativeTarget "ESPProvisionSPMSampleTests" */; + buildPhases = ( + 28D221EA1DCDB63881B20C30 /* [CP] Check Pods Manifest.lock */, + F17785B82A058A3D00C3AE73 /* Sources */, + F17785B92A058A3D00C3AE73 /* Frameworks */, + F17785BA2A058A3D00C3AE73 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + F17785BE2A058A3D00C3AE73 /* PBXTargetDependency */, + ); + name = ESPProvisionSPMSampleTests; + productName = ESPProvisionSPMSampleTests; + productReference = F17785BC2A058A3D00C3AE73 /* ESPProvisionSPMSampleTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; + F17785C52A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests */ = { + isa = PBXNativeTarget; + buildConfigurationList = F17785D62A058A3D00C3AE73 /* Build configuration list for PBXNativeTarget "ESPProvisionSPMSampleUITests" */; + buildPhases = ( + 9B1A2C711B226ECA1B669ED1 /* [CP] Check Pods Manifest.lock */, + F17785C22A058A3D00C3AE73 /* Sources */, + F17785C32A058A3D00C3AE73 /* Frameworks */, + F17785C42A058A3D00C3AE73 /* Resources */, + 2007EF31F6F46742A863B647 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + F17785C82A058A3D00C3AE73 /* PBXTargetDependency */, + ); + name = ESPProvisionSPMSampleUITests; + productName = ESPProvisionSPMSampleUITests; + productReference = F17785C62A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests.xctest */; + productType = "com.apple.product-type.bundle.ui-testing"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + F177859E2A058A3700C3AE73 /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1430; + LastUpgradeCheck = 1430; + TargetAttributes = { + F17785A52A058A3700C3AE73 = { + CreatedOnToolsVersion = 14.3; + }; + F17785BB2A058A3D00C3AE73 = { + CreatedOnToolsVersion = 14.3; + TestTargetID = F17785A52A058A3700C3AE73; + }; + F17785C52A058A3D00C3AE73 = { + CreatedOnToolsVersion = 14.3; + TestTargetID = F17785A52A058A3700C3AE73; + }; + }; + }; + buildConfigurationList = F17785A12A058A3700C3AE73 /* Build configuration list for PBXProject "ESPProvisionSPMSample" */; + compatibilityVersion = "Xcode 14.0"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = F177859D2A058A3700C3AE73; + productRefGroup = F17785A72A058A3700C3AE73 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + F17785A52A058A3700C3AE73 /* ESPProvisionSPMSample */, + F17785BB2A058A3D00C3AE73 /* ESPProvisionSPMSampleTests */, + F17785C52A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + F17785A42A058A3700C3AE73 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F17785F92A058B1F00C3AE73 /* Main.storyboard in Resources */, + F17785B62A058A3C00C3AE73 /* LaunchScreen.storyboard in Resources */, + F17785FD2A058BE800C3AE73 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F17785BA2A058A3D00C3AE73 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F17785C42A058A3D00C3AE73 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 2007EF31F6F46742A863B647 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 28D221EA1DCDB63881B20C30 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ESPProvisionSPMSampleTests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 6F40B16EB8DA327AC110D356 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ESPProvisionSPMSample/Pods-ESPProvisionSPMSample-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-ESPProvisionSPMSample/Pods-ESPProvisionSPMSample-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-ESPProvisionSPMSample/Pods-ESPProvisionSPMSample-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; + 9B1A2C711B226ECA1B669ED1 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + DB4DED6B99DB657F267DF6FB /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-ESPProvisionSPMSample-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + F17611882A076F4B004F381D /* ShellScript */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n# gitversioning.sh\n# \n#\n# Created by sig on 28.10.13.\n#\n\nversion=$(git rev-parse --verify HEAD | cut -c 1-7)\ncurdate=$(date +\"%d.%m.%y\")\n\nfilesource=\"\\n let espGitVersion = \\\"$version\\\"\\n\\n\"\n\ntouch $SRCROOT/ESPProvisionSample/GitVersion.swift\necho \"$filesource\" > $SRCROOT/../ESPProvisionSample/GitVersion.swift\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + F17785A22A058A3700C3AE73 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F17785F22A058A8100C3AE73 /* ProvisionViewController.swift in Sources */, + F17785EC2A058A8100C3AE73 /* BLEDeviceListViewCell.swift in Sources */, + F17785EF2A058A8100C3AE73 /* SoftAPLandingViewController.swift in Sources */, + F17785EB2A058A8100C3AE73 /* BLELandingViewController.swift in Sources */, + F17785AE2A058A3700C3AE73 /* ViewController.swift in Sources */, + F176118A2A077080004F381D /* GitVersion.swift in Sources */, + F17785ED2A058A8100C3AE73 /* ESPAppSettings.swift in Sources */, + F17785F42A058A8100C3AE73 /* DeviceTypeViewController.swift in Sources */, + F17785F02A058A8100C3AE73 /* ConnectViewController.swift in Sources */, + F17785AA2A058A3700C3AE73 /* AppDelegate.swift in Sources */, + F17785AC2A058A3700C3AE73 /* SceneDelegate.swift in Sources */, + F17785F32A058A8100C3AE73 /* WifiListTableViewCell.swift in Sources */, + F17785F62A058A8100C3AE73 /* Utility.swift in Sources */, + F17785F12A058A8100C3AE73 /* StatusViewController.swift in Sources */, + F17785F52A058A8100C3AE73 /* ScannerViewController.swift in Sources */, + F17785EE2A058A8100C3AE73 /* SettingsViewController.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F17785B82A058A3D00C3AE73 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F17785C12A058A3D00C3AE73 /* ESPProvisionSPMSampleTests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + F17785C22A058A3D00C3AE73 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F17785CD2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITestsLaunchTests.swift in Sources */, + F17785CB2A058A3D00C3AE73 /* ESPProvisionSPMSampleUITests.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + F17785BE2A058A3D00C3AE73 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F17785A52A058A3700C3AE73 /* ESPProvisionSPMSample */; + targetProxy = F17785BD2A058A3D00C3AE73 /* PBXContainerItemProxy */; + }; + F17785C82A058A3D00C3AE73 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = F17785A52A058A3700C3AE73 /* ESPProvisionSPMSample */; + targetProxy = F17785C72A058A3D00C3AE73 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + F17785B42A058A3C00C3AE73 /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + F17785B52A058A3C00C3AE73 /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; + F17785F72A058B1F00C3AE73 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + F17785F82A058B1F00C3AE73 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + F17785CE2A058A3D00C3AE73 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + F17785CF2A058A3D00C3AE73 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + F17785D12A058A3D00C3AE73 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E5548CCC2B0EE1C57AF00FE6 /* Pods-ESPProvisionSPMSample.debug.xcconfig */; + buildSettings = { + APP_DISPLAY_NAME = "ESP Prov"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = ESPProvisionSPMSample/ESPProvisionSPMSample.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QWXF6GB4AV; + ESP_ALLOW_PREFIX_SEARCH = YES; + ESP_ALLOW_QR_CODE_SCAN = YES; + ESP_DEVICE_TYPE = Both; + ESP_DEVICE_USERNAME = wifiprov; + ESP_SECURITY_MODE = Secure; + ESP_SETTINGS_ENABLED = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ESPProvisionSPMSample/Info.plist; + INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Connect with BLE Compatible devices for Provisioning"; + INFOPLIST_KEY_NSBluetoothPeripheralUsageDescription = "Connect with BLE Compatible devices for Provisioning"; + INFOPLIST_KEY_NSCameraUsageDescription = "Reading QR code"; + INFOPLIST_KEY_NSLocalNetworkUsageDescription = "App requires access to local network in order to connect to SoftAP devices."; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "App requires your location permission in order to get current WiFi network ssid"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.espressif.ESPProvisionSPMSample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + F17785D22A058A3D00C3AE73 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B8E795D420B2885052F302B7 /* Pods-ESPProvisionSPMSample.release.xcconfig */; + buildSettings = { + APP_DISPLAY_NAME = "ESP Prov"; + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = ESPProvisionSPMSample/ESPProvisionSPMSample.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QWXF6GB4AV; + ESP_ALLOW_PREFIX_SEARCH = YES; + ESP_ALLOW_QR_CODE_SCAN = YES; + ESP_DEVICE_TYPE = Both; + ESP_DEVICE_USERNAME = wifiprov; + ESP_SECURITY_MODE = Secure; + ESP_SETTINGS_ENABLED = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = ESPProvisionSPMSample/Info.plist; + INFOPLIST_KEY_NSBluetoothAlwaysUsageDescription = "Connect with BLE Compatible devices for Provisioning"; + INFOPLIST_KEY_NSBluetoothPeripheralUsageDescription = "Connect with BLE Compatible devices for Provisioning"; + INFOPLIST_KEY_NSCameraUsageDescription = "Reading QR code"; + INFOPLIST_KEY_NSLocalNetworkUsageDescription = "App requires access to local network in order to connect to SoftAP devices."; + INFOPLIST_KEY_NSLocationWhenInUseUsageDescription = "App requires your location permission in order to get current WiFi network ssid"; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen; + INFOPLIST_KEY_UIMainStoryboardFile = Main; + INFOPLIST_KEY_UISupportedInterfaceOrientations = UIInterfaceOrientationPortrait; + IPHONEOS_DEPLOYMENT_TARGET = 13.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.espressif.ESPProvisionSPMSample; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; + F17785D42A058A3D00C3AE73 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 47AE925B80391866611B2494 /* Pods-ESPProvisionSPMSampleTests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QWXF6GB4AV; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.espressif.ESPProvisionSPMSampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ESPProvisionSPMSample.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/ESPProvisionSPMSample"; + }; + name = Debug; + }; + F17785D52A058A3D00C3AE73 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 036AB4CEA041C085767F4B50 /* Pods-ESPProvisionSPMSampleTests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QWXF6GB4AV; + GENERATE_INFOPLIST_FILE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 16.4; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.espressif.ESPProvisionSPMSampleTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/ESPProvisionSPMSample.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/ESPProvisionSPMSample"; + }; + name = Release; + }; + F17785D72A058A3D00C3AE73 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 08E642D02C6C02218B0CC9D4 /* Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.debug.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QWXF6GB4AV; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.espressif.ESPProvisionSPMSampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = ESPProvisionSPMSample; + }; + name = Debug; + }; + F17785D82A058A3D00C3AE73 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 65AB3C527E92F2C884829ACE /* Pods-ESPProvisionSPMSample-ESPProvisionSPMSampleUITests.release.xcconfig */; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = QWXF6GB4AV; + GENERATE_INFOPLIST_FILE = YES; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = com.espressif.ESPProvisionSPMSampleUITests; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_EMIT_LOC_STRINGS = NO; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + TEST_TARGET_NAME = ESPProvisionSPMSample; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + F17785A12A058A3700C3AE73 /* Build configuration list for PBXProject "ESPProvisionSPMSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F17785CE2A058A3D00C3AE73 /* Debug */, + F17785CF2A058A3D00C3AE73 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F17785D02A058A3D00C3AE73 /* Build configuration list for PBXNativeTarget "ESPProvisionSPMSample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F17785D12A058A3D00C3AE73 /* Debug */, + F17785D22A058A3D00C3AE73 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F17785D32A058A3D00C3AE73 /* Build configuration list for PBXNativeTarget "ESPProvisionSPMSampleTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F17785D42A058A3D00C3AE73 /* Debug */, + F17785D52A058A3D00C3AE73 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + F17785D62A058A3D00C3AE73 /* Build configuration list for PBXNativeTarget "ESPProvisionSPMSampleUITests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + F17785D72A058A3D00C3AE73 /* Debug */, + F17785D82A058A3D00C3AE73 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + F17611862A076D5E004F381D /* ESPProvision */ = { + isa = XCSwiftPackageProductDependency; + productName = ESPProvision; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = F177859E2A058A3700C3AE73 /* Project object */; +} diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/AppDelegate.swift b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/AppDelegate.swift new file mode 100644 index 0000000..def386b --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/AppDelegate.swift @@ -0,0 +1,46 @@ +// Copyright 2023 Espressif Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// AppDelegate.swift +// ESPProvisionSPMSample +// +import UIKit + +@main +class AppDelegate: UIResponder, UIApplicationDelegate { + + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + return true + } + + // MARK: UISceneSession Lifecycle + + func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration { + // Called when a new scene session is being created. + // Use this method to select a configuration to create the new scene with. + return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role) + } + + func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) { + // Called when the user discards a scene session. + // If any sessions were discarded while the application was not running, this will be called shortly after application:didFinishLaunchingWithOptions. + // Use this method to release any resources that were specific to the discarded scenes, as they will not return. + } + + +} + diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/Base.lproj/LaunchScreen.storyboard b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/Base.lproj/LaunchScreen.storyboard new file mode 100644 index 0000000..865e932 --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/Base.lproj/LaunchScreen.storyboard @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/ESPProvisionSPMSample.entitlements b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/ESPProvisionSPMSample.entitlements new file mode 100644 index 0000000..7021e63 --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/ESPProvisionSPMSample.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.developer.networking.HotspotConfiguration + + com.apple.developer.networking.wifi-info + + + diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/Info.plist b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/Info.plist new file mode 100644 index 0000000..f27b0b9 --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/Info.plist @@ -0,0 +1,46 @@ + + + + + UIStatusBarStyle + UIStatusBarStyleLightContent + UIUserInterfaceStyle + Light + UIRequiresFullScreen + + ESP Application Setting + + ESP Allow Prefix Search + $(ESP_ALLOW_PREFIX_SEARCH) + ESP Allow QR Code Scan + $(ESP_ALLOW_QR_CODE_SCAN) + ESP Device Type + $(ESP_DEVICE_TYPE) + ESP Device Username + $(ESP_DEVICE_USERNAME) + ESP Enable Setting + $(ESP_SETTINGS_ENABLED) + ESP Securtiy Mode + $(ESP_SECURITY_MODE) + + UIApplicationSceneManifest + + UIApplicationSupportsMultipleScenes + + UISceneConfigurations + + UIWindowSceneSessionRoleApplication + + + UISceneConfigurationName + Default Configuration + UISceneDelegateClassName + $(PRODUCT_MODULE_NAME).SceneDelegate + UISceneStoryboardFile + Main + + + + + + diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/SceneDelegate.swift b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/SceneDelegate.swift new file mode 100644 index 0000000..a82716b --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/SceneDelegate.swift @@ -0,0 +1,63 @@ +// Copyright 2023 Espressif Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// SceneDelegate.swift +// ESPProvisionSPMSample +// + +import UIKit + +class SceneDelegate: UIResponder, UIWindowSceneDelegate { + + var window: UIWindow? + + + func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { + // Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`. + // If using a storyboard, the `window` property will automatically be initialized and attached to the scene. + // This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead). + guard let _ = (scene as? UIWindowScene) else { return } + } + + func sceneDidDisconnect(_ scene: UIScene) { + // Called as the scene is being released by the system. + // This occurs shortly after the scene enters the background, or when its session is discarded. + // Release any resources associated with this scene that can be re-created the next time the scene connects. + // The scene may re-connect later, as its session was not necessarily discarded (see `application:didDiscardSceneSessions` instead). + } + + func sceneDidBecomeActive(_ scene: UIScene) { + // Called when the scene has moved from an inactive state to an active state. + // Use this method to restart any tasks that were paused (or not yet started) when the scene was inactive. + } + + func sceneWillResignActive(_ scene: UIScene) { + // Called when the scene will move from an active state to an inactive state. + // This may occur due to temporary interruptions (ex. an incoming phone call). + } + + func sceneWillEnterForeground(_ scene: UIScene) { + // Called as the scene transitions from the background to the foreground. + // Use this method to undo the changes made on entering the background. + } + + func sceneDidEnterBackground(_ scene: UIScene) { + // Called as the scene transitions from the foreground to the background. + // Use this method to save data, release shared resources, and store enough scene-specific state information + // to restore the scene back to its current state. + } + + +} + diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/ViewController.swift b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/ViewController.swift new file mode 100644 index 0000000..f458b12 --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSample/ViewController.swift @@ -0,0 +1,69 @@ +// Copyright 2023 Espressif Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ViewController.swift +// ESPProvisionSPMSample +// + +import UIKit +class ViewController: UIViewController { + + let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String ?? "1.0.0" + + @IBOutlet weak var centerImage: UIImageView! + @IBOutlet weak var appVersionLabel: UILabel! + @IBOutlet weak var settingsButton: UIButton! + override func viewDidLoad() { + super.viewDidLoad() + navigationController?.setNavigationBarHidden(true, animated: false) + appVersionLabel.text = "App Version - v" + appVersion + " (\(espGitVersion))" + } + + override func viewWillAppear(_ animated: Bool) { + if Utility.shared.espAppSettings.appSettingsEnabled { + settingsButton.isHidden = false + } else { + settingsButton.isHidden = true + } + switch Utility.shared.espAppSettings.deviceType { + case .both: + centerImage.image = UIImage(named: "main_logo") + case .ble: + centerImage.image = UIImage(named: "ble_main_logo") + case .softAp: + centerImage.image = UIImage(named: "softap_main_logo") + } + + } + + @IBAction func addNewDevice(_ sender: Any) { + if Utility.shared.espAppSettings.appAllowsQrCodeScan { + let scannerVC = self.storyboard?.instantiateViewController(withIdentifier: "scannerVC") as! ScannerViewController + navigationController?.pushViewController(scannerVC, animated: false) + } else { + switch Utility.shared.espAppSettings.deviceType { + case .both: + let deviceTypeVC = self.storyboard?.instantiateViewController(withIdentifier: "deviceTypeVC") as! DeviceTypeViewController + navigationController?.pushViewController(deviceTypeVC, animated: false) + case .ble: + let bleLandingVC = self.storyboard?.instantiateViewController(withIdentifier: "bleLandingVC") as! BLELandingViewController + navigationController?.pushViewController(bleLandingVC, animated: false) + case .softAp: + let softAPLandingVC = self.storyboard?.instantiateViewController(withIdentifier: "softAPLandingVC") as! SoftAPLandingViewController + navigationController?.pushViewController(softAPLandingVC, animated: false) + } + } + } +} + diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleTests/ESPProvisionSPMSampleTests.swift b/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleTests/ESPProvisionSPMSampleTests.swift new file mode 100644 index 0000000..20344d9 --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleTests/ESPProvisionSPMSampleTests.swift @@ -0,0 +1,47 @@ +// Copyright 2023 Espressif Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ESPProvisionSPMSampleTests.swift +// ESPProvisionSPMSampleTests +// + +import XCTest +@testable import ESPProvisionSPMSample + +final class ESPProvisionSPMSampleTests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // This is an example of a functional test case. + // Use XCTAssert and related functions to verify your tests produce the correct results. + // Any test you write for XCTest can be annotated as throws and async. + // Mark your test throws to produce an unexpected failure when your test encounters an uncaught error. + // Mark your test async to allow awaiting for asynchronous code to complete. Check the results with assertions afterwards. + } + + func testPerformanceExample() throws { + // This is an example of a performance test case. + self.measure { + // Put the code you want to measure the time of here. + } + } + +} diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleUITests/ESPProvisionSPMSampleUITests.swift b/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleUITests/ESPProvisionSPMSampleUITests.swift new file mode 100644 index 0000000..9e51361 --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleUITests/ESPProvisionSPMSampleUITests.swift @@ -0,0 +1,52 @@ +// Copyright 2023 Espressif Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ESPProvisionSPMSampleUITests.swift +// ESPProvisionSPMSampleUITests +// + +import XCTest + +final class ESPProvisionSPMSampleUITests: XCTestCase { + + override func setUpWithError() throws { + // Put setup code here. This method is called before the invocation of each test method in the class. + + // In UI tests it is usually best to stop immediately when a failure occurs. + continueAfterFailure = false + + // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this. + } + + override func tearDownWithError() throws { + // Put teardown code here. This method is called after the invocation of each test method in the class. + } + + func testExample() throws { + // UI tests must launch the application that they test. + let app = XCUIApplication() + app.launch() + + // Use XCTAssert and related functions to verify your tests produce the correct results. + } + + func testLaunchPerformance() throws { + if #available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 7.0, *) { + // This measures how long it takes to launch your application. + measure(metrics: [XCTApplicationLaunchMetric()]) { + XCUIApplication().launch() + } + } + } +} diff --git a/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleUITests/ESPProvisionSPMSampleUITestsLaunchTests.swift b/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleUITests/ESPProvisionSPMSampleUITestsLaunchTests.swift new file mode 100644 index 0000000..37eeaa6 --- /dev/null +++ b/Example/ESPProvisionSPMSample/ESPProvisionSPMSampleUITests/ESPProvisionSPMSampleUITestsLaunchTests.swift @@ -0,0 +1,43 @@ +// Copyright 2023 Espressif Systems +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// ESPProvisionSPMSampleUITestsLaunchTests.swift +// ESPProvisionSPMSampleUITests +// + +import XCTest + +final class ESPProvisionSPMSampleUITestsLaunchTests: XCTestCase { + + override class var runsForEachTargetApplicationUIConfiguration: Bool { + true + } + + override func setUpWithError() throws { + continueAfterFailure = false + } + + func testLaunch() throws { + let app = XCUIApplication() + app.launch() + + // Insert steps here to perform after app launch but before taking a screenshot, + // such as logging into a test account or navigating somewhere in the app + + let attachment = XCTAttachment(screenshot: app.screenshot()) + attachment.name = "Launch Screen" + attachment.lifetime = .keepAlways + add(attachment) + } +} diff --git a/Example/ESPProvisionSPMSample/Podfile b/Example/ESPProvisionSPMSample/Podfile new file mode 100644 index 0000000..370c32b --- /dev/null +++ b/Example/ESPProvisionSPMSample/Podfile @@ -0,0 +1,30 @@ +# Uncomment the next line to define a global platform for your project +# platform :ios, '9.0' + +target 'ESPProvisionSPMSample' do + # Comment the next line if you don't want to use dynamic frameworks + use_frameworks! + + # Pods for ESPProvisionSPMSample + pod 'MBProgressHUD' + + target 'ESPProvisionSPMSampleTests' do + inherit! :search_paths + # Pods for testing + end + + target 'ESPProvisionSPMSampleUITests' do + # Pods for testing + end + +end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['ENABLE_BITCODE'] = 'YES' + config.build_settings['ARCHS'] = 'arm64' + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' + end + end +end diff --git a/Example/ESPProvisionSample/ESPProvisionSample/Provision/ConnectViewController.swift b/Example/ESPProvisionSample/ESPProvisionSample/Provision/ConnectViewController.swift index bfee625..7fb48fa 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample/Provision/ConnectViewController.swift +++ b/Example/ESPProvisionSample/ESPProvisionSample/Provision/ConnectViewController.swift @@ -102,7 +102,7 @@ extension ConnectViewController: ESPDeviceConnectionDelegate { completionHandler(pop) } - func getUsername(forDevice: ESPProvision.ESPDevice, completionHandler: @escaping (String?) -> Void) { + func getUsername(forDevice: ESPDevice, completionHandler: @escaping (String?) -> Void) { completionHandler(Utility.shared.espAppSettings.username) } } diff --git a/Example/ESPProvisionSample/ESPProvisionSample/Provision/ProvisionViewController.swift b/Example/ESPProvisionSample/ESPProvisionSample/Provision/ProvisionViewController.swift index 5f74657..3c6be37 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample/Provision/ProvisionViewController.swift +++ b/Example/ESPProvisionSample/ESPProvisionSample/Provision/ProvisionViewController.swift @@ -17,10 +17,10 @@ // import CoreBluetooth -import ESPProvision import Foundation import MBProgressHUD import UIKit +import ESPProvision // Class that shows Wi-Fi network list and takes Wi-Fi credentials from user. class ProvisionViewController: UIViewController { diff --git a/Example/ESPProvisionSample/ESPProvisionSample/Provision/ScannerViewController.swift b/Example/ESPProvisionSample/ESPProvisionSample/Provision/ScannerViewController.swift index 3b4d129..52a9a98 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample/Provision/ScannerViewController.swift +++ b/Example/ESPProvisionSample/ESPProvisionSample/Provision/ScannerViewController.swift @@ -17,11 +17,11 @@ // import AVFoundation -import ESPProvision import NetworkExtension import SystemConfiguration.CaptiveNetwork import UIKit import CoreLocation +import ESPProvision // Class that manages QRCode scanning and provides way to switch to manual provisioning. class ScannerViewController: UIViewController, AVCaptureMetadataOutputObjectsDelegate { @@ -210,7 +210,7 @@ extension ScannerViewController: ESPDeviceConnectionDelegate { completionHandler("") } - func getUsername(forDevice: ESPProvision.ESPDevice, completionHandler: @escaping (String?) -> Void) { + func getUsername(forDevice: ESPDevice, completionHandler: @escaping (String?) -> Void) { completionHandler(Utility.shared.espAppSettings.username) } } diff --git a/Example/ESPProvisionSample/ESPProvisionSample/Settings/SettingsViewController.swift b/Example/ESPProvisionSample/ESPProvisionSample/Settings/SettingsViewController.swift index f584ee8..5be2029 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample/Settings/SettingsViewController.swift +++ b/Example/ESPProvisionSample/ESPProvisionSample/Settings/SettingsViewController.swift @@ -17,6 +17,7 @@ // import UIKit +import ESPProvision // Class to change and manage provisioning settings class SettingsViewController: UIViewController { diff --git a/Example/ESPProvisionSample/ESPProvisionSample/SoftAP/SoftAPLandingViewController.swift b/Example/ESPProvisionSample/ESPProvisionSample/SoftAP/SoftAPLandingViewController.swift index ca020e2..7fa3c34 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample/SoftAP/SoftAPLandingViewController.swift +++ b/Example/ESPProvisionSample/ESPProvisionSample/SoftAP/SoftAPLandingViewController.swift @@ -18,7 +18,6 @@ import ESPProvision import Foundation -import MBProgressHUD import SystemConfiguration.CaptiveNetwork import UIKit import CoreLocation diff --git a/Example/ESPProvisionSample/ESPProvisionSample/Utility.swift b/Example/ESPProvisionSample/ESPProvisionSample/Utility.swift index 05e490d..68d9915 100644 --- a/Example/ESPProvisionSample/ESPProvisionSample/Utility.swift +++ b/Example/ESPProvisionSample/ESPProvisionSample/Utility.swift @@ -18,6 +18,7 @@ import Foundation import MBProgressHUD import ESPProvision +import UIKit enum DeviceType: Int, CaseIterable { case both = 0 diff --git a/Package.swift b/Package.swift new file mode 100644 index 0000000..878dee3 --- /dev/null +++ b/Package.swift @@ -0,0 +1,33 @@ +// swift-tools-version: 5.4 +// The swift-tools-version declares the minimum version of Swift required to build this package. +import PackageDescription + +let package = Package( + name: "ESPProvision", + platforms: [ + .iOS(.v13) + ], + products: [ + // Products define the executables and libraries a package produces, and make them visible to other packages. + .library( + name: "ESPProvision", + targets: ["ESPProvision"]), + ], + dependencies: [ + .package( + name: "SwiftProtobuf", + url: "https://github.com/apple/swift-protobuf.git", + "1.20.3" ..< "2.0.0" + ) + ], + targets: [ + // Targets are the basic building blocks of a package. A target can define a module or a test suite. + // Targets can depend on other targets in this package, and on products in packages this package depends on. + .target( + name: "ESPProvision", + dependencies: ["SwiftProtobuf"], + path: "ESPProvision", + exclude: ["Example","Tests","Pods"] + ), + ] +) diff --git a/Podfile b/Podfile index 338e43b..2e6776f 100644 --- a/Podfile +++ b/Podfile @@ -7,6 +7,13 @@ target 'ESPProvision' do # Pods for ESPProvision pod 'SwiftProtobuf', '~> 1.0' - pod 'Curve25519', '~> 1.1.0' end + +post_install do |installer| + installer.pods_project.targets.each do |target| + target.build_configurations.each do |config| + config.build_settings['IPHONEOS_DEPLOYMENT_TARGET'] = '13.0' + end + end +end diff --git a/README.md b/README.md index 239577d..d11573e 100644 --- a/README.md +++ b/README.md @@ -46,6 +46,24 @@ pod 'ESPProvision' ``` +### Swift Package Manager + +The [Swift Package Manager](https://swift.org/package-manager/) is a tool for automating the distribution of Swift code and is integrated into the `swift` compiler. + +Once you have your Swift package set up, adding ESPProvision as a dependency is as easy as adding it to the `dependencies` value of your `Package.swift`. + +```swift +dependencies: [ + .package(url: "https://github.com/espressif/esp-idf-provisioning-ios.git", from: "2.1.1") +] +``` + +### ...using Xcode + +If you are using Xcode, then you should add this SwiftPM package as dependency of your xcode project: + [Apple Docs](https://developer.apple.com/documentation/swift_packages/adding_package_dependencies_to_your_app) + + ## Using ESPProvision ## Introduction