def SUBSCRIBE(self, message):
    data = bytearray()
    if message.getLength() <= 255:
        data = addByte(data, message.getLength())
    else:
        data = addByte(data, 1)
        data = addShort(data, message.getLength())

    if isinstance(message, SNSubscribe):
        data = addByte(data, message.getType())
        topic = message.getTopic()
        if topic is not None:
            flags = Flags(message.isDup(),
                          message.getTopic().getQoS(), False, False, False,
                          message.getTopic().getType())
            flagsByte = flags.encode()
            data = addByte(data, flagsByte)
            data = addShort(data, message.getPacketID())

            if isinstance(topic, FullTopic):
                data = addString(data, message.getTopic().getValue())
            else:
                data = addShort(data, message.getTopic().getValue())

            return data
    else:
        raise ValueError('Encode.subscribe malformed message')
def PUBLISH(self, message):
    data = bytearray()
    if message.getLength() <= 255:
        data = addByte(data, message.getLength())
    else:
        data = addByte(data, 1)
        data = addShort(data, message.getLength())

    if isinstance(message, SNPublish):
        data = addByte(data, int(message.getType()))
        topic = message.getTopic()
        if topic is not None:
            flags = Flags(message.isDup(),
                          message.getTopic().getQoS(), message.isRetain(),
                          False, False,
                          message.getTopic().getType())
            flagsByte = flags.encode()
            data = addByte(data, flagsByte)

            if isinstance(topic, FullTopic):
                data = addString(data, message.getTopic().getValue())
            else:
                data = addShort(data, message.getTopic().getValue())

            data = addShort(data, message.getPacketID())
            data = addString(data, message.getContent())
            return data
    else:
        raise ValueError('Encode.publish malformed message')
def SUBACK_DECODE(self):
    data = bytearray(self.buffer)
    decodeFlags = Flags(False, None, False, False, False, None)
    flags = decodeFlags.decode(getByte(data, self.index),
                               MQTTSN_messageType.SN_SUBACK)
    self.index += 1
    topicID = getShort(data[self.index:self.index + 2])
    self.index += 2
    messageID = getShort(data[self.index:self.index + 2])
    self.index += 2
    code = getByte(data, self.index)
    message = SNSuback(topicID, code, flags.getQoS(), messageID)
    return message
def WILL_TOPIC_UPD_DECODE(self):
    data = bytearray(self.buffer)
    topic = None
    retain = False
    if self.index < self.length:
        decodeFlags = Flags(False, None, False, False, False, None)
        flags = decodeFlags.decode(getByte(data, self.index),
                                   MQTTSN_messageType.SN_WILL_TOPIC_UPD)
        self.index += 1
        retain = flags.isRetain()
        value = getString(data[self.index:len(data)])
        topic = FullTopic(value, flags.getQoS())
    message = WillTopicUpd(retain, topic)
    return message
def CONNECT_DECODE(self):
    data = bytearray(self.buffer)
    decodeFlags = Flags(False, None, False, False, False, None)
    flags = decodeFlags.decode(getByte(data, self.index),
                               MQTTSN_messageType.SN_CONNECT)
    self.index += 1
    protocolID = getByte(data, self.index)
    if protocolID != 1:
        raise ValueError('Invalid protocolID ' + protocolID)
    self.index += 1
    duration = getShort(data[self.index:self.index + 2])
    self.index += 2
    clientID = getString(data[self.index:len(data)])
    clientID = clientID.strip()
    message = SNConnect(flags.isWill(), flags.isClean(), duration, clientID)
    return message
def SUBACK(self, message):
    data = bytearray()
    if message.getLength() <= 255:
        data = addByte(data, message.getLength())
    else:
        data = addByte(data, 1)
        data = addShort(data, message.getLength())

    if isinstance(message, SNSuback):
        data = addByte(data, int(message.getType()))
        flags = Flags(False, message.getQoS(), False, False, False, None)
        flagsByte = flags.encode()
        data = addByte(data, flagsByte)
        data = addShort(data, message.getTopicID())
        data = addShort(data, message.getPacketID())
        data = addByte(data, message.getCode())
        return data
    else:
        raise ValueError('Encode.suback malformed message')
def WILL_TOPIC_UPD(self, message):
    data = bytearray()
    if message.getLength() <= 255:
        data = addByte(data, message.getLength())
    else:
        data = addByte(data, 1)
        data = addShort(data, message.getLength())

    if isinstance(message, WillTopicUpd):
        data = addByte(data, int(message.getType()))
        if message.getTopic() is not None:
            flags = Flags(False,
                          message.getTopic().getQoS(), message.isRetain(),
                          False, False, None)
            flagsByte = flags.encode()
            data = addByte(data, flagsByte)
            data = addString(data, message.getTopic().getValue())
            return data
    else:
        raise ValueError('Encode.willTopicUpd malformed message')
def CONNECT(self, message):
    data = bytearray()
    if message.getLength() <= 255:
        data = addByte(data, message.getLength())
    else:
        data = addByte(data, 1)
        data = addShort(data, message.getLength())

    if isinstance(message, SNConnect):
        data = addByte(data, int(message.getType()))
        flags = Flags(False, None, False, message.getWillPresent(),
                      message.getCleanSession(), None)
        flagsByte = flags.encode()
        data = addByte(data, flagsByte)
        data = addByte(data, message.getProtocolID())
        data = addShort(data, message.getDuration())
        data = addString(data, message.getClientID())
    else:
        raise ValueError('Encode.snConnect malformed message')
    return data
def UNSUBSCRIBE_DECODE(self):
    data = bytearray(self.buffer)
    decodeFlags = Flags(False, None, False, False, False, None)
    flags = decodeFlags.decode(getByte(data, self.index),
                               MQTTSN_messageType.SN_UNSUBSCRIBE)
    self.index += 1
    messageID = getShort(data[self.index:self.index + 2])
    self.index += 2
    topic = None
    if self.index < self.length:
        if flags.getTopicType() == TopicType.NAMED:
            topicName = getString(data[self.index:len(data)])
            topic = FullTopic(topicName, flags.getQoS())
        if flags.getTopicType() == TopicType.ID:  #ID
            topicID = getShort(data[self.index:self.index + 2])
            topic = IdentifierTopic(topicName, flags.getQoS())
        if flags.getTopicType() == TopicType.SHORT:  #SHORT
            topicName = getString(data[self.index:len(data)])
            topic = ShortTopic(topicName, flags.getQoS())
    message = SNUnsubscribe(messageID, topic)
    return message
def PUBLISH_DECODE(self):
    data = bytearray(self.buffer)
    decodeFlags = Flags(False, None, False, False, False, None)
    flags = decodeFlags.decode(getByte(data, self.index),
                               MQTTSN_messageType.SN_PUBLISH)
    self.index += 1
    topicID = getShort(data[self.index:self.index + 2])
    self.index += 2
    messageID = getShort(data[self.index:self.index + 2])
    self.index += 2
    if flags.getQoS() != 0 and messageID == 0:
        raise ValueError('invalid PUBLISH QoS-0 messageID: ' + messageID)
    topic = None
    if flags.getTopicType() == TopicType.SHORT:  #SHORT
        topic = ShortTopic(topicID, flags.getQoS())
    else:
        topic = IdentifierTopic(topicID, flags.getQoS())
    content = ''
    if self.index < self.length:
        content = getString(data[self.index:len(data)])
        content.strip()
    message = SNPublish(messageID, topic, content, flags.isDup(),
                        flags.isRetain())
    return message