-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathRemoteController.swift
138 lines (113 loc) · 4.83 KB
/
RemoteController.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//
// RemoteController.swift
// Blender
//
// Created by Tony Ingraldi on 7/18/15.
// Copyright (c) 2015 Majesty Software. All rights reserved.
//
import CoreBluetooth
let DummyUUID = CBUUID(string: "00000000-0000-0000-0000-000000000000")
protocol RemoteControllerDelegate : NSObjectProtocol {
func remoteController(remoteController: RemoteController, didReceivePacket packet: Packet)
func remoteControllerIsInitialized(remoteController: RemoteController)
}
class RemoteController: NSObject, CBCentralManagerDelegate, CBPeripheralDelegate {
private var peripheral: CBPeripheral?
private var centralManager: CBCentralManager!
private var characteristics = [CBUUID:CBCharacteristic]()
var usesExplicitServiceUUIDs = true
var deviceServiceUUID: CBUUID {
return DummyUUID
}
var deviceServiceUUIDs: [CBUUID]? {
let UUIDs: [CBUUID]? = usesExplicitServiceUUIDs ? [deviceServiceUUID] : nil
return UUIDs
}
var receiveCharacteristicUUID: CBUUID { // receive from perspective of peripheral
return DummyUUID
}
var transmitCharacteristicUUID: CBUUID { // transmit from perspective of peripheral
return DummyUUID
}
var delegate: RemoteControllerDelegate?
func initialize() {
print("Initializing")
centralManager = CBCentralManager(delegate: self, queue: nil)
}
func centralManagerDidUpdateState(_ central: CBCentralManager) {
if (central.state == .poweredOn && peripheral == nil) {
print("Starting scan for peripherals")
centralManager.scanForPeripherals(withServices: self.deviceServiceUUIDs, options: nil)
}
}
func centralManager(_ central: CBCentralManager, didDiscover peripheral: CBPeripheral, advertisementData: [String : Any], rssi RSSI: NSNumber) {
print("Discovered peripheral \(peripheral)")
central.stopScan()
self.peripheral = peripheral;
peripheral.delegate = self;
central.connect(peripheral, options: nil)
}
func centralManager(_ central: CBCentralManager, didFailToConnect peripheral: CBPeripheral, error: Error?) {
print("Failed to connect: \(String(describing: error))")
}
func centralManager(_ central: CBCentralManager, didConnect peripheral: CBPeripheral) {
print("Connected to \(peripheral)")
peripheral.discoverServices(self.deviceServiceUUIDs);
}
func centralManager(_ central: CBCentralManager, didDisconnectPeripheral peripheral: CBPeripheral, error: Error?) {
print("Disconnected from \(peripheral)")
if let actualError = error {
print(actualError.localizedDescription)
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverServices error: Error?) {
guard let services = peripheral.services else {
return
}
for service: CBService in services {
print("Discovered service \(service)")
peripheral.discoverCharacteristics([self.transmitCharacteristicUUID, self.receiveCharacteristicUUID], for: service)
}
if let actualError = error {
print(actualError.localizedDescription)
}
}
func peripheral(_ peripheral: CBPeripheral, didDiscoverCharacteristicsFor service: CBService, error: Error?) {
guard let localCharacteristics = service.characteristics else {
return
}
for characteristic in localCharacteristics {
print("Discovered characteristic \(characteristic) for service \(service)")
characteristics[characteristic.uuid] = characteristic
}
if let transmitCharacteristic = characteristics[self.transmitCharacteristicUUID] {
self.peripheral?.setNotifyValue(true, for: transmitCharacteristic)
self.delegate?.remoteControllerIsInitialized(remoteController: self)
}
if let actualError = error {
print(actualError.localizedDescription)
}
}
func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) {
if error == nil {
let packet = Packet(data: characteristic.data)
self.delegate?.remoteController(remoteController: self, didReceivePacket: packet)
} else {
print(error!)
}
}
func read() {
self.peripheral?.readValue(for: self.characteristics[self.transmitCharacteristicUUID]!)
}
func write(data: NSData) {
if (peripheral?.state == .connected) {
self.peripheral?.writeValue(data as Data, for: self.characteristics[self.receiveCharacteristicUUID]!, type: .withoutResponse)
} else {
print("Refusing to write to a disconnected peripheral")
}
}
func write(packet: Packet) {
print("Writing packet \(packet)")
self.write(data: packet.data)
}
}