PodInfoPulseLog.swift 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. //
  2. // PodInfoPulseLog.swift
  3. // OmniKit
  4. //
  5. // Created by Eelke Jager on 26/09/2018.
  6. // Copyright © 2018 Pete Schwamb. All rights reserved.
  7. //
  8. import Foundation
  9. // Type $50 Pod Info returns (up to) the most recent 50 32-bit pulse log entries
  10. public struct PodInfoPulseLogRecent : PodInfo {
  11. // CMD 1 2 3 4 5 6 7 8
  12. // DATA 0 1 2 3 4 5 6
  13. // 02 LL 50 IIII XXXXXXXX ...
  14. public let podInfoType : PodInfoResponseSubType = .pulseLogRecent
  15. public let indexLastEntry: Int // the pulse # for last pulse log entry
  16. public let nEntries : Int // how many 32-bit pulse entries returned (calculated)
  17. public let pulseLog : [UInt32]
  18. public let data : Data
  19. public init(encodedData: Data) throws {
  20. let logStartByteOffset = 3 // starting byte offset of the pulse log in DATA
  21. let nLogBytesReturned = encodedData.count - logStartByteOffset
  22. guard encodedData.count >= logStartByteOffset && (nLogBytesReturned & 0x3) == 0 else {
  23. throw MessageBlockError.notEnoughData // not enough data to start log or a non-integral # of pulse log entries
  24. }
  25. self.nEntries = nLogBytesReturned / MemoryLayout<UInt32>.size
  26. self.indexLastEntry = Int((UInt16(encodedData[1]) << 8) | UInt16(encodedData[2]))
  27. self.pulseLog = createPulseLog(encodedData: encodedData, logStartByteOffset: logStartByteOffset, nEntries: self.nEntries)
  28. self.data = encodedData
  29. }
  30. }
  31. // Type $51 Pod info returns (up to) the most previous 50 32-bit pulse log entries
  32. public struct PodInfoPulseLogPrevious : PodInfo {
  33. // CMD 1 2 3 4 5 6 7 8
  34. // DATA 0 1 2 3 4 5 6
  35. // 02 LL 51 NNNN XXXXXXXX ...
  36. public let podInfoType : PodInfoResponseSubType = .pulseLogPrevious
  37. public let nEntries : Int // how many 32-bit pulse log entries returned
  38. public let pulseLog : [UInt32]
  39. public let data : Data
  40. public init(encodedData: Data) throws {
  41. let logStartByteOffset = 3 // starting byte offset of the pulse log in DATA
  42. let nLogBytesReturned = encodedData.count - logStartByteOffset
  43. guard encodedData.count >= logStartByteOffset && (nLogBytesReturned & 0x3) == 0 else {
  44. throw MessageBlockError.notEnoughData // first 3 bytes missing or non-integral # of pulse log entries
  45. }
  46. let nEntriesCalculated = nLogBytesReturned / MemoryLayout<UInt32>.size
  47. self.nEntries = Int((UInt16(encodedData[1]) << 8) | UInt16(encodedData[2]))
  48. // verify we actually got all the reported entries
  49. if self.nEntries > nEntriesCalculated {
  50. throw MessageBlockError.notEnoughData // some pulse log entry count mismatch issue
  51. }
  52. self.pulseLog = createPulseLog(encodedData: encodedData, logStartByteOffset: logStartByteOffset, nEntries: self.nEntries)
  53. self.data = encodedData
  54. }
  55. }
  56. func createPulseLog(encodedData: Data, logStartByteOffset: Int, nEntries: Int) -> [UInt32] {
  57. var pulseLog: [UInt32] = Array(repeating: 0, count: nEntries)
  58. var index = 0
  59. while index < nEntries {
  60. pulseLog[index] = encodedData[(logStartByteOffset+(index*4))...].toBigEndian(UInt32.self)
  61. index += 1
  62. }
  63. return pulseLog
  64. }
  65. extension BinaryInteger {
  66. var binaryDescription: String {
  67. var binaryString = ""
  68. var internalNumber = self
  69. var counter = 0
  70. for _ in (1...self.bitWidth) {
  71. binaryString.insert(contentsOf: "\(internalNumber & 1)", at: binaryString.startIndex)
  72. internalNumber >>= 1
  73. counter += 1
  74. if counter % 8 == 0 {
  75. binaryString.insert(contentsOf: " ", at: binaryString.startIndex)
  76. }
  77. }
  78. return binaryString
  79. }
  80. }
  81. func pulseLogString(pulseLogEntries: [UInt32], lastPulseNumber: Int) -> String {
  82. var str: String = "Pulse eeeeee0a pppliiib cccccccc dfgggggg\n"
  83. var index = pulseLogEntries.count - 1
  84. var pulseNumber = lastPulseNumber
  85. while index >= 0 {
  86. str += String(format: "%04d:", pulseNumber) + UInt32(pulseLogEntries[index]).binaryDescription + "\n"
  87. index -= 1
  88. pulseNumber -= 1
  89. }
  90. return str + "\n"
  91. }