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 {
/**
@ -42,14 +50,17 @@ extension Message {
/// The counter of the message (for freshness)
let id: UInt32
let deviceId: UInt8?
/**
Create new message content.
- Parameter time: The time of message creation,
- Parameter id: The counter of the message
*/
init(time: UInt32, id: UInt32) {
init(time: UInt32, id: UInt32, device: UInt8) {
self.time = time
self.id = id
self.deviceId = device
}
/**
@ -61,20 +72,29 @@ extension Message {
*/
init<T: Sequence>(decodeFrom data: T) where T.Element == UInt8 {
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
static var length: Int {
MemoryLayout<UInt32>.size * 2
MemoryLayout<UInt32>.size * 2 + 1
}
/// The message content encoded to 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 {
@ -96,6 +116,14 @@ extension Message {
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
var encoded: Data {
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
case messageAccepted = 7
/// The device id is invalid
case messageDeviceInvalid = 8
/// The request did not contain body data with the key
case noBodyData = 10
@ -61,6 +64,8 @@ extension MessageResult: CustomStringConvertible {
return "Message counter invalid"
case .messageAccepted:
return "Message accepted"
case .messageDeviceInvalid:
return "Invalid device ID"
case .noBodyData:
return "No body data included in the request"
case .deviceNotConnected:

View File

@ -11,7 +11,7 @@ final class AppTests: XCTestCase {
}
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 output = Message.Content(decodeFrom: data)
XCTAssertEqual(input, output)
@ -22,7 +22,7 @@ final class AppTests: XCTestCase {
func testEncodingMessage() {
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 buffer = ByteBuffer(data: data)
let output = Message(decodeFrom: buffer)
@ -31,7 +31,7 @@ final class AppTests: XCTestCase {
func testSigning() throws {
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)
XCTAssertTrue(input.isValid(using: key))