-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* basic layout for CoreBluetooth transport * Can discover and connect to devices with service ID AAAA * add .idea to gitignore * Can see characteristics of devices * Can read values of characteristics * remove .idea * Move Transport to extension * Create Extensions folder * UNTESTED: can probably send and receive abc * got sending and recieving working * asthetics * autocorrect * some linting * kinda works * started cleaning up * oops * format * cleanup * delete * refactor * fixed * refactor * removed eol * major cleanup * format * fixed lint issues * fixed * disable rule * done * minor * removed comments * minor * nodoc & removed unused code * docs * cleanups * removed relayer/main * receives data, node decodes no longer in transport * updated * typer * bidirectional read / write * fixes * updates * minor update * notifications * cleanup * format * reformatted * docs * Update CoreBluetoothTransport.swift * Update CoreBluetoothTransport.swift * Update CoreBluetoothTransport.swift * Update CoreBluetoothTransport.swift * docs * change uuid
- Loading branch information
Showing
47 changed files
with
1,955 additions
and
94 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,7 @@ xcuserdata/ | |
*.moved-aside | ||
*.xccheckout | ||
*.xcscmblueprint | ||
.idea | ||
*.xcworkspace | ||
|
||
## Obj-C/Swift specific | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11,3 +11,5 @@ identifier_name: | |
excluded: | ||
- id | ||
- to | ||
disabled_rules: | ||
- trailing_comma |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
{ | ||
"object": { | ||
"pins": [ | ||
{ | ||
"package": "SwiftProtobuf", | ||
"repositoryURL": "https://github.com/apple/swift-protobuf.git", | ||
"state": { | ||
"branch": null, | ||
"revision": "3a3594f84b746793c84c2ab2f1e855aaa9d3a593", | ||
"version": "1.6.0" | ||
} | ||
} | ||
] | ||
}, | ||
"version": 1 | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
import Foundation | ||
|
||
/// :nodoc: | ||
extension UUID { | ||
var bytes: Data { | ||
return withUnsafePointer(to: self) { | ||
Data(bytes: $0, count: MemoryLayout.size(ofValue: self)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
import CoreBluetooth | ||
import Foundation | ||
|
||
/// CoreBluetoothTransport is used to send and receive message over Bluetooth | ||
public class CoreBluetoothTransport: NSObject, Transport { | ||
/// The transports delegate. | ||
public weak var delegate: TransportDelegate? | ||
|
||
/// The peers a specific transport can send messages to. | ||
public fileprivate(set) var peers = [Peer]() | ||
|
||
private let centralManager: CBCentralManager | ||
private let peripheralManager: CBPeripheralManager | ||
|
||
private static let ubServiceUUID = CBUUID(string: "BEA3B031-76FB-4889-B3C7-000000000000") | ||
private static let receiveCharacteristicUUID = CBUUID(string: "BEA3B031-76FB-4889-B3C7-000000000001") | ||
|
||
private static let characteristic = CBMutableCharacteristic( | ||
type: CoreBluetoothTransport.receiveCharacteristicUUID, | ||
properties: [.read, .writeWithoutResponse, .notify], | ||
value: nil, | ||
permissions: [.writeable, .readable] | ||
) | ||
|
||
// make this nicer, we need this cause we need a reference to the peripheral? | ||
private var perp: CBPeripheral? | ||
private var centrals = [Addr: CBCentral]() | ||
private var peripherals = [Addr: (peripheral: CBPeripheral, characteristic: CBCharacteristic)]() | ||
|
||
/// Initializes a CoreBluetoothTransport with a new CBCentralManager and CBPeripheralManager. | ||
public convenience override init() { | ||
self.init( | ||
centralManager: CBCentralManager(delegate: nil, queue: nil), | ||
peripheralManager: CBPeripheralManager(delegate: nil, queue: nil) | ||
) | ||
} | ||
|
||
/// Initializes a CoreBluetoothTransport. | ||
/// | ||
/// - Parameters: | ||
/// - centralManager: The CoreBluetooth Central Manager to use. | ||
/// - peripheralManager: The CoreBluetooth Peripheral Manager to use. | ||
public init(centralManager: CBCentralManager, peripheralManager: CBPeripheralManager) { | ||
self.centralManager = centralManager | ||
self.peripheralManager = peripheralManager | ||
super.init() | ||
self.centralManager.delegate = self | ||
self.peripheralManager.delegate = self | ||
} | ||
|
||
/// Send implements a function to send messages between nodes using Bluetooth | ||
/// | ||
/// - Parameters: | ||
/// - message: The message to send. | ||
/// - to: The recipient address of the message. | ||
public func send(message: Data, to: Addr) { | ||
if let peer = peripherals[to] { | ||
return peer.peripheral.writeValue( | ||
message, | ||
for: peer.characteristic, | ||
type: CBCharacteristicWriteType.withoutResponse | ||
) | ||
} | ||
|
||
if let central = centrals[to] { | ||
peripheralManager.updateValue( | ||
message, | ||
for: CoreBluetoothTransport.characteristic, | ||
onSubscribedCentrals: [central] | ||
) | ||
} | ||
} | ||
|
||
/// Listen implements a function to receive messages being sent to a node. | ||
public func listen() { | ||
// @todo mark as listening, only turn on peripheral characteristic at this point, etc. | ||
} | ||
|
||
fileprivate func remove(peer: Addr) { | ||
peripherals.removeValue(forKey: peer) | ||
peers.removeAll(where: { $0.id == peer }) | ||
} | ||
|
||
fileprivate func add(central: CBCentral) { | ||
let id = Addr(central.identifier.bytes) | ||
|
||
if centrals[id] != nil { | ||
return | ||
} | ||
|
||
centrals[id] = central | ||
peers.append(Peer(id: id, services: [UBID]())) | ||
} | ||
} | ||
|
||
/// :nodoc: | ||
extension CoreBluetoothTransport: CBPeripheralManagerDelegate { | ||
public func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { | ||
if peripheral.state == .poweredOn { | ||
let service = CBMutableService(type: CoreBluetoothTransport.ubServiceUUID, primary: true) | ||
|
||
service.characteristics = [CoreBluetoothTransport.characteristic] | ||
peripheral.add(service) | ||
|
||
peripheral.startAdvertising([ | ||
CBAdvertisementDataServiceUUIDsKey: [CoreBluetoothTransport.ubServiceUUID], | ||
CBAdvertisementDataLocalNameKey: nil, | ||
]) | ||
} | ||
} | ||
|
||
public func peripheralManager(_: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) { | ||
for request in requests { | ||
guard let data = request.value else { | ||
// @todo | ||
return | ||
} | ||
|
||
delegate?.transport(self, didReceiveData: data, from: Addr(request.central.identifier.bytes)) | ||
add(central: request.central) | ||
} | ||
} | ||
|
||
public func peripheralManager( | ||
_: CBPeripheralManager, | ||
central: CBCentral, | ||
didSubscribeTo _: CBCharacteristic | ||
) { | ||
add(central: central) | ||
} | ||
|
||
public func peripheralManager( | ||
_: CBPeripheralManager, | ||
central: CBCentral, | ||
didUnsubscribeFrom _: CBCharacteristic | ||
) { | ||
// @todo check that this is the characteristic | ||
let id = Addr(central.identifier.bytes) | ||
centrals.removeValue(forKey: id) | ||
peers.removeAll(where: { $0.id == id }) | ||
} | ||
} | ||
|
||
/// :nodoc: | ||
extension CoreBluetoothTransport: CBCentralManagerDelegate { | ||
public func centralManagerDidUpdateState(_ central: CBCentralManager) { | ||
if central.state == .poweredOn { | ||
centralManager.scanForPeripherals(withServices: [CoreBluetoothTransport.ubServiceUUID]) | ||
} | ||
|
||
// @todo handling for other states | ||
} | ||
|
||
public func centralManager( | ||
_ central: CBCentralManager, | ||
didDiscover peripheral: CBPeripheral, | ||
advertisementData _: [String: Any], | ||
rssi _: NSNumber | ||
) { | ||
perp = peripheral | ||
peripheral.delegate = self | ||
centralManager.connect(peripheral) | ||
} | ||
|
||
public func centralManager(_: CBCentralManager, didConnect peripheral: CBPeripheral) { | ||
peripheral.discoverServices([CoreBluetoothTransport.ubServiceUUID]) | ||
} | ||
|
||
public func centralManager(_: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error _: Error?) { | ||
remove(peer: Addr(peripheral.identifier.bytes)) | ||
} | ||
} | ||
|
||
/// :nodoc: | ||
extension CoreBluetoothTransport: CBPeripheralDelegate { | ||
public func peripheral(_ peripheral: CBPeripheral, didDiscoverServices _: Error?) { | ||
if let service = peripheral.services?.first(where: { $0.uuid == CoreBluetoothTransport.ubServiceUUID }) { | ||
peripheral.discoverCharacteristics([CoreBluetoothTransport.receiveCharacteristicUUID], for: service) | ||
} | ||
} | ||
|
||
public func peripheral( | ||
_ peripheral: CBPeripheral, | ||
didDiscoverCharacteristicsFor service: CBService, | ||
error _: Error? | ||
) { | ||
let id = Addr(peripheral.identifier.bytes) | ||
if peripherals[id] != nil { | ||
return | ||
} | ||
|
||
let characteristics = service.characteristics | ||
if let char = characteristics?.first(where: { $0.uuid == CoreBluetoothTransport.receiveCharacteristicUUID }) { | ||
peripherals[id] = (peripheral, char) | ||
peripherals[id]?.peripheral.setNotifyValue(true, for: char) | ||
// @todo we may need to do some handshake to obtain services from a peer. | ||
peers.append(Peer(id: id, services: [UBID]())) | ||
} | ||
} | ||
|
||
public func peripheral(_ peripheral: CBPeripheral, didModifyServices invalidatedServices: [CBService]) { | ||
if invalidatedServices.contains(where: { $0.uuid == CoreBluetoothTransport.ubServiceUUID }) { | ||
remove(peer: Addr(peripheral.identifier.bytes)) | ||
} | ||
} | ||
|
||
public func peripheral( | ||
_ peripheral: CBPeripheral, | ||
didUpdateValueFor characteristic: CBCharacteristic, | ||
error _: Error? | ||
) { | ||
guard let value = characteristic.value else { return } | ||
delegate?.transport(self, didReceiveData: value, from: Addr(peripheral.identifier.bytes)) | ||
} | ||
|
||
public func peripheral( | ||
_: CBPeripheral, | ||
didUpdateNotificationStateFor _: CBCharacteristic, | ||
error _: Error? | ||
) { | ||
// @todo figure out exactly what we will want to do here. | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
import Foundation | ||
|
||
/// TransportDelegate is used to handle the receiving of messages. | ||
/// TransportDelegate is used to handle the receiving data. | ||
public protocol TransportDelegate: AnyObject { | ||
/// Called when a transport receives a new message. | ||
/// Called when a transport receives new data. | ||
/// | ||
/// - Parameters: | ||
/// - transport: The transport that received a message. | ||
/// - message: The received message. | ||
func transport(_ transport: Transport, didReceiveMessage message: Message) | ||
/// - transport: The transport that received a data. | ||
/// - data: The received data. | ||
/// - from: The peer from which the data was received. | ||
func transport(_ transport: Transport, didReceiveData data: Data, from: Addr) | ||
} |
Oops, something went wrong.