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

Option to disable chunking feature to improve compatibility with non bluetoothKit devices #90

Merged
merged 2 commits into from Sep 21, 2018
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion BluetoothKit.podspec
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = 'BluetoothKit'
s.version = '0.4.0'
s.version = '0.4.1'
s.license = { :type => 'MIT' }
s.homepage = 'https://github.com/rasmusth/BluetoothKit'
s.authors = { 'Rasmus Taulborg Hummelmose' => 'rasmus@hummelmose.dk' }
Expand Down
8 changes: 2 additions & 6 deletions Source/BKCBCentralManagerDelegateProxy.swift
Expand Up @@ -30,7 +30,7 @@ internal protocol BKCBCentralManagerStateDelegate: class {
}

internal protocol BKCBCentralManagerDiscoveryDelegate: class {
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber)
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber)
}

internal protocol BKCBCentralManagerConnectionDelegate: class {
Expand Down Expand Up @@ -62,7 +62,7 @@ internal class BKCBCentralManagerDelegateProxy: NSObject, CBCentralManagerDelega
stateDelegate?.centralManagerDidUpdateState(central)
}

internal func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
internal func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
discoveryDelegate?.centralManager(central, didDiscover: peripheral, advertisementData: advertisementData, rssi: RSSI)
}

Expand All @@ -78,8 +78,4 @@ internal class BKCBCentralManagerDelegateProxy: NSObject, CBCentralManagerDelega
connectionDelegate?.centralManager(central, didDisconnectPeripheral: peripheral, error: error)
}





}
13 changes: 6 additions & 7 deletions Source/BKCentral.swift
Expand Up @@ -75,7 +75,7 @@ public class BKCentral: BKPeer, BKCBCentralManagerStateDelegate, BKConnectionPoo
guard let centralManager = _centralManager else {
return nil
}

if #available(tvOS 10.0, iOS 10.0, OSX 10.13, *) {
return BKAvailability(managerState: centralManager.state)
} else {
Expand Down Expand Up @@ -292,7 +292,7 @@ public class BKCentral: BKPeer, BKCBCentralManagerStateDelegate, BKConnectionPoo
}

var remotePeripherals: [BKRemotePeripheral] = []

#if os(OSX)
if #available(OSX 10.13, *) {
for peripheral in peripherals {
Expand All @@ -310,12 +310,12 @@ public class BKCentral: BKPeer, BKCBCentralManagerStateDelegate, BKConnectionPoo
remotePeripherals.append(remotePeripheral)
}
#endif

return remotePeripherals
}
return nil
}

// MARK: Internal Functions

internal func setUnavailable(_ cause: BKUnavailabilityCause, oldCause: BKUnavailabilityCause?) {
Expand Down Expand Up @@ -344,20 +344,19 @@ public class BKCentral: BKPeer, BKCBCentralManagerStateDelegate, BKConnectionPoo

// MARK: BKCBCentralManagerStateDelegate


internal func centralManagerDidUpdateState(_ central: CBCentralManager) {
switch central.state {
case .unknown, .resetting:
break
case .unsupported, .unauthorized, .poweredOff:

let newCause: BKUnavailabilityCause
if #available(iOS 10.0, tvOS 10.0, OSX 10.13, *) {
newCause = BKUnavailabilityCause(managerState: central.state)
} else {
newCause = BKUnavailabilityCause(centralManagerState: central.centralManagerState)
}

switch stateMachine.state {
case let .unavailable(cause):
let oldCause = cause
Expand Down
13 changes: 7 additions & 6 deletions Source/BKConfiguration.swift
Expand Up @@ -41,8 +41,9 @@ public class BKConfiguration {
/// Data used to indicate that no more data is coming when communicating.
public var endOfDataMark: Data

/// Data used to indicate that a transfer was cancellen when communicating.
public var dataCancelledMark: Data
/// Enabled by default. This config will automatically chunk data sent and received.
/// Disable this if you want to talk to devices that are not using bluetoothKit and then add your own logic for large payloads.
public var chunkingEnabled: Bool

internal var serviceUUIDs: [CBUUID] {
let serviceUUIDs = [ dataServiceUUID ]
Expand All @@ -51,14 +52,14 @@ public class BKConfiguration {

// MARK: Initialization

public init(dataServiceUUID: UUID, dataServiceCharacteristicUUID: UUID) {
public init(dataServiceUUID: UUID, dataServiceCharacteristicUUID: UUID, chunkingEnabled: Bool) {
self.dataServiceUUID = CBUUID(nsuuid: dataServiceUUID)
self.dataServiceCharacteristicUUID = CBUUID(nsuuid: dataServiceCharacteristicUUID)
endOfDataMark = "EOD".data(using: String.Encoding.utf8)!
dataCancelledMark = "COD".data(using: String.Encoding.utf8)!
self.endOfDataMark = "EOD".data(using: String.Encoding.utf8)!
self.chunkingEnabled = chunkingEnabled
}

// MARK Functions
// MARK: Functions

internal func characteristicUUIDsForServiceUUID(_ serviceUUID: CBUUID) -> [CBUUID] {
if serviceUUID == dataServiceUUID {
Expand Down
2 changes: 1 addition & 1 deletion Source/BKContinuousScanner.swift
Expand Up @@ -60,7 +60,7 @@ internal class BKContinousScanner {
state = .stopped
}

// MARK Internal Functions
// MARK: Internal Functions

internal func scanContinuouslyWithChangeHandler(_ changeHandler: @escaping ChangeHandler, stateHandler: StateHandler? = nil, duration: TimeInterval = 3, inBetweenDelay: TimeInterval = 3, errorHandler: ErrorHandler?) {
guard !busy else {
Expand Down
2 changes: 2 additions & 0 deletions Source/BKErrorDomain.swift
Expand Up @@ -30,10 +30,12 @@ import Foundation
- FailedToConnectDueToTimeout: The time out elapsed while attempting to connect to a peripheral.
- RemotePeerNotConnected: The action failed because the remote peer attempted to interact with, was not connected.
- InternalError(underlyingError): Will be returned if any of the internal or private classes returns an unhandled error.
- SendFailure(reason): Will be returned if wasn't able to send data. This could be cause the payload was too big etc.
*/
public enum BKError: Error {
case interruptedByUnavailability(cause: BKUnavailabilityCause)
case failedToConnectDueToTimeout
case remotePeerNotConnected
case internalError(underlyingError: Error?)
case sendFailure(reason: String)
}
17 changes: 17 additions & 0 deletions Source/BKPeer.swift
Expand Up @@ -53,6 +53,23 @@ public class BKPeer {
- parameter completionHandler: A completion handler allowing you to react in case the data failed to send or once it was sent succesfully.
*/
public func sendData(_ data: Data, toRemotePeer remotePeer: BKRemotePeer, completionHandler: BKSendDataCompletionHandler?) {
if configuration?.chunkingEnabled == false {
if data.count > remotePeer.maximumUpdateValueLength {
if let handler = completionHandler {
handler(data, remotePeer, BKError.sendFailure(reason: "data.count(\(data.count) is exceeding maximum payload length of \(remotePeer.maximumUpdateValueLength)"))
}
return
}
let result = sendData(data, toRemotePeer: remotePeer)
if let handler = completionHandler {
handler(data, remotePeer, result ? nil : .remotePeerNotConnected)
}
return
}
sendDataInTasks(data, toRemotePeer: remotePeer, completionHandler: completionHandler)
}

private func sendDataInTasks(_ data: Data, toRemotePeer remotePeer: BKRemotePeer, completionHandler: BKSendDataCompletionHandler?) {
guard connectedRemotePeers.contains(remotePeer) else {
completionHandler?(data, remotePeer, BKError.remotePeerNotConnected)
return
Expand Down
9 changes: 4 additions & 5 deletions Source/BKPeripheral.swift
Expand Up @@ -187,14 +187,14 @@ public class BKPeripheral: BKPeer, BKCBPeripheralManagerDelegate, BKAvailability
case .unknown, .resetting:
break
case .unsupported, .unauthorized, .poweredOff:

let newCause: BKUnavailabilityCause
if #available(iOS 10.0, tvOS 10.0, OSX 10.13, *) {
newCause = BKUnavailabilityCause(managerState: peripheralManager.state)
} else {
newCause = BKUnavailabilityCause(peripheralManagerState: peripheralManager.peripheralManagerState)
}

switch stateMachine.state {
case let .unavailable(cause):
let oldCause = cause
Expand All @@ -216,7 +216,6 @@ public class BKPeripheral: BKPeer, BKCBPeripheralManagerDelegate, BKAvailability
}
}


internal func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) {

}
Expand All @@ -239,7 +238,7 @@ public class BKPeripheral: BKPeer, BKCBPeripheralManagerDelegate, BKAvailability
}

internal func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFromCharacteristic characteristic: CBCharacteristic) {

#if os(OSX)
if #available(OSX 10.13, *) {
if let remoteCentral = connectedRemotePeers.filter({ ($0.identifier == central.identifier) }).last as? BKRemoteCentral {
Expand All @@ -260,7 +259,7 @@ public class BKPeripheral: BKPeer, BKCBPeripheralManagerDelegate, BKAvailability
guard writeRequest.characteristic.uuid == characteristicData.uuid else {
continue
}

#if os(OSX)
if #available(OSX 10.13, *) {
guard let remotePeer = (connectedRemotePeers.filter { $0.identifier == writeRequest.central.identifier } .last),
Expand Down
4 changes: 2 additions & 2 deletions Source/BKPeripheralConfiguration.swift
Expand Up @@ -37,9 +37,9 @@ public class BKPeripheralConfiguration: BKConfiguration {

// MARK: Initialization

public init(dataServiceUUID: UUID, dataServiceCharacteristicUUID: UUID, localName: String? = nil) {
public init(dataServiceUUID: UUID, dataServiceCharacteristicUUID: UUID, localName: String? = nil, chunkingEnabled: Bool) {
self.localName = localName
super.init(dataServiceUUID: dataServiceUUID, dataServiceCharacteristicUUID: dataServiceCharacteristicUUID)
super.init(dataServiceUUID: dataServiceUUID, dataServiceCharacteristicUUID: dataServiceCharacteristicUUID, chunkingEnabled: chunkingEnabled)
}

}
4 changes: 4 additions & 0 deletions Source/BKRemotePeer.swift
Expand Up @@ -56,6 +56,10 @@ public class BKRemotePeer: Equatable {
}

internal func handleReceivedData(_ receivedData: Data) {
if configuration?.chunkingEnabled == false {
delegate?.remotePeer(self, didSendArbitraryData: receivedData)
return
}
if receivedData == configuration!.endOfDataMark {
if let finalData = data {
delegate?.remotePeer(self, didSendArbitraryData: finalData)
Expand Down
1 change: 0 additions & 1 deletion Source/BKRemotePeripheral.swift
Expand Up @@ -184,5 +184,4 @@ public class BKRemotePeripheral: BKRemotePeer, BKCBPeripheralDelegate {
handleReceivedData(characteristic.value!)
}


}
8 changes: 4 additions & 4 deletions Source/BKScanner.swift
Expand Up @@ -104,14 +104,14 @@ internal class BKScanner: BKCBCentralManagerDiscoveryDelegate {

// MARK: BKCBCentralManagerDiscoveryDelegate

internal func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
internal func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String: Any], rssi RSSI: NSNumber) {
guard busy else {
return
}

let RSSI = Int(RSSI.intValue)
var remotePeripheral: BKRemotePeripheral

#if os(OSX)
if #available(OSX 10.13, *) {
remotePeripheral = BKRemotePeripheral(identifier: peripheral.identifier, peripheral: peripheral)
Expand All @@ -121,7 +121,7 @@ internal class BKScanner: BKCBCentralManagerDiscoveryDelegate {
#else
remotePeripheral = BKRemotePeripheral(identifier: peripheral.identifier, peripheral: peripheral)
#endif

remotePeripheral.configuration = configuration
let discovery = BKDiscovery(advertisementData: advertisementData, remotePeripheral: remotePeripheral, RSSI: RSSI)
if !discoveries.contains(discovery) {
Expand Down