Created
September 14, 2018 16:43
-
-
Save bricklife/f529e73b68771179ad5392d0e9449dd2 to your computer and use it in GitHub Desktop.
micro:bit simulator for Scratch 3.0
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
// | |
// BLEPeripheral.swift | |
// BLEPeripheral | |
// | |
// Created by ooba on 26/07/2017. | |
// Copyright © 2017 bricklife.com. All rights reserved. | |
// | |
import Foundation | |
import CoreBluetooth | |
class BLEPeripheral: NSObject { | |
var peripheralManager: CBPeripheralManager? | |
let serviceUUID = CBUUID(string: "f005") | |
let rxUUID = CBUUID(string: "5261da01-fa7e-42ab-850b-7c80220097cc") | |
let txUUID = CBUUID(string: "5261da02-fa7e-42ab-850b-7c80220097cc") | |
var rxCharacteristic: CBMutableCharacteristic? | |
var txCharacteristic: CBMutableCharacteristic? | |
var timer: Timer? | |
var pressingButtonA: Bool = false | |
var pressingButtonB: Bool = false | |
override init() { | |
super.init() | |
peripheralManager = CBPeripheralManager(delegate: self, queue: nil) | |
} | |
func startAdvertising() { | |
let advertisementData: [String : Any] = [ | |
CBAdvertisementDataLocalNameKey: "micro:bit sim", | |
CBAdvertisementDataServiceUUIDsKey: [serviceUUID], | |
] | |
peripheralManager?.startAdvertising(advertisementData) | |
} | |
func stopAdvertising() { | |
peripheralManager?.stopAdvertising() | |
} | |
func addService() { | |
peripheralManager?.removeAllServices() | |
let service = CBMutableService(type: serviceUUID, primary: true) | |
let rx = CBMutableCharacteristic(type: rxUUID, properties: [.read, .notify], value: nil, permissions: [.readable]) | |
let tx = CBMutableCharacteristic(type: txUUID, properties: [.write, .writeWithoutResponse], value: nil, permissions: [.writeable]) | |
service.characteristics = [rx, tx] | |
peripheralManager?.add(service) | |
rx.value = Data(bytes: Array<UInt8>(repeating: 0, count: 10)) | |
self.rxCharacteristic = rx | |
self.txCharacteristic = tx | |
} | |
func notify() { | |
guard let characteristic = rxCharacteristic else { return } | |
let data = Data(bytes: [0x00, 0x00, | |
0x00, 0x00, | |
pressingButtonA ? 0x01 : 0x00, | |
pressingButtonB ? 0x01 : 0x00, | |
0x00, 0x00, 0x00, | |
0x00, | |
]) | |
characteristic.value = data | |
peripheralManager?.updateValue(data, for: characteristic, onSubscribedCentrals: nil) | |
} | |
} | |
extension BLEPeripheral: CBPeripheralManagerDelegate { | |
func peripheralManagerDidUpdateState(_ peripheral: CBPeripheralManager) { | |
switch peripheral.state { | |
case .poweredOn: | |
print("poweredOn") | |
addService() | |
startAdvertising() | |
default: | |
print(peripheral.state) | |
stopAdvertising() | |
} | |
} | |
func peripheralManagerDidStartAdvertising(_ peripheral: CBPeripheralManager, error: Error?) { | |
print("didStartAdvertising:", error ?? "success") | |
} | |
func peripheralManager(_ peripheral: CBPeripheralManager, didAdd service: CBService, error: Error?) { | |
print("didAdd:", service, error ?? "success") | |
} | |
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveRead request: CBATTRequest) { | |
print("didReceiveRead:", request) | |
if let characteristic = rxCharacteristic, request.characteristic.uuid == characteristic.uuid { | |
request.value = characteristic.value | |
peripheral.respond(to: request, withResult: .success) | |
} else { | |
peripheral.respond(to: request, withResult: .requestNotSupported) | |
} | |
} | |
func peripheralManager(_ peripheral: CBPeripheralManager, didReceiveWrite requests: [CBATTRequest]) { | |
print("didReceiveWrite:", requests) | |
guard let firstRequest = requests.first else { | |
fatalError() | |
} | |
for request in requests { | |
if let characteristic = txCharacteristic, request.characteristic.uuid == characteristic.uuid { | |
characteristic.value = request.value | |
} else { | |
peripheral.respond(to: firstRequest, withResult: .requestNotSupported) | |
return | |
} | |
} | |
peripheral.respond(to: firstRequest, withResult: .success) | |
} | |
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didSubscribeTo characteristic: CBCharacteristic) { | |
print("didSubscribeTo:", central, characteristic) | |
timer = Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true, block: { [weak self] (_) in | |
self?.notify() | |
}) | |
} | |
func peripheralManager(_ peripheral: CBPeripheralManager, central: CBCentral, didUnsubscribeFrom characteristic: CBCharacteristic) { | |
print("didUnsubscribeFrom:", central, characteristic) | |
timer?.invalidate() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment