Exemplo n.º 1
0
    def generatePacketData(packetID: int, reasonCode: int, reasonString: str,
                           userProperties: dict) -> bytes:
        """
		userProperties e un dictionar cu cheie string si valori de tip lista de string
		"""
        fixed = b"\x50"
        packet_id = struct.pack("!H", packetID)
        variable = packet_id + struct.pack("!B", reasonCode)
        properties = b"\x1f" + CustomUTF8.encode(reasonString)
        for key in userProperties.keys():
            for value in userProperties[key]:
                properties += b"\x26" + CustomUTF8.encode(
                    key) + CustomUTF8.encode(value)
        propertyLength = VariableByte.encode(len(properties))
        variable += propertyLength
        variable += properties
        remainingLength = VariableByte.encode(len(variable))
        fixed += remainingLength
        return fixed + variable
Exemplo n.º 2
0
	def generatePacketData(packetID: int, reasonString:str, userProperties:dict, payload:list) -> bytes:
		fixed = b"\x90"
		#TODO : add remaining length
		
		variable = struct.pack("!H", packetID)
		props = b"\x1F"+CustomUTF8.encode(reasonString)
			
		for key in userProperties.keys():
			for value in userProperties[key]:
				props+=b"\x26"+CustomUTF8.encode(key)+CustomUTF8.encode(value)
		variable+=VariableByte.encode(len(props))+props

		remainingLength = VariableByte.encode(len(variable))
		fixed+=remainingLength

		payload_data = b""

		for response_reason_code in payload:
			payload_data += struct.pack("!B", response_reason_code)

		return fixed+variable+payload_data
Exemplo n.º 3
0
 def parseFixedHeader(self):
     fixed_part = self.data[:1]
     num = b""
     for byte in self.data[1:]:
         num += struct.pack("!B", byte)
         if byte < 0x80:
             break
     required = len(num)
     self.fixed['type'], self.fixed['remainingLength'] = struct.unpack(
         "!B{}s".format(required), fixed_part + num)
     self.fixed['type'] >>= 4
     self.fixed['remainingLength'] = VariableByte.decode(
         self.fixed['remainingLength'])
     self.fixed_size = 1 + required
Exemplo n.º 4
0
    def parseVariableHeader(self):
        variableHeader = self.data[self.fixed_size:]
        self.variable['packet_id'] = struct.unpack("!H", variableHeader[:2])[0]
        variableHeader = variableHeader[2:]

        # 2 bytes so far

        properties = variableHeader
        num = b""
        for byte in properties:
            num += struct.pack("!B", byte)
            if byte < 0x80:
                break
        required = len(num)

        self.variable['propertyLength'] = struct.unpack(
            "!{}s".format(required), num)[0]
        self.variable['propertyLength'] = VariableByte.decode(
            self.variable['propertyLength'])

        self.variable['properties'] = {}
        self.variable['properties']['userProperty'] = {}
        self.variable_size = 2 + self.variable['propertyLength']
        properties = properties[required:]

        i = 0
        while i < self.variable['propertyLength']:
            if properties[i] == 0x0B:
                if 'subscription_identifier' not in self.variable[
                        'properties'].keys():
                    self.variable['properties'][
                        'subscription_identifier'] = struct.unpack(
                            "!B", properties[i + 1:i + 2])[0]
                else:
                    raise MQTTError(
                        "Malformed Packet: Subscription Identifier already exist"
                    )
            if properties[i] == 0x26:
                offset1, str1 = readCustomUTF8String(properties[i + 1:])
                offset2, str2 = readCustomUTF8String(properties[i + 1 +
                                                                offset1:])
                if str1 not in self.variable['properties'][
                        'userProperty'].keys():
                    self.variable['properties']['userProperty'][str1] = [str2]
                else:
                    self.variable['properties']['userProperty'][str1].append(
                        str2)
                i += offset1 + offset2
            i = i + 1
Exemplo n.º 5
0
class SubscribePacket(MQTTPacket):
    def __init__(self, data):
        self.data = data
        self.fixed = {}
        self.fixed_size = 0
        self.variable = {}
        self.variable_size = 0
        self.payload = {}
        self.payload_size = 0

    def parseFixedHeader(self):
        fixed_part = self.data[:1]
	num=b""
	for byte in self.data[1:]:
	    num+=struct.pack("!B", byte)
		if byte<0x80:
		    break
	required=len(num)
	self.fixed['type'], self.fixed['remainingLength'] = struct.unpack("!B{}s".format(required), fixed_part+num)
        if self.fixed['type'] & 0x0F != 0x02:
            raise MQTTError("Malformed Packet")
	self.fixed['type']>>=4
	self.fixed['remainingLength']=VariableByte.decode(self.fixed['remainingLength'])
	self.fixed_size=1+required
Exemplo n.º 6
0
    def parseVariableHeader(self):
        variableHeader = self.data[self.fixed_size:]

        #pubrec packed id
        packet_id_MSB, packet_id_LSB = struct.unpack("!2b", variableHeader[:2])
        self.variable['packet_id'] = (packet_id_MSB << 8) + packet_id_LSB
        variableHeader = variableHeader[2:]

        #pubrec reason code
        pubrec_reason_code = struct.unpack("!B", variableHeader[:1])[0]
        self.variable['pubrec_reason_code'] = pubrec_reason_code
        if (self.fixed['remainingLength'] == 2):
            self.variable['pubrec_reason_code'] = 0x00
        variableHeader = variableHeader[1:]

        #properties can be omitted if the reason code is Success
        #3 bytes so far (1 byte from packet_id_MSB + 1 byte from packet_id_LSB + 1 byte from reason code), this offset will help me for properties index
        #in case if reason code isn't Success, properties can't be omitted

        properties = self.data[self.fixed_size + 3:]

        #in num I add the properties byte by byte
        num = b""
        for byte in properties:
            num += struct.pack("!B", byte)
            if byte < 0x80:
                break
        required = len(num)

        self.variable['propertyLength'] = struct.unpack(
            "!{}s".format(required), num)[0]

        #i will decode the byte format in order to have an integer which is in fact the length of properties
        self.variable['propertyLength'] = VariableByte.decode(
            self.variable['propertyLength'])
        #print("prop length:" + str(self.variable['propertyLength']))

        if (self.fixed['remainingLength'] < 4):
            self.variable['propertyLength'] = 0
        else:
            self.variable['properties'] = {}
            self.variable['properties']['userProperty'] = {}

            #my variable header is composed by the 3 bytes from above + all the properties
            #it means that its length is the sum of 3 bytes from above and the length of properties
            self.variable_size = self.variable['propertyLength'] + 3

            properties = properties[required:]

            i = 0
            while i < self.variable['propertyLength']:
                if properties[i] == 0x1f:
                    if 'reason_string' not in self.variable['properties'].keys(
                    ):
                        OFFSET_TO_READ_START = i + 1
                        OFFSET_TO_READ_END = i + 3
                        to_read = properties[
                            OFFSET_TO_READ_START:
                            OFFSET_TO_READ_END]  #octetii care arata lungimea
                        #print("to read: " + str(to_read))
                        efective_length = struct.unpack(
                            "!H", to_read
                        )[0]  #transf in nr => lungimea stringului meu de 2 bytes
                        #print("efective_lentgh: " + str(efective_length))
                        self.variable['properties'][
                            'reason_string'] = CustomUTF8.decode(
                                struct.unpack(
                                    "!{}s".format(2 + efective_length),
                                    properties[i + 1:i + 3 +
                                               efective_length])[0])
                        i = i + 2 + efective_length
                    else:
                        raise MQTTError(
                            "Malformed Packet : reason string already exists")
                if properties[i] == 0x26:
                    OFFSET_TO_READ_1_START = i + 1
                    OFFSET_TO_READ_1_END = i + 3
                    to_read = properties[
                        OFFSET_TO_READ_1_START:OFFSET_TO_READ_1_END]
                    str1size = struct.unpack("!H", to_read)[0]
                    str1 = struct.unpack(
                        "!{}s".format(str1size + OFFSET_TO_READ_1_END -
                                      OFFSET_TO_READ_1_START),
                        properties[
                            OFFSET_TO_READ_1_START:OFFSET_TO_READ_1_END +
                            str1size])[0]
                    OFFSET_TO_READ_2_START = i + 3 + str1size
                    OFFSET_TO_READ_2_END = i + 5 + str1size
                    to_read2 = properties[
                        OFFSET_TO_READ_2_START:OFFSET_TO_READ_2_END]
                    str2size = struct.unpack("!H", to_read2)[0]
                    str2 = struct.unpack(
                        "!{}s".format(str2size + OFFSET_TO_READ_2_END -
                                      OFFSET_TO_READ_2_START),
                        properties[
                            OFFSET_TO_READ_2_START:OFFSET_TO_READ_2_END +
                            str2size])[0]
                    if CustomUTF8.decode(str1) not in self.variable[
                            'properties']['userProperty'].keys():
                        self.variable['properties']['userProperty'][
                            CustomUTF8.decode(str1)] = [
                                CustomUTF8.decode(str2)
                            ]
                    else:
                        self.variable['properties']['userProperty'][
                            CustomUTF8.decode(str1)].append(
                                CustomUTF8.decode(str2))
                        i += 4 + len(CustomUTF8.decode(str1)) + len(
                            CustomUTF8.decode(str2))
                i = i + 1
Exemplo n.º 7
0

if __name__ == "__main__":
    #fixed header
    fixed = b"\x50"

    #variable header
    packet_id = b"\x05\x02"
    pubrec_reason_code = b"\x83"
    reason_string = b"\x1f" + CustomUTF8.encode("$sys/rcp")
    userProperty = b"\x26" + CustomUTF8.encode(
        "Munteanu_Letitia") + CustomUTF8.encode("Ioana")

    #properties
    properties = reason_string + userProperty
    property_length = VariableByte.encode(len(properties))

    variableHeader = packet_id + pubrec_reason_code + property_length + properties
    length_of_variable_header = len(variableHeader)

    remainingLength = VariableByte.encode(length_of_variable_header)
    #print("RL:" + str(remainingLength))

    data = fixed + remainingLength + variableHeader
    data = struct.pack("!{}s".format(len(data)), data)

    packet = PubrecPacket(data)
    packet.parseFixedHeader()
    packet.parseVariableHeader()
    print(packet.fixed)
    print(packet.variable)
Exemplo n.º 8
0
    def parseVariableHeader(self):
        variableHeader = self.data[self.fixed_size:]

        #pubcomp packed id
        packet_id_MSB, packet_id_LSB = struct.unpack("!2B", variableHeader[:2])
        self.variable['packet_id'] = (packet_id_MSB << 8) + packet_id_LSB
        variableHeader = variableHeader[2:]

        #pubcomp reason code
        pubcomp_reason_code = struct.unpack("!B", variableHeader[:1])[0]
        self.variable['pubcomp_reason_code'] = pubcomp_reason_code
        if (self.fixed['remainingLength'] == 2):
            self.variable['pubcomp_reason_code'] = 0x00
        variableHeader = variableHeader[1:]

        #properties can be omitted if the reason code is Success
        #3 bytes so far
        #in case if reason code isn't Success, properties can't be omitted

        properties = self.data[self.fixed_size + 3:]
        num = b""
        for byte in properties:
            num += struct.pack("!B", byte)
            if byte < 0x80:
                break
        required = len(num)

        self.variable['propertyLength'] = struct.unpack(
            "!{}s".format(required), num)[0]

        #fac decode ca sa am prop length intr un int
        self.variable['propertyLength'] = VariableByte.decode(
            self.variable['propertyLength'])

        if (self.fixed['remainingLength'] < 4):
            self.variable['propertyLength'] = 0
        else:
            self.variable['properties'] = {}
            self.variable['properties']['userProperty'] = {}
            self.variable_size = self.variable['propertyLength'] + 3
            properties = properties[required:]

            i = 0
            while i < self.variable['propertyLength']:
                if properties[i] == 0x1f:
                    if 'reason_string' not in self.variable['properties'].keys(
                    ):
                        OFFSET_TO_READ_START = i + 1
                        OFFSET_TO_READ_END = i + 3
                        to_read = properties[
                            OFFSET_TO_READ_START:OFFSET_TO_READ_END]
                        efective_length = struct.unpack("!H", to_read)[0]
                        self.variable['properties'][
                            'reason_string'] = CustomUTF8.decode(
                                struct.unpack(
                                    "!{}s".format(2 + efective_length),
                                    properties[i + 1:i + 3 +
                                               efective_length])[0])
                        i = i + 2 + efective_length
                    else:
                        raise MQTTError(
                            "Malformed Packet : reason string already exists")
                if properties[i] == 0x26:
                    START = i + 1
                    END = i + 3
                    to_read = properties[START:END]
                    str1size = struct.unpack("!H", to_read)[0]
                    str1 = struct.unpack("!{}s".format(str1size + END - START),
                                         properties[START:END + str1size])[0]
                    START_index = i + 3 + str1size
                    END_index = i + 5 + str1size
                    to_read2 = properties[START_index:END_index]
                    str2size = struct.unpack("!H", to_read2)[0]
                    str2 = struct.unpack(
                        "!{}s".format(str2size + END_index - START_index),
                        properties[START_index:END_index + str2size])[0]
                    if CustomUTF8.decode(str1) not in self.variable[
                            'properties']['userProperty'].keys():
                        self.variable['properties']['userProperty'][
                            CustomUTF8.decode(str1)] = [
                                CustomUTF8.decode(str2)
                            ]
                    else:
                        self.variable['properties']['userProperty'][
                            CustomUTF8.decode(str1)].append(
                                CustomUTF8.decode(str2))
                        i = i + 4 + len(CustomUTF8.decode(str1)) + len(
                            CustomUTF8.decode(str2))
                i = i + 1
Exemplo n.º 9
0
    def parseVariableHeader(self):
        variableHeader = self.data[self.fixed_size:]

        #pubrel packed id
        packet_id_MSB, packet_id_LSB = struct.unpack("!2b", variableHeader[:2])
        self.variable['packet_id'] = (packet_id_MSB << 8) + packet_id_LSB
        print('packet_id: ' + str(self.variable['packet_id']))
        variableHeader = variableHeader[2:]

        #pubrel reason code
        pubrec_reason_code = struct.unpack("!B", variableHeader[:1])[0]
        self.variable['pubrec_reason_code'] = pubrec_reason_code
        if (self.fixed['remainingLength'] == 2):
            self.variable['pubrec_reason_code'] = 0x00
        print('pubrec_reason_code: ' +
              str(self.variable['pubrec_reason_code']))
        variableHeader = variableHeader[1:]

        #properties can be omitted if the reason code is Success
        #3 bytes so far

        #in case if reason code isn't Success, properties can't be omitted

        properties = self.data[self.fixed_size + 3:]
        num = b""
        for byte in properties:
            num += struct.pack("!B", byte)
            if byte < 0x80:
                break
        required = len(num)

        self.variable['propertyLength'] = struct.unpack(
            "!{}s".format(required), num)[0]

        #fac decode ca sa am prop length intr un int
        self.variable['propertyLength'] = VariableByte.decode(
            self.variable['propertyLength'])

        if (self.fixed['remainingLength'] < 4):
            self.variable['propertyLength'] = 0
        else:
            self.variable['properties'] = {}
            self.variable['properties']['userProperty'] = {}
            self.variable_size = self.variable['propertyLength'] + 3
            properties = properties[required:]

            i = 0
            while i < self.variable['propertyLength']:
                if properties[i] == 0x1f:
                    if 'reason_string' not in self.variable['properties'].keys(
                    ):
                        OFFSET_TO_READ_START = i + 1
                        OFFSET_TO_READ_END = i + 3
                        to_read = properties[
                            OFFSET_TO_READ_START:
                            OFFSET_TO_READ_END]  #octetii care arata lungimea
                        #print("to read: " + str(to_read))
                        efective_length = struct.unpack(
                            "!H", to_read
                        )[0]  #transf in nr => lungimea stringului meu de 2 bytes
                        #print("efective_lentgh: " + str(efective_length))
                        self.variable['properties'][
                            'reason_string'] = CustomUTF8.decode(
                                struct.unpack(
                                    "!{}s".format(2 + efective_length),
                                    properties[i + 1:i + 3 +
                                               efective_length])[0])
                        i = i + 2 + efective_length
                    else:
                        raise MQTTError(
                            "Malformed Packet : reason string already exists")
                if properties[i] == 0x26:
                    OFFSET_TO_READ_1_START = i + 1
                    OFFSET_TO_READ_1_END = i + 3
                    to_read = properties[
                        OFFSET_TO_READ_1_START:OFFSET_TO_READ_1_END]
                    str1size = struct.unpack("!H", to_read)[0]
                    str1 = struct.unpack(
                        "!{}s".format(str1size + OFFSET_TO_READ_1_END -
                                      OFFSET_TO_READ_1_START),
                        properties[
                            OFFSET_TO_READ_1_START:OFFSET_TO_READ_1_END +
                            str1size])[0]
                    OFFSET_TO_READ_2_START = i + 3 + str1size
                    OFFSET_TO_READ_2_END = i + 5 + str1size
                    to_read2 = properties[
                        OFFSET_TO_READ_2_START:OFFSET_TO_READ_2_END]
                    str2size = struct.unpack("!H", to_read2)[0]
                    str2 = struct.unpack(
                        "!{}s".format(str2size + OFFSET_TO_READ_2_END -
                                      OFFSET_TO_READ_2_START),
                        properties[
                            OFFSET_TO_READ_2_START:OFFSET_TO_READ_2_END +
                            str2size])[0]
                    if CustomUTF8.decode(str1) not in self.variable[
                            'properties']['userProperty'].keys():
                        self.variable['properties']['userProperty'][
                            CustomUTF8.decode(str1)] = [
                                CustomUTF8.decode(str2)
                            ]
                    else:
                        self.variable['properties']['userProperty'][
                            CustomUTF8.decode(str1)].append(
                                CustomUTF8.decode(str2))
                        i += 4 + len(CustomUTF8.decode(str1)) + len(
                            CustomUTF8.decode(str2))
                i = i + 1
Exemplo n.º 10
0
    def generatePacketData(ack_flags: bool, reason_code: int,
                           properties: dict) -> bytes:
        data = b"\x20"
        if ack_flags:
            flags = b"\x01"
        else:
            flags = b"\x00"
        rc = struct.pack("!B", reason_code)
        props = b""
        myProperties = list(properties.keys())

        if 'SessionExpiryInterval' in myProperties:
            props += b"\x11" + \
                struct.pack("!I", properties['SessionExpiryInterval'])
            myProperties.remove('SessionExpiryInterval')
        if 'ReceiveMaximum' in myProperties:
            props += b"\x21" + struct.pack("!H", properties['ReceiveMaximum'])
            myProperties.remove('ReceiveMaximum')
        if 'MaximumQoS' in myProperties:
            props += b"\x24" + struct.pack("!B", properties['MaximumQoS'])
            myProperties.remove('MaximumQoS')
        if 'RetainAvailable' in myProperties:
            props += b"\x25" + struct.pack("!B", properties['RetainAvailable'])
            myProperties.remove('RetainAvailable')
        if 'MaximumPacketSize' in myProperties:
            props += b"\x27" + struct.pack(
                "!I".properties['MaximumPacketSize'])
            myProperties.remove('MaximumPacketSize')
        if 'AssignedClientId' in myProperties:
            props += b"\x12" + CustomUTF8.encode(
                properties['AssignedClientId'])
            myProperties.remove('AssignedClientId')
        if 'TopicAliasMaximum' in myProperties:
            props += b"\x22" + struct.pack(
                "!H".properties['TopicAliasMaximum'])
            myProperties.remove('TopicAliasMaximum')
        if 'ReasonString' in myProperties:
            props += b"\x1F" + CustomUTF8.encode(properties['ReasonString'])
            myProperties.remove('ReasonString')
        if 'UserProperty' in myProperties:
            for key in properties['UserProperty'].keys():
                for value in properties['UserProperty'][key]:
                    props += b"\x26" + \
                        CustomUTF8.encode(key)+CustomUTF8.encode(value)
            myProperties.remove('UserProperty')
        if 'WildcardSubscriptionAvailable' in myProperties:
            props += b"\x28" + \
                struct.pack("!B", properties['WildcardSubscriptionAvailable'])
            myProperties.remove('WildcardSubscriptionAvailable')
        if 'SubscriptionIdentifiersAvailable' in myProperties:
            props += b"\x29" + \
                struct.pack(
                    "!B", properties['SubscriptionIdentifiersAvailable'])
            myProperties.remove('SubscriptionIdentifiersAvailable')
        if 'SharedSubscriptionAvailable' in myProperties:
            props += b"\x2A" + \
                struct.pack("!B", properties['SharedSubscriptionAvailable'])
            myProperties.remove('SharedSubscriptionAvailable')
        if 'ServerKeepAlive' in myProperties:
            props += b"\x13" + struct.pack("!H", properties['ServerKeepAlive'])
            myProperties.remove('ServerKeepAlive')
        if 'ResponseInformation' in myProperties:
            props += b"\x1A" + \
                CustomUTF8.encode(properties['ResponseInformation'])
            myProperties.remove('ResponseInformation')
        if 'ServerReference' in myProperties:
            props += b"\x1C" + CustomUTF8.encode(properties['ServerReference'])
            myProperties.remove('ServerReference')
        if 'AuthenticationMethod' in myProperties:
            props += b"\x15" + \
                CustomUTF8.encode(properties['AuthenticationMethod'])
            myProperties.remove('AuthenticationMethod')
        if 'AuthenticationData' in myProperties:
            props += b"\x16" + \
                BinaryData.fromBytesToBinary(properties['AuthenticationData'])
            myProperties.remove('AuthenticationData')

        if myProperties != []:
            raise ValueError("Unknown property was not parsed")
        propertyLength = VariableByte.encode(len(props))
        # 1 pentru flags si 1 pentru rc
        remainingLength = VariableByte.encode(2 + len(propertyLength) +
                                              len(props))
        # len(propertyLength) pare stupid, dar e necesar
        # propertyLength e format ca variable Byte si face parte din continutul pachetului.
        data += remainingLength + flags + rc + propertyLength + props
        return data
Exemplo n.º 11
0
    def parseVariableHeader(self) -> None:
        variableHeader = self.data[self.fixed_size:]
        offset, self.variable['name'] = readCustomUTF8String(variableHeader)
        self.variable['length']=offset-2
        variableHeader = variableHeader[offset:]
        protocol_version = struct.unpack("!B", variableHeader[:1])[0]
        self.variable['protocolVersion'] = protocol_version
        variableHeader = variableHeader[1:]
        connectFlags = struct.unpack("!B", variableHeader[:1])[0]
        self.variable['usernameFlag'] = (connectFlags & 128 == 128)
        self.variable['passwordFlag'] = (connectFlags & 64 == 64)
        self.variable['willRetain'] = (connectFlags & 32 == 32)
        self.variable['willQoS'] = connectFlags & 24  # 16+8
        self.variable['willFlag'] = (connectFlags & 4 == 4)
        self.variable['cleanStart'] = (connectFlags & 2 == 2)
        reserved = (connectFlags & 1 == 1)
        if reserved:
            raise MQTTError("Not reserved")
        variableHeader = variableHeader[1:]
        keep_alive_msb, keep_alive_lsb = struct.unpack(
            "!2B", variableHeader[:2])
        self.variable['KeepAlive'] = (keep_alive_msb << 8)+keep_alive_lsb
        # 10 bytes is the common variable header, without properties
        properties = self.data[10+self.fixed_size:]
        num = b""
        for byte in properties:
            num += struct.pack("!B", byte)
            if byte < 0x80:
                break
        required = len(num)
        self.variable['propertyLength'] = struct.unpack(
            "!{}s".format(required), num)[0]
        self.variable['propertyLength'] = VariableByte.decode(
            self.variable['propertyLength'])
        self.variable['properties'] = {}

        self.variable['properties']['requestResponseInformation'] = 1
        self.variable['properties']['userProperty'] = {}

        self.variable_size = self.variable['propertyLength']+10
        properties = properties[required:]
        i = 0
        while i < self.variable['propertyLength']:
            if properties[i] == 0x11:
                if 'sessionExpiry' not in self.variable['properties'].keys():
                    self.variable['properties']['sessionExpiry'] = struct.unpack(
                        "!I", properties[i+1:i+5])[0]
                    i += 4
                else:
                    raise MQTTError(
                        "Malformed Packet : sessionExpiry already exists")
            if properties[i] == 0x21:
                if 'receiveMaximum' not in self.variable['properties'].keys():
                    self.variable['properties']['receiveMaximum'] = struct.unpack(
                        "!H", properties[i+1:i+3])[0]
                    if self.variable['properties']['receiveMaximum'] == 0:
                        raise MQTTError(
                            "Malformed Packet : sessionExpiry is set to 0")
                    i += 2
                else:
                    raise MQTTError(
                        "Malformed Packet : receiveMaximum already exists")
            if properties[i] == 0x27:
                if 'maximumPacketSize' not in self.variable['properties'].keys():
                    self.variable['properties']['maximumPacketSize'] = struct.unpack(
                        "!I", properties[i+1:i+5])[0]
                    if self.variable['properties']['maximumPacketSize'] == 0:
                        raise MQTTError(
                            "Malformed Packet : sessionExpiry is set to 0")
                    i += 4
                else:
                    raise MQTTError(
                        "Malformed Packet : sessionExpiry already exists")
            if properties[i] == 0x22:
                if 'topicAliasMaximum' not in self.variable['properties'].keys():
                    self.variable['properties']['topicAliasMaximum'] = struct.unpack(
                        "!H", properties[i+1:i+3])[0]
                else:
                    raise MQTTError(
                        "Malformed Packet : topicAliasMaximum already exists")
                i += 2
            if properties[i] == 0x19:
                if 'requestResponseInformation' not in self.variable['properties'].keys():
                    self.variable['properties']['requestResponseInformation'] = struct.unpack(
                        "!B", properties[i+1:i+2])[0]
                    if self.variable['properties']['requestResponseInformation'] not in [0, 1]:
                        raise MQTTError(
                        "Malformed Packet : requestResponseInformation is not 0 or 1")
                else:
                    raise MQTTError(
                        "Malformed Packet : requestResponseInformation already exists")
            if properties[i] == 0x17:
                if 'requestProblemInformation' not in self.variable['properties'].keys():
                    self.variable['properties']['requestProblemInformation'] = struct.unpack(
                        "!B", properties[i+1:i+2])[0]
                    if self.variable['properties']['requestProblemInformation'] not in [0, 1]:
                        raise MQTTError(
                            "Malformed Packet : requestProblemInformation is not in 0 or 1")
                else:
                    raise MQTTError(
                        "Malformed Packet : requestProblemInformation already exists")

            if properties[i] == 0x26:
                offset1, str1 = readCustomUTF8String(properties[i+1:])
                offset2, str2 = readCustomUTF8String(properties[i+1+offset1:])
                if str1 not in self.variable['properties']['userProperty'].keys():
                    self.variable['properties']['userProperty'][str1] = [str2]
                else:
                    self.variable['properties']['userProperty'][str1].append(str2)
                i += offset1+offset2

            if properties[i] == 0x15:
                if 'authMethod' not in self.variable['properties'].keys():
                    offset, self.variable['properties']['authMethod'] = readCustomUTF8String(properties[i+1:])
                    i += 2+len(self.variable['properties']['authMethod'])
                else:
                    raise MQTTError(
                        "Malformed Packet : authMethod already exists")
            if properties[i] == 0x16:
                if 'authData' not in self.variable['properties'].keys():
                    offset, self.variable['properties']['authData']=readBinaryData(properties[i+1:])
                    i += offset
                else:
                    raise MQTTError(
                        "Malformed Packet : authentication data already exists")
            i = i+1

        if 'sessionExpiry' not in self.variable['properties'].keys():
            self.variable['properties']['sessionExpiry'] = 0
        if 'receiveMaximum' not in self.variable['properties'].keys():
            self.variable['properties']['receiveMaximum'] = 65535
        if 'topicAliasMaximum' not in self.variable['properties'].keys():
            self.variable['properties']['topicAliasMaximum'] = 0
        if 'requestResponseInformation' not in self.variable['properties'].keys():
            self.variable['properties']['requestResponseInformation'] = 0
        if 'requestProblemInformation' not in self.variable['properties'].keys():
            self.variable['properties']['requestProblemInformation'] = 1
Exemplo n.º 12
0
    def parsePayloadHeader(self):
        offset = self.fixed_size+self.variable_size+1
        self.payload_size = self.fixed['remainingLength']-self.variable_size
        payloadHeader = self.data[offset:]
        offset, self.payload['clientID'] = readCustomUTF8String(payloadHeader)
        payloadHeader=payloadHeader[offset:]

        if self.variable['willFlag']:
            self.payload['willProperties'] = {}
            self.payload['willProperties']['userProperty'] = {}
            num = b""
            for byte in payloadHeader:
                num += struct.pack("!B", byte)
                if byte < 0x80:
                    break
            self.payload['willProperties']['willLength'] = VariableByte.decode(
                num)
            i = 0
            payloadHeader = payloadHeader[len(num):]
            while i < self.payload['willProperties']['willLength']:
                if payloadHeader[i] == 0x18:
                    if 'willDelayInterval' not in self.payload['willProperties'].keys():
                        self.payload['willProperties']['willDelayInterval'] = struct.unpack(
                            "!I", payloadHeader[i+1:i+5])[0]
                    else:
                        raise MQTTError(
                            "Malformed Packet : willDelay already exists")
                    i += 4
                elif payloadHeader[i] == 0x01:
                    if 'payloadFormatIndicator' not in self.payload['willProperties'].keys():
                        self.payload['willProperties']['payloadFormatIndicator'] = struct.unpack(
                            "!B", payloadHeader[i+1:i+2])[0]
                        if self.payload['willProperties']['payloadFormatIndicator'] not in [0, 1]:
                            raise MQTTError("Malformed Packet : payloadFormatIndicator not in 0 or 1")
                    else:
                        raise MQTTError(
                            "Malformed Packet : payloadFormatIndicator already exists")
                    i += 1
                elif payloadHeader[i] == 0x02:
                    if 'messageExpiryInterval' not in self.payload['willProperties'].keys():
                        self.payload['willProperties']['messageExpiryInterval'] = (
                            True, struct.unpack("!I", payloadHeader[i+1:i+5])[0])
                    else:
                        raise MQTTError(
                            "Malformed Packet : messageExpiryInterval already exists")
                    i += 4
                    
                elif payloadHeader[i] == 0x03:
                    if 'contentType' not in self.payload['willProperties'].keys():
                        offset, self.payload['willProperties']['contentType'] = readCustomUTF8String(payloadHeader[i+1:])
                    else:
                        raise MQTTError(
                            "Malformed Packet : contentType already exists")
                    i += offset
                elif payloadHeader[i] == 0x08:
                    if 'responseTopic' not in self.payload['willProperties'].keys():
                        offset, self.payload['willProperties']['responseTopic'] = readCustomUTF8String(payloadHeader[i+1:])
                    else:
                        raise MQTTError(
                            "Malformed Packet : responseTopic already exists")
                    i += offset
                elif payloadHeader[i] == 0x09:
                    if 'correlationData' not in self.payload['willProperties'].keys():
                        length = struct.unpack("!H", payloadHeader[i+1:i+3])[0]
                        self.payload['willProperties']['correlationData'] = payloadHeader[i+1:i+3+length]
                    else:
                        raise MQTTError("Malformed Packet : correlationData already exists")
                    i += 2+length
                elif payloadHeader[i] == 0x26:
                    offset1, str1 = readCustomUTF8String(payloadHeader[i+1:])
                    offset2, str2 = readCustomUTF8String(payloadHeader[i+1+offset1:])
                    if str1 not in self.payload['willProperties']['userProperty'].keys():
                        self.payload['willProperties']['userProperty'][str1] = [str2]
                    else:
                        self.payload['willProperties']['userProperty'][str1].append(str2)
                    i += offset1+offset2
                i += 1


            if 'willDelayInterval' not in self.payload['willProperties'].keys():
                self.payload['willProperties']['willDelayInterval'] = 0
            if 'payloadFormatIndicator' not in self.payload['willProperties'].keys():
                self.payload['willProperties']['payloadFormatIndicator'] = 0
            if 'messageExpiryInterval' not in self.payload['willProperties'].keys():
                self.payload['willProperties']['messageExpiryInterval'] = (False, 0)
            
            offset, self.payload['willTopic']=readCustomUTF8String(payloadHeader[self.payload['willProperties']['willLength']:])
            payloadHeader=payloadHeader[offset+self.payload['willProperties']['willLength']:]
            
            offset, self.payload['willPayload']=readBinaryData(payloadHeader)
            payloadHeader=payloadHeader[offset:]

        if self.variable['usernameFlag']:
            offset, self.payload['username']=readCustomUTF8String(payloadHeader)
            payloadHeader=payloadHeader[offset:]

        if self.variable['passwordFlag']:
            offset, self.payload['password']=readBinaryData(payloadHeader)
            payloadHeader=payloadHeader[offset:]
Exemplo n.º 13
0
    

if __name__ == "__main__":

    clientID = CustomUTF8.encode("r3allyrandomid")
    willDelay = struct.pack("!I", 35)
    payloadFormatIndicator = b"\x01\x01"
    messageExpiryInterval = b"\x02"+struct.pack("!I", 32)
    willTopic = CustomUTF8.encode("pc/temp")
    willPayload = CustomUTF8.encode("this is a test message to be sent as a will payload and be submitted as key-value pair")
    correlationData = b"\x09"+b"\x00\x02\x04\x08"
    contentType = b"\x03"+CustomUTF8.encode("application/x-pdf")
    responseTopic = b"\x08"+CustomUTF8.encode("my response topic")
    userProperties = b"\x26"+CustomUTF8.encode("salut_din_will")+CustomUTF8.encode("dev")
    will = b"\x18"+willDelay+ payloadFormatIndicator + messageExpiryInterval+userProperties+contentType+ correlationData
    willLength = VariableByte.encode(len(will))
    username = CustomUTF8.encode("admin")
    password = CustomUTF8.encode("password")
    otherProps = willTopic+willPayload+username+password
    variableContents = b"\x00\x04MQTT\x05\xfe\x01\xff"
    properties = b"\x11\x00\x00\x00\x02\x21\x00\x02\x26"+CustomUTF8.encode("salut")+CustomUTF8.encode("Emil")+b"\x26"+CustomUTF8.encode("salut")+CustomUTF8.encode("bunaziua")+b"\x26"+CustomUTF8.encode(
        "hello")+CustomUTF8.encode("welcome")+b"\x15"+CustomUTF8.encode("userpass")+b"\x16\x00\x04\x02\x03\x04\x05"+b"\x26"+CustomUTF8.encode("salut")+CustomUTF8.encode("Andrei")
    propertyLength = VariableByte.encode(len(properties))
    byte_data = b"\x10"+VariableByte.encode(
        len(variableContents+propertyLength+properties+clientID+willLength+will+otherProps))

    packetContents = byte_data+variableContents + \
        propertyLength+properties+clientID+willLength+will + otherProps
    data = struct.pack("!{}s".format(len(packetContents)), packetContents)
    packet = ConnectPacket(data)
    print(data)