172 lines
6.5 KiB
Swift
172 lines
6.5 KiB
Swift
//
|
|
// MqttDecodePublish.swift
|
|
// CocoaMQTT
|
|
//
|
|
// Created by liwei wang on 2021/7/27.
|
|
//
|
|
|
|
import Foundation
|
|
|
|
public class MqttDecodePublish: NSObject {
|
|
|
|
// 3.3.2.3 PUBLISH Properties
|
|
// 3.3.2.3.1 Property Length
|
|
public var propertyLength: Int?
|
|
// 3.3.2.3.2 Payload Format Indicator
|
|
public var payloadFormatIndicator: PayloadFormatIndicator?
|
|
// 3.3.2.3.3 Message Expiry Interval
|
|
public var messageExpiryInterval: UInt32?
|
|
// 3.3.2.3.4 Topic Alias
|
|
public var topicAlias: UInt16?
|
|
// 3.3.2.3.5 Response Topic
|
|
public var responseTopic: String?
|
|
// 3.3.2.3.6 Correlation Data
|
|
public var correlationData: [UInt8]?
|
|
// 3.3.2.3.7 Property
|
|
public var userProperty: [String: String]?
|
|
// 3.3.2.3.8 Subscription Identifier
|
|
public var subscriptionIdentifier: Int = 0
|
|
// 3.3.2.3.9 Content Type
|
|
public var contentType: String?
|
|
|
|
// public var applicationMessage: [UInt8]?
|
|
|
|
// 3.3.2.1 Topic Name
|
|
public var topic: String = ""
|
|
// 3.3.2.2 Packet Identifier
|
|
public var packetIdentifier: UInt16?
|
|
public var mqtt5DataIndex = 0
|
|
|
|
public func decodePublish(fixedHeader: UInt8, publishData: [UInt8]) {
|
|
// Topic Name
|
|
// 3.3.2.1 Topic Name
|
|
var dataIndex = 0
|
|
guard let result = unsignedByteToString(data: publishData, offset: dataIndex) else {
|
|
return
|
|
}
|
|
self.topic = result.resStr
|
|
dataIndex = result.newOffset
|
|
mqtt5DataIndex = dataIndex
|
|
|
|
printDebug("topic = \(topic)")
|
|
|
|
guard let recQos = CocoaMQTTQoS(rawValue: (fixedHeader & 0b0000_0110) >> 1) else {
|
|
return
|
|
}
|
|
|
|
// 3.3.2.2 Packet Identifier
|
|
// Packet Identifier
|
|
if recQos == .qos1 || recQos == .qos2 {
|
|
let IdentifierResult = integerCompute(data: publishData, formatType: formatInt.formatUint16.rawValue, offset: dataIndex)
|
|
packetIdentifier = UInt16(IdentifierResult!.res)
|
|
dataIndex = IdentifierResult!.newOffset
|
|
}
|
|
|
|
var protocolVersion = ""
|
|
if let storage = CocoaMQTTStorage() {
|
|
protocolVersion = storage.queryMQTTVersion()
|
|
}
|
|
|
|
if protocolVersion == "5.0" {
|
|
// 3.3.2.3.1 Property Length
|
|
// propertyLength
|
|
let propertyLengthVariableByteInteger = decodeVariableByteInteger(data: publishData, offset: dataIndex)
|
|
propertyLength = propertyLengthVariableByteInteger.res
|
|
dataIndex = propertyLengthVariableByteInteger.newOffset
|
|
mqtt5DataIndex = propertyLengthVariableByteInteger.newOffset
|
|
|
|
let occupyIndex = dataIndex
|
|
|
|
while dataIndex < occupyIndex + (propertyLength ?? 0) {
|
|
|
|
let resVariableByteInteger = decodeVariableByteInteger(data: publishData, offset: dataIndex)
|
|
dataIndex = resVariableByteInteger.newOffset
|
|
let propertyNameByte = resVariableByteInteger.res
|
|
guard let propertyName = CocoaMQTTPropertyName(rawValue: UInt8(propertyNameByte)) else {
|
|
break
|
|
}
|
|
switch propertyName.rawValue {
|
|
// 3.3.2.3.2 Payload Format Indicator
|
|
case CocoaMQTTPropertyName.payloadFormatIndicator.rawValue:
|
|
if publishData[dataIndex] & 0b0000_0001 > 0 {
|
|
payloadFormatIndicator = .utf8
|
|
} else {
|
|
payloadFormatIndicator = .unspecified
|
|
}
|
|
dataIndex += 1
|
|
|
|
// 3.3.2.3.3 Message Expiry Interval
|
|
case CocoaMQTTPropertyName.willExpiryInterval.rawValue:
|
|
let comRes = integerCompute(data: publishData, formatType: formatInt.formatUint32.rawValue, offset: dataIndex)
|
|
messageExpiryInterval = UInt32(comRes!.res)
|
|
dataIndex = comRes!.newOffset
|
|
|
|
// 3.3.2.3.4 Topic Alias
|
|
case CocoaMQTTPropertyName.topicAlias.rawValue:
|
|
let comRes = integerCompute(data: publishData, formatType: formatInt.formatUint16.rawValue, offset: dataIndex)
|
|
topicAlias = UInt16(comRes!.res)
|
|
dataIndex = comRes!.newOffset
|
|
|
|
// 3.3.2.3.5 Response Topic
|
|
case CocoaMQTTPropertyName.responseTopic.rawValue:
|
|
guard let result = unsignedByteToString(data: publishData, offset: dataIndex) else {
|
|
break
|
|
}
|
|
responseTopic = result.resStr
|
|
dataIndex = result.newOffset
|
|
|
|
// 3.3.2.3.6 Correlation Data
|
|
case CocoaMQTTPropertyName.correlationData.rawValue:
|
|
guard let result = unsignedByteToBinary(data: publishData, offset: dataIndex) else {
|
|
break
|
|
}
|
|
correlationData = result.resStr
|
|
dataIndex = result.newOffset
|
|
|
|
// 3.3.2.3.7 User Property
|
|
case CocoaMQTTPropertyName.userProperty.rawValue:
|
|
var key: String?
|
|
var value: String?
|
|
guard let keyRes = unsignedByteToString(data: publishData, offset: dataIndex) else {
|
|
break
|
|
}
|
|
key = keyRes.resStr
|
|
dataIndex = keyRes.newOffset
|
|
|
|
guard let valRes = unsignedByteToString(data: publishData, offset: dataIndex) else {
|
|
break
|
|
}
|
|
value = valRes.resStr
|
|
dataIndex = valRes.newOffset
|
|
|
|
if userProperty == nil {
|
|
userProperty = [:]
|
|
}
|
|
|
|
userProperty![key!] = value
|
|
|
|
// 3.3.2.3.8 Subscription Identifier
|
|
case CocoaMQTTPropertyName.subscriptionIdentifier.rawValue:
|
|
let valRes = decodeVariableByteInteger(data: publishData, offset: dataIndex)
|
|
subscriptionIdentifier = valRes.res
|
|
dataIndex = valRes.newOffset
|
|
|
|
// 3.3.2.3.9 Content Type
|
|
case CocoaMQTTPropertyName.contentType.rawValue:
|
|
guard let valRes = unsignedByteToString(data: publishData, offset: dataIndex) else {
|
|
break
|
|
}
|
|
contentType = valRes.resStr
|
|
dataIndex = valRes.newOffset
|
|
|
|
default:
|
|
return
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
}
|