Command.swift 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. //
  2. // Command.swift
  3. // RileyLinkBLEKit
  4. //
  5. // Copyright © 2017 Pete Schwamb. All rights reserved.
  6. //
  7. import Foundation
  8. // CmdBase
  9. enum RileyLinkCommand: UInt8 {
  10. case getState = 1
  11. case getVersion = 2
  12. case getPacket = 3
  13. case sendPacket = 4
  14. case sendAndListen = 5
  15. case updateRegister = 6
  16. case reset = 7
  17. case led = 8
  18. case readRegister = 9
  19. case setModeRegisters = 10
  20. case setSWEncoding = 11
  21. case setPreamble = 12
  22. case resetRadioConfig = 13
  23. case getStatistics = 14
  24. }
  25. enum RileyLinkLEDType: UInt8 {
  26. case green = 0
  27. case blue = 1
  28. }
  29. protocol Command {
  30. associatedtype ResponseType: Response
  31. var data: Data { get }
  32. }
  33. struct GetPacket: Command {
  34. typealias ResponseType = PacketResponse
  35. let listenChannel: UInt8
  36. let timeoutMS: UInt32
  37. init(listenChannel: UInt8, timeoutMS: UInt32) {
  38. self.listenChannel = listenChannel
  39. self.timeoutMS = timeoutMS
  40. }
  41. var data: Data {
  42. var data = Data([
  43. RileyLinkCommand.getPacket.rawValue,
  44. listenChannel
  45. ])
  46. data.appendBigEndian(timeoutMS)
  47. return data
  48. }
  49. }
  50. struct GetVersion: Command {
  51. typealias ResponseType = GetVersionResponse
  52. var data: Data {
  53. return Data([RileyLinkCommand.getVersion.rawValue])
  54. }
  55. }
  56. struct SendAndListen: Command {
  57. typealias ResponseType = PacketResponse
  58. let outgoing: Data
  59. /// In general, 0 = meter, cgm. 2 = pump
  60. let sendChannel: UInt8
  61. /// 0 = no repeat, i.e. only one packet. 1 repeat = 2 packets sent total.
  62. let repeatCount: UInt8
  63. let delayBetweenPacketsMS: UInt16
  64. let listenChannel: UInt8
  65. let timeoutMS: UInt32
  66. let retryCount: UInt8
  67. let preambleExtensionMS: UInt16
  68. let firmwareVersion: RadioFirmwareVersion
  69. init(outgoing: Data, sendChannel: UInt8, repeatCount: UInt8, delayBetweenPacketsMS: UInt16, listenChannel: UInt8, timeoutMS: UInt32, retryCount: UInt8, preambleExtensionMS: UInt16, firmwareVersion: RadioFirmwareVersion) {
  70. self.outgoing = outgoing
  71. self.sendChannel = sendChannel
  72. self.repeatCount = repeatCount
  73. self.delayBetweenPacketsMS = delayBetweenPacketsMS
  74. self.listenChannel = listenChannel
  75. self.timeoutMS = timeoutMS
  76. self.retryCount = retryCount
  77. self.preambleExtensionMS = preambleExtensionMS
  78. self.firmwareVersion = firmwareVersion
  79. }
  80. var data: Data {
  81. var data = Data([
  82. RileyLinkCommand.sendAndListen.rawValue,
  83. sendChannel,
  84. repeatCount
  85. ])
  86. if firmwareVersion.supports16BitPacketDelay {
  87. data.appendBigEndian(delayBetweenPacketsMS)
  88. } else {
  89. data.append(UInt8(clamping: Int(delayBetweenPacketsMS)))
  90. }
  91. data.append(listenChannel);
  92. data.appendBigEndian(timeoutMS)
  93. data.append(retryCount)
  94. if firmwareVersion.supportsPreambleExtension {
  95. data.appendBigEndian(preambleExtensionMS)
  96. }
  97. data.append(outgoing)
  98. return data
  99. }
  100. }
  101. struct SendPacket: Command {
  102. typealias ResponseType = CodeResponse
  103. let outgoing: Data
  104. /// In general, 0 = meter, cgm. 2 = pump
  105. let sendChannel: UInt8
  106. /// 0 = no repeat, i.e. only one packet. 1 repeat = 2 packets sent total.
  107. let repeatCount: UInt8
  108. let delayBetweenPacketsMS: UInt16
  109. let preambleExtensionMS: UInt16
  110. let firmwareVersion: RadioFirmwareVersion
  111. init(outgoing: Data, sendChannel: UInt8, repeatCount: UInt8, delayBetweenPacketsMS: UInt16, preambleExtensionMS: UInt16, firmwareVersion: RadioFirmwareVersion) {
  112. self.outgoing = outgoing
  113. self.sendChannel = sendChannel
  114. self.repeatCount = repeatCount
  115. self.delayBetweenPacketsMS = delayBetweenPacketsMS
  116. self.preambleExtensionMS = preambleExtensionMS
  117. self.firmwareVersion = firmwareVersion;
  118. }
  119. var data: Data {
  120. var data = Data([
  121. RileyLinkCommand.sendPacket.rawValue,
  122. sendChannel,
  123. repeatCount,
  124. ])
  125. if firmwareVersion.supports16BitPacketDelay {
  126. data.appendBigEndian(delayBetweenPacketsMS)
  127. } else {
  128. data.append(UInt8(clamping: Int(delayBetweenPacketsMS)))
  129. }
  130. if firmwareVersion.supportsPreambleExtension {
  131. data.appendBigEndian(preambleExtensionMS)
  132. }
  133. data.append(outgoing)
  134. return data
  135. }
  136. }
  137. struct RegisterSetting {
  138. let address: CC111XRegister
  139. let value: UInt8
  140. }
  141. struct UpdateRegister: Command {
  142. typealias ResponseType = UpdateRegisterResponse
  143. enum Response: UInt8 {
  144. case success = 1
  145. case invalidRegister = 2
  146. }
  147. let register: RegisterSetting
  148. let firmwareVersion: RadioFirmwareVersion
  149. init(_ address: CC111XRegister, value: UInt8, firmwareVersion: RadioFirmwareVersion) {
  150. register = RegisterSetting(address: address, value: value)
  151. self.firmwareVersion = firmwareVersion
  152. }
  153. var data: Data {
  154. var data = Data([
  155. RileyLinkCommand.updateRegister.rawValue,
  156. register.address.rawValue,
  157. register.value
  158. ])
  159. if firmwareVersion.needsExtraByteForUpdateRegisterCommand {
  160. data.append(0)
  161. }
  162. return data
  163. }
  164. }
  165. struct ReadRegister: Command {
  166. typealias ResponseType = ReadRegisterResponse
  167. enum Response: UInt8 {
  168. case success = 1
  169. case invalidRegister = 2
  170. }
  171. let address: CC111XRegister
  172. let firmwareVersion: RadioFirmwareVersion
  173. init(_ address: CC111XRegister, firmwareVersion: RadioFirmwareVersion) {
  174. self.address = address
  175. self.firmwareVersion = firmwareVersion
  176. }
  177. var data: Data {
  178. var data = Data([
  179. RileyLinkCommand.readRegister.rawValue,
  180. address.rawValue,
  181. ])
  182. if firmwareVersion.needsExtraByteForReadRegisterCommand {
  183. data.append(address.rawValue)
  184. }
  185. return data
  186. }
  187. }
  188. struct SetModeRegisters: Command {
  189. typealias ResponseType = UpdateRegisterResponse
  190. enum RegisterModeType: UInt8 {
  191. case tx = 0x01
  192. case rx = 0x02
  193. }
  194. private var settings: [RegisterSetting] = []
  195. let registerMode: RegisterModeType
  196. mutating func append(_ registerSetting: RegisterSetting) {
  197. settings.append(registerSetting)
  198. }
  199. var data: Data {
  200. var data = Data([
  201. RileyLinkCommand.setModeRegisters.rawValue,
  202. registerMode.rawValue
  203. ])
  204. for setting in settings {
  205. data.append(setting.address.rawValue)
  206. data.append(setting.value)
  207. }
  208. return data
  209. }
  210. }
  211. struct SetSoftwareEncoding: Command {
  212. typealias ResponseType = CodeResponse
  213. let encodingType: SoftwareEncodingType
  214. init(_ encodingType: SoftwareEncodingType) {
  215. self.encodingType = encodingType
  216. }
  217. var data: Data {
  218. return Data([
  219. RileyLinkCommand.setSWEncoding.rawValue,
  220. encodingType.rawValue
  221. ])
  222. }
  223. }
  224. struct SetPreamble: Command {
  225. typealias ResponseType = CodeResponse
  226. let preambleValue: UInt16
  227. init(_ value: UInt16) {
  228. self.preambleValue = value
  229. }
  230. var data: Data {
  231. var data = Data([RileyLinkCommand.setPreamble.rawValue])
  232. data.appendBigEndian(preambleValue)
  233. return data
  234. }
  235. }
  236. struct SetLEDMode: Command {
  237. typealias ResponseType = CodeResponse
  238. let led: RileyLinkLEDType
  239. let mode: RileyLinkLEDMode
  240. init(_ led: RileyLinkLEDType, mode: RileyLinkLEDMode) {
  241. self.led = led
  242. self.mode = mode
  243. }
  244. var data: Data {
  245. return Data([RileyLinkCommand.led.rawValue, led.rawValue, mode.rawValue])
  246. }
  247. }
  248. struct ResetRadioConfig: Command {
  249. typealias ResponseType = CodeResponse
  250. var data: Data {
  251. return Data([RileyLinkCommand.resetRadioConfig.rawValue])
  252. }
  253. }
  254. struct GetStatistics: Command {
  255. typealias ResponseType = GetStatisticsResponse
  256. var data: Data {
  257. return Data([RileyLinkCommand.getStatistics.rawValue])
  258. }
  259. }