Update API with device id

This commit is contained in:
Christoph Hagen 2023-08-08 15:17:59 +02:00
parent 23fd5055cd
commit 9dd0045c4b
3 changed files with 40 additions and 7 deletions

View File

@ -29,6 +29,14 @@ struct Message: Equatable, Hashable {
} }
} }
extension Message: Codable {
enum CodingKeys: Int, CodingKey {
case mac = 1
case content = 2
}
}
extension Message { extension Message {
/** /**
@ -42,14 +50,17 @@ extension Message {
/// The counter of the message (for freshness) /// The counter of the message (for freshness)
let id: UInt32 let id: UInt32
let deviceId: UInt8?
/** /**
Create new message content. Create new message content.
- Parameter time: The time of message creation, - Parameter time: The time of message creation,
- Parameter id: The counter of the message - Parameter id: The counter of the message
*/ */
init(time: UInt32, id: UInt32) { init(time: UInt32, id: UInt32, device: UInt8) {
self.time = time self.time = time
self.id = id self.id = id
self.deviceId = device
} }
/** /**
@ -61,20 +72,29 @@ extension Message {
*/ */
init<T: Sequence>(decodeFrom data: T) where T.Element == UInt8 { init<T: Sequence>(decodeFrom data: T) where T.Element == UInt8 {
self.time = UInt32(data: Data(data.prefix(MemoryLayout<UInt32>.size))) self.time = UInt32(data: Data(data.prefix(MemoryLayout<UInt32>.size)))
self.id = UInt32(data: Data(data.dropFirst(MemoryLayout<UInt32>.size))) self.id = UInt32(data: Data(data.dropLast().suffix(MemoryLayout<UInt32>.size)))
self.deviceId = data.suffix(1).last!
} }
/// The byte length of an encoded message content /// The byte length of an encoded message content
static var length: Int { static var length: Int {
MemoryLayout<UInt32>.size * 2 MemoryLayout<UInt32>.size * 2 + 1
} }
/// The message content encoded to data /// The message content encoded to data
var encoded: Data { var encoded: Data {
time.encoded + id.encoded time.encoded + id.encoded + Data([deviceId ?? 0])
}
} }
} }
extension Message.Content: Codable {
enum CodingKeys: Int, CodingKey {
case time = 1
case id = 2
case deviceId = 3
}
} }
extension Message { extension Message {
@ -96,6 +116,14 @@ extension Message {
self.init(decodeFrom: data) self.init(decodeFrom: data)
} }
init?(decodeFrom data: Data, index: inout Int) {
guard index + Message.length <= data.count else {
return nil
}
self.init(decodeFrom: data.advanced(by: index))
index += Message.length
}
/// The message encoded to data /// The message encoded to data
var encoded: Data { var encoded: Data {
mac + content.encoded mac + content.encoded

View File

@ -26,6 +26,9 @@ enum MessageResult: UInt8 {
/// The key was accepted by the device, and the door will be opened /// The key was accepted by the device, and the door will be opened
case messageAccepted = 7 case messageAccepted = 7
/// The device id is invalid
case messageDeviceInvalid = 8
/// 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
@ -61,6 +64,8 @@ extension MessageResult: CustomStringConvertible {
return "Message counter invalid" return "Message counter invalid"
case .messageAccepted: case .messageAccepted:
return "Message accepted" return "Message accepted"
case .messageDeviceInvalid:
return "Invalid device ID"
case .noBodyData: case .noBodyData:
return "No body data included in the request" return "No body data included in the request"
case .deviceNotConnected: case .deviceNotConnected:

View File

@ -11,7 +11,7 @@ final class AppTests: XCTestCase {
} }
func testEncodingContent() { func testEncodingContent() {
let input = Message.Content(time: 1234567890, id: 23456789) let input = Message.Content(time: 1234567890, id: 23456789, device: 0)
let data = Array(input.encoded) let data = Array(input.encoded)
let output = Message.Content(decodeFrom: data) let output = Message.Content(decodeFrom: data)
XCTAssertEqual(input, output) XCTAssertEqual(input, output)
@ -22,7 +22,7 @@ final class AppTests: XCTestCase {
func testEncodingMessage() { func testEncodingMessage() {
let input = Message(mac: Data(repeating: 42, count: 32), let input = Message(mac: Data(repeating: 42, count: 32),
content: Message.Content(time: 1234567890, id: 23456789)) content: Message.Content(time: 1234567890, id: 23456789, device: 0))
let data = input.encoded let data = input.encoded
let buffer = ByteBuffer(data: data) let buffer = ByteBuffer(data: data)
let output = Message(decodeFrom: buffer) let output = Message(decodeFrom: buffer)
@ -31,7 +31,7 @@ final class AppTests: XCTestCase {
func testSigning() throws { func testSigning() throws {
let key = SymmetricKey(size: .bits256) let key = SymmetricKey(size: .bits256)
let content = Message.Content(time: 1234567890, id: 23456789) let content = Message.Content(time: 1234567890, id: 23456789, device: 0)
let input = content.authenticate(using: key) let input = content.authenticate(using: key)
XCTAssertTrue(input.isValid(using: key)) XCTAssertTrue(input.isValid(using: key))