Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unwrapping optionals fixed #413

Merged
merged 2 commits into from
Apr 29, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,9 @@ extension BaseDFUExecutor {

func error(_ error: DFUError, didOccurWithMessage message: String) {
if error == .bluetoothDisabled {
delegate{ $0.dfuError(.bluetoothDisabled, didOccurWithMessage: message) }
delegate {
$0.dfuError(.bluetoothDisabled, didOccurWithMessage: message)
}
// Release the cyclic reference.
peripheral.destroy()
return
Expand Down
82 changes: 36 additions & 46 deletions iOSDFULibrary/Classes/Implementation/GenericDFU/DFUPeripheral.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,8 +101,8 @@ internal class BaseDFUPeripheral<TD : BasePeripheralDelegate> : NSObject, BaseDF
internal let experimentalButtonlessServiceInSecureDfuEnabled: Bool
/// Default error callback.
internal var defaultErrorCallback: ErrorCallback {
return { (error, message) in
self.delegate?.error(error, didOccurWithMessage: message)
return { [weak self] error, message in
self?.delegate?.error(error, didOccurWithMessage: message)
}
}

Expand Down Expand Up @@ -155,23 +155,23 @@ internal class BaseDFUPeripheral<TD : BasePeripheralDelegate> : NSObject, BaseDF
}
self.peripheral = peripheral

if peripheral.state != .connected {
connect()
} else {
switch peripheral.state {
case .connected:
let name = peripheral.name ?? "Unknown device"
logger.i("Connected to \(name)")

let dfuService = findDfuService(in: peripheral.services)
if dfuService == nil {
if let dfuService = findDfuService(in: peripheral.services) {
// A DFU service was found, congratulations!
logger.i("Services discovered")
peripheralDidDiscoverDfuService(dfuService)
} else {
// DFU service has not been found, but it doesn't matter it's not
// there. Perhaps the user's application didn't discover it.
// Let's discover DFU services.
discoverServices()
} else {
// A DFU service was found, congratulations!
logger.i("Services discovered")
peripheralDidDiscoverDfuService(dfuService!)
}
default:
connect()
}
}

Expand All @@ -181,13 +181,14 @@ internal class BaseDFUPeripheral<TD : BasePeripheralDelegate> : NSObject, BaseDF
}

func disconnect() {
if peripheral!.state == .connected {
guard let peripheral = peripheral else { return }
if peripheral.state == .connected {
logger.v("Disconnecting...")
} else {
logger.v("Cancelling connection...")
}
logger.d("centralManager.cancelPeripheralConnection(peripheral)")
centralManager.cancelPeripheralConnection(peripheral!)
centralManager.cancelPeripheralConnection(peripheral)
}

func destroy() {
Expand Down Expand Up @@ -239,10 +240,11 @@ internal class BaseDFUPeripheral<TD : BasePeripheralDelegate> : NSObject, BaseDF
stateAsString = "Unknown"
}
logger.d("[Callback] Central Manager did update state to: \(stateAsString)")
if central.state == .poweredOn {
switch central.state {
case .poweredOn:
// We are now ready to rumble!
start()
} else {
default:
// The device has been already disconnected if it was connected.
delegate?.error(.bluetoothDisabled, didOccurWithMessage: "Bluetooth adapter powered off")
destroy()
Expand Down Expand Up @@ -339,11 +341,10 @@ internal class BaseDFUPeripheral<TD : BasePeripheralDelegate> : NSObject, BaseDF
// MARK: - Peripheral Delegate methods

func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard error == nil else {
if let error = error {
logger.e("Services discovery failed")
logger.e(error!)
delegate?.error(.serviceDiscoveryFailed, didOccurWithMessage:
"Services discovery failed")
logger.e(error)
delegate?.error(.serviceDiscoveryFailed, didOccurWithMessage: "Services discovery failed")
return
}

Expand All @@ -370,8 +371,7 @@ internal class BaseDFUPeripheral<TD : BasePeripheralDelegate> : NSObject, BaseDF
logger.d("Did you connect to the correct target? It might be that the previous services were cached: toggle Bluetooth from iOS settings to clear cache. Also, ensure the device contains the Service Changed characteristic")

// The device does not support DFU, nor buttonless jump
delegate?.error(.deviceNotSupported, didOccurWithMessage:
"DFU Service not found")
delegate?.error(.deviceNotSupported, didOccurWithMessage: "DFU Service not found")
return
}
// A DFU service was found, congratulations!
Expand Down Expand Up @@ -409,7 +409,7 @@ internal class BaseDFUPeripheral<TD : BasePeripheralDelegate> : NSObject, BaseDF
This method should reset the device, preferably switching it to application mode.
*/
func resetDevice() {
if peripheral != nil && peripheral!.state != .disconnected {
if let peripheral = peripheral, peripheral.state != .disconnected {
disconnect()
} else {
peripheralDidDisconnect()
Expand All @@ -424,27 +424,17 @@ internal class BaseDFUPeripheral<TD : BasePeripheralDelegate> : NSObject, BaseDF
- returns: A `DFUService` type if a DFU service has been found, or `nil` if
services are `nil` or the list does not contain any supported DFU Service.
*/
private func findDfuService(in services:[CBService]?) -> CBService? {
if let services = services {
for service in services {
// Skip the experimental Buttonless DFU Service if this feature wasn't enabled.
if experimentalButtonlessServiceInSecureDfuEnabled && service.matches(uuid: uuidHelper.buttonlessExperimentalService) {
// The experimental Buttonless DFU Service for Secure DFU has been found.
return service
}

if service.matches(uuid: uuidHelper.secureDFUService) {
// Secure DFU Service has been found.
return service
}

if service.matches(uuid: uuidHelper.legacyDFUService) {
// Legacy DFU Service has been found.
return service
}
}
private func findDfuService(in services: [CBService]?) -> CBService? {
return services?.first { service in
// The experimental Buttonless DFU Service for Secure DFU has been found.
// Skip the experimental Buttonless DFU Service if this feature wasn't enabled.
(experimentalButtonlessServiceInSecureDfuEnabled &&
service.matches(uuid: uuidHelper.buttonlessExperimentalService)) ||
// Secure DFU Service has been found.
service.matches(uuid: uuidHelper.secureDFUService) ||
// Legacy DFU Service has been found.
service.matches(uuid: uuidHelper.legacyDFUService)
}
return nil
}

/**
Expand Down Expand Up @@ -651,7 +641,7 @@ internal class BaseCommonDFUPeripheral<TD : DFUPeripheralDelegate, TS : DFUServi
// This part of firmware has been successfully sent.

// Check if there is another part to be sent.
if (delegate?.peripheralDidDisconnectAfterFirmwarePartSent() ?? false) {
if delegate?.peripheralDidDisconnectAfterFirmwarePartSent() == true {
// As we are already in bootloader mode, the peripheral set
// may be reused for sending a second part.
connectOrSwitchToNewPeripheral(after: 15.0)
Expand Down Expand Up @@ -695,15 +685,15 @@ internal class BaseCommonDFUPeripheral<TD : DFUPeripheralDelegate, TS : DFUServi
// With that flag equal to true, the library will try to connect to the
// same device (with a short timeout), and if that fails, will try to
// scan for a new address using `DFUPeripheralSelector`.
connect(withTimeout: timeout) { [unowned self] in
connect(withTimeout: timeout) { [weak self] in
// Scan for a new device and connect to it.
self.switchToNewPeripheralAndConnect()
self?.switchToNewPeripheralAndConnect()
}
}

func switchToNewPeripheralAndConnect() {
// Release the previous peripheral.
peripheral!.delegate = nil
peripheral?.delegate = nil
peripheral = nil
cleanUp()

Expand Down
Loading