-
Notifications
You must be signed in to change notification settings - Fork 2
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
feature/core-bluetooth #52
Merged
Merged
Changes from 55 commits
Commits
Show all changes
63 commits
Select commit
Hold shift + click to select a range
164f555
basic layout for CoreBluetooth transport
ec2 75b6157
Can discover and connect to devices with service ID AAAA
ec2 f4d0015
add .idea to gitignore
ec2 11f0cc3
Can see characteristics of devices
ec2 396a237
Can read values of characteristics
ec2 1a39b5f
remove .idea
ec2 02a1edc
Move Transport to extension
ec2 4d85b24
Create Extensions folder
ec2 cddafe4
UNTESTED: can probably send and receive abc
ec2 183790e
Merge branch 'master' into feature/core-bluetooth
ec2 d9a6f0b
got sending and recieving working
ec2 c2af52b
asthetics
ec2 109ef66
Merge branch 'master' into feature/core-bluetooth
ec2 4360544
autocorrect
ec2 0217368
merge conflicts
ec2 7877229
some linting
ec2 3eed0ab
Merge branch 'master' into feature/core-bluetooth
ec2 9f58511
kinda works
ec2 7aa2eab
started cleaning up
decanus 0006cb1
oops
decanus a4a9f73
format
decanus 29a441b
cleanup
decanus e7b25ab
delete
decanus f368dc3
refactor
decanus 0b171d8
fixed
decanus ca90346
refactor
decanus 93d66bd
removed eol
decanus 0c9c030
major cleanup
decanus c70f416
format
decanus d4675af
fixed lint issues
decanus cfa4055
fixed
decanus 7790850
disable rule
decanus 81a5973
done
decanus 8f659a8
minor
decanus 34ecca7
removed comments
decanus a325ff0
minor
decanus 40ebc3b
nodoc & removed unused code
decanus 685ae19
docs
decanus 0cafc29
merged
decanus c5781b2
cleanups
decanus ea5f46b
updates
decanus 8a60067
removed relayer/main
decanus 1668d20
receives data, node decodes no longer in transport
decanus ebd9926
updated
decanus d5e775e
typer
decanus 66040cd
bidirectional read / write
decanus 0387386
fixes
decanus 925f81b
updates
decanus 5f57ed3
minor update
decanus d7f554b
notifications
decanus 6dae52e
cleanup
decanus 01e326c
format
decanus 0fb25c9
reformatted
decanus f981784
docs
decanus 733ad24
Update CoreBluetoothTransport.swift
decanus ab11691
Update CoreBluetoothTransport.swift
decanus 065599f
Update CoreBluetoothTransport.swift
decanus 1050da7
Update CoreBluetoothTransport.swift
decanus dbdf612
merged
decanus 48a10fb
Merge branch 'feature/core-bluetooth' of github.com:ultralight-beam/U…
decanus 8000442
merged
decanus e55286e
docs
decanus 6070337
change uuid
decanus File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
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,9 @@ | ||
import Foundation | ||
|
||
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,222 @@ | ||
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: "AAAA") | ||
private static let receiveCharacteristicUUID = CBUUID(string: "0002") | ||
|
||
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) | ||
peers.append(Peer(id: id, services: [UBID]())) // @todo we may need to do some handshake to obtain services from a peer. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Line should be 120 characters or less: currently 132 characters |
||
} | ||
} | ||
|
||
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
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
message type?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
:)