93 lines
2.8 KiB
Swift
Executable File
93 lines
2.8 KiB
Swift
Executable File
import Vapor
|
|
|
|
extension PublicAPI {
|
|
|
|
var path: PathComponent {
|
|
.init(stringLiteral: rawValue)
|
|
}
|
|
|
|
var pathParameter: PathComponent {
|
|
.parameter(rawValue)
|
|
}
|
|
}
|
|
|
|
private func handleKeyPost(_ req: Request) -> KeyPostResponse {
|
|
guard let keyId = req.parameters.get(PublicAPI.postKeyIdParameter.rawValue, as: UInt16.self) else {
|
|
return .invalidKeyId
|
|
}
|
|
guard let body = req.body.data else {
|
|
return .noBodyData
|
|
}
|
|
guard body.readableBytes == KeyManagement.keySize else {
|
|
return .invalidKeySize
|
|
}
|
|
guard let key = body.getData(at: 0, length: KeyManagement.keySize) else {
|
|
return .corruptkeyData
|
|
}
|
|
return keyManager.sendKeyToDevice(key, keyId: keyId)
|
|
}
|
|
|
|
func routes(_ app: Application) throws {
|
|
|
|
/**
|
|
Get the connection status of the device.
|
|
|
|
The response is a string of either "1" (connected) or "0" (disconnected)
|
|
*/
|
|
app.get(PublicAPI.getDeviceStatus.path) { req -> String in
|
|
keyManager.deviceStatus
|
|
}
|
|
|
|
/**
|
|
Get the response from the device.
|
|
|
|
The response is a string of an integer `rawValue` of a `KeyResult`
|
|
*/
|
|
app.get(PublicAPI.getDeviceResponse.path) { req -> String in
|
|
keyManager.deviceResponse
|
|
}
|
|
|
|
/**
|
|
Post a request to remove the information about the last key transmission.
|
|
|
|
- The request always succeeds and returns the string "Success"
|
|
*/
|
|
app.post(PublicAPI.clearKeyRequest.path) { req -> String in
|
|
keyManager.clearClientRequest()
|
|
return "Success"
|
|
}
|
|
|
|
/**
|
|
Post a key to the device for unlocking.
|
|
|
|
The corresponding integer key id for the key data must be contained in the url path.
|
|
|
|
The request returns a string containing a `rawValue` of a `KeyPostResponse`
|
|
A success of this method does not yet signal successful unlocking.
|
|
The client should request the status by inquiring the device response.
|
|
*/
|
|
app.post(PublicAPI.postKey.path, PublicAPI.postKeyIdParameter.pathParameter) { req -> String in
|
|
let result = handleKeyPost(req)
|
|
return String(result.rawValue)
|
|
}
|
|
|
|
/**
|
|
Start a new websocket connection for the client to receive table updates from the server
|
|
- Returns: Nothing
|
|
- Note: The first (and only) message from the client over the connection must be a valid session token.
|
|
*/
|
|
app.webSocket(PublicAPI.socket.path) { req, socket in
|
|
socket.onBinary { _, data in
|
|
keyManager.processDeviceResponse(data)
|
|
}
|
|
socket.onText { _, text in
|
|
keyManager.authenticateDevice(psk: text)
|
|
}
|
|
|
|
_ = socket.onClose.always { _ in
|
|
keyManager.didCloseDeviceSocket()
|
|
}
|
|
keyManager.createNewDeviceConnection(socket)
|
|
}
|
|
}
|