Move to Bytes from Data, simplify result cases
This commit is contained in:
parent
f9039c7b3a
commit
1c6c29d585
@ -24,10 +24,6 @@ struct DeviceResponse {
|
|||||||
.init(event: .noBodyData)
|
.init(event: .noBodyData)
|
||||||
}
|
}
|
||||||
|
|
||||||
static var corruptkeyData: DeviceResponse {
|
|
||||||
.init(event: .corruptkeyData)
|
|
||||||
}
|
|
||||||
|
|
||||||
static var operationInProgress: DeviceResponse {
|
static var operationInProgress: DeviceResponse {
|
||||||
.init(event: .operationInProgress)
|
.init(event: .operationInProgress)
|
||||||
}
|
}
|
||||||
@ -39,7 +35,7 @@ struct DeviceResponse {
|
|||||||
let response: Message?
|
let response: Message?
|
||||||
|
|
||||||
init?(_ buffer: ByteBuffer) {
|
init?(_ buffer: ByteBuffer) {
|
||||||
guard let byte = buffer.getData(at: 0, length: 1) else {
|
guard let byte = buffer.getBytes(at: 0, length: 1) else {
|
||||||
print("No bytes received from device")
|
print("No bytes received from device")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
import CryptoKit
|
import CryptoKit
|
||||||
import NIOCore
|
import NIOCore
|
||||||
import Vapor
|
|
||||||
|
|
||||||
struct Message: Equatable, Hashable {
|
struct Message: Equatable, Hashable {
|
||||||
|
|
||||||
@ -20,9 +19,9 @@ struct Message: Equatable, Hashable {
|
|||||||
self.id = id
|
self.id = id
|
||||||
}
|
}
|
||||||
|
|
||||||
init(decodeFrom data: Data) {
|
init<T: Sequence>(decodeFrom data: T) where T.Element == UInt8 {
|
||||||
self.time = UInt32(data: data[data.startIndex..<data.startIndex+4])
|
self.time = UInt32(data: data.prefix(4))
|
||||||
self.id = UInt32(data: data[data.startIndex+4..<data.startIndex+8])
|
self.id = UInt32(data: data.dropFirst(4))
|
||||||
}
|
}
|
||||||
|
|
||||||
static var length: Int {
|
static var length: Int {
|
||||||
@ -59,16 +58,16 @@ struct Message: Equatable, Hashable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
init?(decodeFrom buffer: ByteBuffer) {
|
init?(decodeFrom buffer: ByteBuffer) {
|
||||||
guard let data = buffer.getData(at: 0, length: Message.length) else {
|
guard let data = buffer.getBytes(at: 0, length: Message.length) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
self.init(decodeFrom: data)
|
self.init(decodeFrom: data)
|
||||||
}
|
}
|
||||||
|
|
||||||
private init(decodeFrom data: Data) {
|
private init<T: Sequence>(decodeFrom data: T) where T.Element == UInt8 {
|
||||||
let count = SHA256Digest.byteCount
|
let count = SHA256Digest.byteCount
|
||||||
self.mac = data[data.startIndex..<data.startIndex+count]
|
self.mac = Data(data.prefix(count))
|
||||||
self.content = .init(decodeFrom: data.advanced(by: count))
|
self.content = .init(decodeFrom: Array(data.dropFirst(count)))
|
||||||
}
|
}
|
||||||
|
|
||||||
func isValid(using key: SymmetricKey) -> Bool {
|
func isValid(using key: SymmetricKey) -> Bool {
|
||||||
@ -86,13 +85,12 @@ struct Message: Equatable, Hashable {
|
|||||||
|
|
||||||
extension UInt32 {
|
extension UInt32 {
|
||||||
|
|
||||||
init(data: Data) {
|
init<T: Sequence>(data: T) where T.Element == UInt8 {
|
||||||
self = data
|
self = data
|
||||||
.reversed()
|
.reversed()
|
||||||
.enumerated()
|
.enumerated()
|
||||||
.map { UInt32($0.element) << ($0.offset * 8) }
|
.map { UInt32($0.element) << ($0.offset * 8) }
|
||||||
.reduce(0, +)
|
.reduce(0, +)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var encoded: Data {
|
var encoded: Data {
|
||||||
|
@ -27,15 +27,9 @@ enum MessageResult: UInt8 {
|
|||||||
case messageAccepted = 7
|
case messageAccepted = 7
|
||||||
|
|
||||||
|
|
||||||
/// The device produced an unknown error
|
|
||||||
case unknownDeviceError = 9
|
|
||||||
|
|
||||||
/// The request did not contain body data with the key
|
/// The request did not contain body data with the key
|
||||||
case noBodyData = 10
|
case noBodyData = 10
|
||||||
|
|
||||||
/// The body data could not be read
|
|
||||||
case corruptkeyData = 11
|
|
||||||
|
|
||||||
/// The device is not connected
|
/// The device is not connected
|
||||||
case deviceNotConnected = 12
|
case deviceNotConnected = 12
|
||||||
|
|
||||||
@ -64,12 +58,8 @@ extension MessageResult: CustomStringConvertible {
|
|||||||
return "Message counter invalid"
|
return "Message counter invalid"
|
||||||
case .messageAccepted:
|
case .messageAccepted:
|
||||||
return "Message accepted"
|
return "Message accepted"
|
||||||
case .unknownDeviceError:
|
|
||||||
return "The device experienced an unknown error"
|
|
||||||
case .noBodyData:
|
case .noBodyData:
|
||||||
return "No body data included in the request"
|
return "No body data included in the request"
|
||||||
case .corruptkeyData:
|
|
||||||
return "Key data corrupted"
|
|
||||||
case .deviceNotConnected:
|
case .deviceNotConnected:
|
||||||
return "Device not connected"
|
return "Device not connected"
|
||||||
case .deviceTimedOut:
|
case .deviceTimedOut:
|
||||||
|
@ -33,7 +33,7 @@ func routes(_ app: Application) throws {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Post a key to the device for unlocking.
|
Post a message to the device for unlocking.
|
||||||
|
|
||||||
The request returns one or `Message.length+1` bytes of data, where the first byte is the raw value of a `MessageResult`,
|
The request returns one or `Message.length+1` bytes of data, where the first byte is the raw value of a `MessageResult`,
|
||||||
and the optional following bytes contain the response message of the device. This request does not complete until either the device responds or the request times out. The timeout is specified by `KeyManagement.deviceTimeout`.
|
and the optional following bytes contain the response message of the device. This request does not complete until either the device responds or the request times out. The timeout is specified by `KeyManagement.deviceTimeout`.
|
||||||
@ -45,9 +45,9 @@ func routes(_ app: Application) throws {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Start a new websocket connection for the client to receive table updates from the server
|
Start a new websocket connection for the device to receive messages from the server
|
||||||
- Returns: Nothing
|
- Returns: Nothing
|
||||||
- Note: The first (and only) message from the client over the connection must be a valid session token.
|
- Note: The first message from the device over the connection must be a valid auth token.
|
||||||
*/
|
*/
|
||||||
app.webSocket(PublicAPI.socket.path) { req, socket in
|
app.webSocket(PublicAPI.socket.path) { req, socket in
|
||||||
socket.onBinary { _, data in
|
socket.onBinary { _, data in
|
||||||
|
@ -12,11 +12,11 @@ final class AppTests: XCTestCase {
|
|||||||
|
|
||||||
func testEncodingContent() {
|
func testEncodingContent() {
|
||||||
let input = Message.Content(time: 1234567890, id: 23456789)
|
let input = Message.Content(time: 1234567890, id: 23456789)
|
||||||
let data = input.encoded
|
let data = input.bytes
|
||||||
let output = Message.Content(decodeFrom: data)
|
let output = Message.Content(decodeFrom: data)
|
||||||
XCTAssertEqual(input, output)
|
XCTAssertEqual(input, output)
|
||||||
let data2 = Data([42, 42]) + data
|
let data2 = [42, 42] + data
|
||||||
let output2 = Message.Content(decodeFrom: Data(data2[2...]))
|
let output2 = Message.Content(decodeFrom: data2[2...])
|
||||||
XCTAssertEqual(input, output2)
|
XCTAssertEqual(input, output2)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,4 +42,12 @@ final class AppTests: XCTestCase {
|
|||||||
XCTAssertEqual(decoded!, input)
|
XCTAssertEqual(decoded!, input)
|
||||||
XCTAssertEqual(content, input.content)
|
XCTAssertEqual(content, input.content)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func testMessageTransmission() throws {
|
||||||
|
let app = Application(.testing)
|
||||||
|
defer { app.shutdown() }
|
||||||
|
try configure(app)
|
||||||
|
|
||||||
|
// How to open a socket via request?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user