Response.swift 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214
  1. //
  2. // Response.swift
  3. // RileyLinkBLEKit
  4. //
  5. // Copyright © 2018 Pete Schwamb. All rights reserved.
  6. //
  7. enum ResponseCode: UInt8 {
  8. case rxTimeout = 0xaa
  9. case commandInterrupted = 0xbb
  10. case zeroData = 0xcc
  11. case success = 0xdd
  12. case invalidParam = 0x11
  13. case unknownCommand = 0x22
  14. }
  15. protocol Response {
  16. var code: ResponseCode { get }
  17. init?(data: Data)
  18. init?(legacyData data: Data)
  19. }
  20. struct CodeResponse: Response {
  21. let code: ResponseCode
  22. init?(data: Data) {
  23. guard data.count == 1, let code = ResponseCode(rawValue: data[data.startIndex]) else {
  24. return nil
  25. }
  26. self.code = code
  27. }
  28. init?(legacyData data: Data) {
  29. guard data.count == 0 else {
  30. return nil
  31. }
  32. self.code = .success
  33. }
  34. }
  35. struct ReadRegisterResponse: Response {
  36. let code: ResponseCode
  37. let value: UInt8
  38. init?(data: Data) {
  39. guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
  40. return nil
  41. }
  42. self.init(code: code, value: data[data.startIndex.advanced(by: 1)])
  43. }
  44. init?(legacyData data: Data) {
  45. self.init(code: .success, value: data[0])
  46. }
  47. private init?(code: ResponseCode, value: UInt8) {
  48. self.code = code
  49. self.value = value
  50. }
  51. }
  52. struct UpdateRegisterResponse: Response {
  53. let code: ResponseCode
  54. init?(data: Data) {
  55. guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
  56. return nil
  57. }
  58. self.code = code
  59. }
  60. private enum LegacyCode: UInt8 {
  61. case success = 1
  62. case invalidRegister = 2
  63. var responseCode: ResponseCode {
  64. switch self {
  65. case .success:
  66. return .success
  67. case .invalidRegister:
  68. return .invalidParam
  69. }
  70. }
  71. }
  72. init?(legacyData data: Data) {
  73. guard data.count > 0, let code = LegacyCode(rawValue: data[data.startIndex])?.responseCode else {
  74. return nil
  75. }
  76. self.code = code
  77. }
  78. }
  79. struct GetVersionResponse: Response {
  80. let code: ResponseCode
  81. let version: String
  82. init?(data: Data) {
  83. guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
  84. return nil
  85. }
  86. self.init(code: code, versionData: data[data.startIndex.advanced(by: 1)...])
  87. }
  88. init?(legacyData data: Data) {
  89. self.init(code: .success, versionData: data)
  90. }
  91. private init?(code: ResponseCode, versionData: Data) {
  92. self.code = code
  93. guard let version = String(bytes: versionData, encoding: .utf8) else {
  94. return nil
  95. }
  96. self.version = version
  97. }
  98. }
  99. struct GetStatisticsResponse: Response {
  100. let code: ResponseCode
  101. let statistics: RileyLinkStatistics
  102. init?(data: Data) {
  103. guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
  104. return nil
  105. }
  106. self.init(code: code, data: data[data.startIndex.advanced(by: 1)...])
  107. }
  108. init?(legacyData data: Data) {
  109. self.init(code: .success, data: data)
  110. }
  111. private init?(code: ResponseCode, data: Data) {
  112. self.code = code
  113. guard data.count >= 16 else {
  114. return nil
  115. }
  116. let uptime = TimeInterval(milliseconds: Double(data[data.startIndex...].toBigEndian(UInt32.self)))
  117. let radioRxOverflowCount = data[data.startIndex.advanced(by: 4)...].toBigEndian(UInt16.self)
  118. let radioRxFifoOverflowCount = data[data.startIndex.advanced(by: 6)...].toBigEndian(UInt16.self)
  119. let packetRxCount = data[data.startIndex.advanced(by: 8)...].toBigEndian(UInt16.self)
  120. let packetTxCount = data[data.startIndex.advanced(by: 10)...].toBigEndian(UInt16.self)
  121. let crcFailureCount = data[data.startIndex.advanced(by: 12)...].toBigEndian(UInt16.self)
  122. let spiSyncFailureCount = data[data.startIndex.advanced(by: 14)...].toBigEndian(UInt16.self)
  123. self.statistics = RileyLinkStatistics(uptime: uptime, radioRxOverflowCount: radioRxOverflowCount, radioRxFifoOverflowCount: radioRxFifoOverflowCount, packetRxCount: packetRxCount, packetTxCount: packetTxCount, crcFailureCount: crcFailureCount, spiSyncFailureCount: spiSyncFailureCount)
  124. }
  125. }
  126. struct PacketResponse: Response {
  127. let code: ResponseCode
  128. let packet: RFPacket?
  129. init?(data: Data) {
  130. guard data.count > 0, let code = ResponseCode(rawValue: data[data.startIndex]) else {
  131. return nil
  132. }
  133. switch code {
  134. case .success:
  135. guard let packet = RFPacket(rfspyResponse: data[data.startIndex.advanced(by: 1)...]) else {
  136. return nil
  137. }
  138. self.packet = packet
  139. case .rxTimeout,
  140. .commandInterrupted,
  141. .zeroData,
  142. .invalidParam,
  143. .unknownCommand:
  144. self.packet = nil
  145. }
  146. self.code = code
  147. }
  148. init?(legacyData data: Data) {
  149. guard data.count > 0 else {
  150. return nil
  151. }
  152. packet = RFPacket(rfspyResponse: data)
  153. if packet != nil {
  154. code = .success
  155. } else {
  156. guard let code = ResponseCode(rawValue: data[data.startIndex]) else {
  157. return nil
  158. }
  159. self.code = code
  160. }
  161. }
  162. init(code: ResponseCode, packet: RFPacket?) {
  163. self.code = code
  164. self.packet = packet
  165. }
  166. }