| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214 |
- //
- // Response.swift
- // RileyLinkBLEKit
- //
- // Copyright © 2018 Pete Schwamb. All rights reserved.
- //
- enum ResponseCode: UInt8 {
- case rxTimeout = 0xaa
- case commandInterrupted = 0xbb
- case zeroData = 0xcc
- case success = 0xdd
- case invalidParam = 0x11
- case unknownCommand = 0x22
- }
- protocol Response {
- var code: ResponseCode { get }
- init?(data: Data)
- init?(legacyData data: Data)
- }
- struct CodeResponse: Response {
- let code: ResponseCode
- init?(data: Data) {
- guard data.count == 1, let code = ResponseCode(rawValue: data[data.startIndex]) else {
- return nil
- }
- self.code = code
- }
- init?(legacyData data: Data) {
- guard data.count == 0 else {
- return nil
- }
- self.code = .success
- }
- }
- struct ReadRegisterResponse: Response {
- let code: ResponseCode
- let value: UInt8
-
- init?(data: Data) {
- guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
- return nil
- }
-
- self.init(code: code, value: data[data.startIndex.advanced(by: 1)])
- }
-
- init?(legacyData data: Data) {
- self.init(code: .success, value: data[0])
- }
-
- private init?(code: ResponseCode, value: UInt8) {
- self.code = code
- self.value = value
- }
- }
- struct UpdateRegisterResponse: Response {
- let code: ResponseCode
- init?(data: Data) {
- guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
- return nil
- }
- self.code = code
- }
- private enum LegacyCode: UInt8 {
- case success = 1
- case invalidRegister = 2
- var responseCode: ResponseCode {
- switch self {
- case .success:
- return .success
- case .invalidRegister:
- return .invalidParam
- }
- }
- }
- init?(legacyData data: Data) {
- guard data.count > 0, let code = LegacyCode(rawValue: data[data.startIndex])?.responseCode else {
- return nil
- }
- self.code = code
- }
- }
- struct GetVersionResponse: Response {
- let code: ResponseCode
- let version: String
- init?(data: Data) {
- guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
- return nil
- }
- self.init(code: code, versionData: data[data.startIndex.advanced(by: 1)...])
- }
- init?(legacyData data: Data) {
- self.init(code: .success, versionData: data)
- }
- private init?(code: ResponseCode, versionData: Data) {
- self.code = code
- guard let version = String(bytes: versionData, encoding: .utf8) else {
- return nil
- }
- self.version = version
- }
- }
- struct GetStatisticsResponse: Response {
- let code: ResponseCode
-
- let statistics: RileyLinkStatistics
- init?(data: Data) {
- guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
- return nil
- }
-
- self.init(code: code, data: data[data.startIndex.advanced(by: 1)...])
- }
-
- init?(legacyData data: Data) {
- self.init(code: .success, data: data)
- }
- private init?(code: ResponseCode, data: Data) {
- self.code = code
-
- guard data.count >= 16 else {
- return nil
- }
-
- let uptime = TimeInterval(milliseconds: Double(data[data.startIndex...].toBigEndian(UInt32.self)))
- let radioRxOverflowCount = data[data.startIndex.advanced(by: 4)...].toBigEndian(UInt16.self)
- let radioRxFifoOverflowCount = data[data.startIndex.advanced(by: 6)...].toBigEndian(UInt16.self)
- let packetRxCount = data[data.startIndex.advanced(by: 8)...].toBigEndian(UInt16.self)
- let packetTxCount = data[data.startIndex.advanced(by: 10)...].toBigEndian(UInt16.self)
- let crcFailureCount = data[data.startIndex.advanced(by: 12)...].toBigEndian(UInt16.self)
- let spiSyncFailureCount = data[data.startIndex.advanced(by: 14)...].toBigEndian(UInt16.self)
-
- self.statistics = RileyLinkStatistics(uptime: uptime, radioRxOverflowCount: radioRxOverflowCount, radioRxFifoOverflowCount: radioRxFifoOverflowCount, packetRxCount: packetRxCount, packetTxCount: packetTxCount, crcFailureCount: crcFailureCount, spiSyncFailureCount: spiSyncFailureCount)
- }
- }
- struct PacketResponse: Response {
- let code: ResponseCode
- let packet: RFPacket?
- init?(data: Data) {
- guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
- return nil
- }
- switch code {
- case .success:
- guard let packet = RFPacket(rfspyResponse: data[data.startIndex.advanced(by: 1)...]) else {
- return nil
- }
- self.packet = packet
- case .rxTimeout,
- .commandInterrupted,
- .zeroData,
- .invalidParam,
- .unknownCommand:
- self.packet = nil
- }
- self.code = code
- }
- init?(legacyData data: Data) {
- guard data.count > 0 else {
- return nil
- }
- packet = RFPacket(rfspyResponse: data)
- if packet != nil {
- code = .success
- } else {
- guard let code = ResponseCode(rawValue: data[data.startIndex]) else {
- return nil
- }
- self.code = code
- }
- }
- init(code: ResponseCode, packet: RFPacket?) {
- self.code = code
- self.packet = packet
- }
- }
|