import Foundation enum BluetoothRequest { /** * Request the number of bytes already recorded * * Request: * - No additional bytes expected * * Response: * - `BluetoothResponseType.success` * - the number of recorded bytes as a `Uint16` (2 bytes) * - the number of seconds until the next measurement as a `Uint16` (2 bytes) * - the number of seconds between measurements as a `Uint16` (2 bytes) * - the number of measurements as a `Uint16` (2 bytes) * - the maximum number of bytes to request as a `Uint16` (2 bytes) * - the number of seconds since power on as a `Uint32` (4 bytes) */ case getInfo /** * Request recording data * * Request: * - Bytes 1-2: Memory offset (`UInt16`) * - Bytes 3-4: Number of bytes (`UInt16`) * * Response: * - `BluetoothResponseType.success`, plus the requested bytes * - `BluetoothResponseType.responseTooLarge` if too many bytes are requested */ case getRecordingData(offset: Int, count: Int) /** * Request deletion of recordings * * Request: * - Bytes 1-2: Number of bytes to clear (uint16_t) * * Response: * - `BluetoothResponseType.success` * - `BluetoothResponseType.invalidNumberOfBytesToDelete`, if the number of bytes does not match. * This may happen when a new temperature recording is performed in between calls */ case clearRecordingBuffer(byteCount: Int) var serialized: Data { let firstByte = Data([byte]) switch self { case .getInfo: return firstByte case .getRecordingData(let offset, let count): return firstByte + count.twoByteData + offset.twoByteData case .clearRecordingBuffer(let byteCount): return firstByte + byteCount.twoByteData } } var byte: UInt8 { switch self { case .getInfo: return 0 case .getRecordingData: return 1 case .clearRecordingBuffer: return 2 } } } private extension Int { var twoByteData: Data { let value = UInt16(clamping: self) return Data([value.low, value.high]) } } private extension UInt16 { var low: UInt8 { UInt8(self & 0xFF) } var high: UInt8 { UInt8((self >> 8) & 0xFF) } }