Exemplo n.º 1
0
class BaseNyamuk:
    def __init__(self, id = None, username = None, password = None, WITH_BROKER = False):
        ''' Constructor '''
        self.id = id
        self.username = None
        self.password = None
        
        self.address = ""
        self.keep_alive = NC.KEEPALIVE_VAL
        self.clean_session = False
        self.state = NC.CS_NEW
        self.last_msg_in = time.time()
        self.last_msg_out = time.time()
        self.last_mid = 0
        
        #output packet queue
        self.out_packet = []
        
        #input packet queue
        self.in_packet = MqttPkt()
        self.in_packet.packet_cleanup()
        
        #networking
        self.sock = NC.INVALID_SOCKET
        
        self.will = None
        
        
        self.in_callback = False
        self.message_retry = NC.MESSAGE_RETRY
        self.last_retry_check = 0
        self.messages = None
        
        
        #LOGGING:TODO
        self.log_priorities = -1
        self.log_destinations = -1
        
        #callback
        self.on_connect = None
        self.on_disconnect = None
        self.on_message = None
        self.on_publish = None
        self.on_subscribe = None
        self.on_unsubscribe = None
        
        self.host = None
        self.port = 1883
        
        #hack var
        self.as_broker = False
    
    def __del__(self):
        pass
        
    def mid_generate(self):
        self.last_mid += 1
        if self.last_mid == 0:
            self.last_mid += 1
        return self.last_mid
    
    def packet_queue(self, pkt):
        '''
        Enqueue packet to out_packet queue
        '''
        
        pkt.pos = 0
        pkt.to_process = pkt.packet_length
        
        self.out_packet.append(pkt)
        
        #if self.in_callback == False:
        #    return self.packet_write()
        #else:
        #    return NC.ERR_SUCCESS
        
        return NC.ERR_SUCCESS
    
    def packet_write(self):
        """Write packet to network."""
        bytes_written = 0
        
        if self.sock == NC.INVALID_SOCKET:
            return NC.ERR_NO_CONN, bytes_written
        
        while len(self.out_packet) > 0:
            pkt = self.out_packet[0]
            write_length, status = nyamuk_net.write(self.sock, pkt.payload)
            if write_length > 0:
                pkt.to_process -= write_length
                pkt.pos += write_length
                
                bytes_written += write_length
                
                if pkt.to_process > 0:
                    return NC.ERR_SUCCESS, bytes_written
            else:
                if status == errno.EAGAIN or status == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_written
                elif status == errno.ECONNRESET:
                    return NC.ERR_CONN_LOST, bytes_written
                else:
                    return NC.ERR_UNKNOWN, bytes_written
            
            if pkt.command & 0xF6 == NC.CMD_PUBLISH and self.on_publish is not None:
                self.in_callback = True
                self.on_publish(pkt.mid)
                self.in_callback = False
            
            #next
            del self.out_packet[0]
            
            #free data (unnecessary)
            
            self.last_msg_out = time.time()
            
        
        return NC.ERR_SUCCESS, bytes_written
    
    def packet_read(self):
        """Read packet from network."""
        bytes_received = 0
        
        if self.sock == NC.INVALID_SOCKET:
            return NC.ERR_NO_CONN
        
        if self.in_packet.command == 0:
            readlen, ba,status = nyamuk_net.read(self.sock, 1)
            if readlen == 1:
                bytes_received += 1
                byte = ba[0]
                self.in_packet.command = byte
                
                if self.as_broker == True:
                    if self.bridge is None and self.state == NC.CS_NEW and (byte & 0xF0) != NC.CMD_CONNECT:
                        print "RETURN ERR_PROTOCOL"
                        return NC.ERR_PROTOCOL, bytes_received
            else:
                if readlen == 0:
                    return NC.ERR_CONN_LOST, bytes_received
                if status == errno.EAGAIN or status == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_received
                else:
                    if status == errno.ECONNRESET:
                        return NC.ERR_CONN_LOST, bytes_received
                    else:
                        return NC.ERR_UNKNOWN, bytes_received
        
        if self.in_packet.have_remaining == False:
            loop_flag = True
            while loop_flag == True:
                readlen, ba,status = nyamuk_net.read(self.sock, 1)
                byte = ba[0]
                if readlen == 1:
                    bytes_received += 1
                    self.in_packet.remaining_count += 1
                    if self.in_packet.remaining_count > 4:
                        return NC.ERR_PROTOCOL, bytes_received
                    
                    self.in_packet.remaining_length += (byte & 127) * self.in_packet.remaining_mult
                    self.in_packet.remaining_mult *= 128
                else:
                    if readlen == 0:
                        return NC.ERR_CONN_LOST, bytes_received
                
                if (byte & 128) == 0:
                    loop_flag = False
            
            if self.in_packet.remaining_length > 0:
                self.in_packet.payload = bytearray(self.in_packet.remaining_length)
                if self.in_packet.payload is None:
                    return NC.ERR_NO_MEM, bytes_received
                self.in_packet.to_process = self.in_packet.remaining_length
            
            self.in_packet.have_remaining = True
        
        if self.in_packet.to_process > 0:
            readlen, ba, status = nyamuk_net.read(self.sock, self.in_packet.to_process)
            if readlen > 0:
                bytes_received += readlen
                for x in range(0, readlen):
                    self.in_packet.payload[self.in_packet.pos] = ba[x]
                    self.in_packet.pos += 1
                    self.in_packet.to_process -= 1
            else:
                if status == errno.EAGAIN or status == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_received
                else:
                    if status == errno.ECONNRESET:
                        return NC.ERR_CONN_LOST, bytes_received
                    else:
                        return NC.ERR_UNKNOWN, bytes_received
        
        #all data for this packet is read
        self.in_packet.pos = 0
        
        rc = self.packet_handle()
        
        self.in_packet.packet_cleanup()
        
        self.last_msg_in = time.time()
        
        return rc, bytes_received
                
    def socket_close(self):
        """Close our socket."""
        if self.sock != NC.INVALID_SOCKET:
            self.sock.close()
        self.sock = NC.INVALID_SOCKET
        
    def build_publish_pkt(self, mid, topic, payload, qos, retain, dup):
        """Build PUBLISH packet."""
        pkt = MqttPkt()
        payloadlen = len(payload)
        packetlen = 2 + len(topic) + payloadlen
        
        if qos > 0:
            packetlen += 2
        
        pkt.mid = mid
        pkt.command = NC.CMD_PUBLISH | ((dup & 0x1) << 3) | (qos << 1) | retain
        pkt.remaining_length = packetlen
        
        rc = pkt.alloc()
        if rc != NC.ERR_SUCCESS:
            return rc, None
        
        #variable header : Topic String
        pkt.write_string(topic, len(topic))
        
        if qos > 0:
            pkt.write_uint16(mid)
        
        #payloadlen
        if payloadlen > 0:
            pkt.write_bytes(payload, payloadlen)
        
        return NC.ERR_SUCCESS, pkt
    
    def send_simple_command(self, cmd):
        pkt = MqttPkt()
        
        pkt.command = cmd
        pkt.remaining_length = 0
        
        rc = pkt.alloc()
        if rc != NC.ERR_SUCCESS:
            return rc
        
        return self.packet_queue(pkt)
Exemplo n.º 2
0
class BaseNyamuk:
    """Base class of nyamuk."""
    def __init__(self, client_id, username, password, server, port, keepalive,
                 ssl, ssl_opts):
        ''' Constructor '''
        self.client_id = client_id
        self.username = username
        self.password = password
        self.server = server
        self.port = port
        self.ssl = ssl
        self.ssl_opts = ssl_opts

        self.address = ""
        self.keep_alive = keepalive
        self.clean_session = 1
        self.state = NC.CS_NEW
        self.last_msg_in = time.time()
        self.last_msg_out = time.time()
        self.last_mid = 0

        #output packet queue
        self.out_packet = []

        #input packet queue
        self.in_packet = MqttPkt()
        self.in_packet.packet_cleanup()

        #networking
        self.sock = NC.INVALID_SOCKET

        self.will = None

        self.message_retry = NC.MESSAGE_RETRY
        self.last_retry_check = 0
        self.messages = None

        self.bridge = None

        #LOGGING Option:TODO
        self.log_priorities = -1
        self.log_destinations = -1

        self.host = None

        #hack var
        self.as_broker = False

        #event list
        self.event_list = []

    def pop_event(self):
        """Pop an event from event_list."""
        if len(self.event_list) > 0:
            evt = self.event_list.pop(0)
            return evt
        return None

    def push_event(self, evt):
        """Add an event to event_list."""
        self.event_list.append(evt)

    def mid_generate(self):
        """Generate mid. TODO : check."""
        self.last_mid += 1
        if self.last_mid == 0:
            self.last_mid += 1
        return self.last_mid

    def packet_queue(self, pkt):
        """Enqueue packet to out_packet queue."""

        pkt.pos = 0
        pkt.to_process = pkt.packet_length

        self.out_packet.append(pkt)
        return NC.ERR_SUCCESS

    def packet_write(self):
        """Write packet to network."""
        bytes_written = 0

        if self.sock == NC.INVALID_SOCKET:
            return NC.ERR_NO_CONN, bytes_written

        while len(self.out_packet) > 0:
            pkt = self.out_packet[0]
            write_length, status = nyamuk_net.write(self.sock, pkt.payload)
            if write_length > 0:
                pkt.to_process -= write_length
                pkt.pos += write_length

                bytes_written += write_length

                if pkt.to_process > 0:
                    return NC.ERR_SUCCESS, bytes_written
            else:
                if status == errno.EAGAIN or status == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_written
                elif status == errno.ECONNRESET:
                    return NC.ERR_CONN_LOST, bytes_written
                else:
                    return NC.ERR_UNKNOWN, bytes_written
            """
            if pkt.command & 0xF6 == NC.CMD_PUBLISH and self.on_publish is not None:
                self.in_callback = True
                self.on_publish(pkt.mid)
                self.in_callback = False
            """

            #next
            del self.out_packet[0]

            #free data (unnecessary)

            self.last_msg_out = time.time()

        return NC.ERR_SUCCESS, bytes_written

    def packet_read(self):
        """Read packet from network."""
        bytes_received = 0

        if self.sock == NC.INVALID_SOCKET:
            return NC.ERR_NO_CONN

        if self.in_packet.command == 0:
            ba_data, errnum, errmsg = nyamuk_net.read(self.sock, 1)
            if errnum == 0 and len(ba_data) == 1:
                bytes_received += 1
                byte = ba_data[0]
                self.in_packet.command = byte

                if self.as_broker:
                    if self.bridge is None and self.state == NC.CS_NEW and (
                            byte & 0xF0) != NC.CMD_CONNECT:
                        print "RETURN ERR_PROTOCOL"
                        return NC.ERR_PROTOCOL, bytes_received
            else:
                if errnum == errno.EAGAIN or errnum == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_received
                elif errnum == 0 and len(
                        ba_data) == 0 or errnum == errno.ECONNRESET:
                    return NC.ERR_CONN_LOST, bytes_received
                else:
                    evt = event.EventNeterr(errnum, errmsg)
                    self.push_event(evt)
                    return NC.ERR_UNKNOWN, bytes_received

        if not self.in_packet.have_remaining:
            loop_flag = True
            while loop_flag:
                ba_data, errnum, errmsg = nyamuk_net.read(self.sock, 1)

                if errnum == 0 and len(ba_data) == 1:
                    byte = ba_data[0]
                    bytes_received += 1
                    self.in_packet.remaining_count += 1
                    if self.in_packet.remaining_count > 4:
                        return NC.ERR_PROTOCOL, bytes_received

                    self.in_packet.remaining_length += (
                        byte & 127) * self.in_packet.remaining_mult
                    self.in_packet.remaining_mult *= 128
                else:
                    if errnum == errno.EAGAIN or errnum == errno.EWOULDBLOCK:
                        return NC.ERR_SUCCESS, bytes_received
                    elif errnum == 0 and len(
                            ba_data) == 0 or errnum == errno.ECONNRESET:
                        return NC.ERR_CONN_LOST, bytes_received
                    else:
                        evt = event.EventNeterr(errnum, errmsg)
                        self.push_event(evt)
                        return NC.ERR_UNKNOWN, bytes_received

                if (byte & 128) == 0:
                    loop_flag = False

            if self.in_packet.remaining_length > 0:
                self.in_packet.payload = bytearray(
                    self.in_packet.remaining_length)
                if self.in_packet.payload is None:
                    return NC.ERR_NO_MEM, bytes_received
                self.in_packet.to_process = self.in_packet.remaining_length

            self.in_packet.have_remaining = True

        if self.in_packet.to_process > 0:
            ba_data, errnum, errmsg = nyamuk_net.read(
                self.sock, self.in_packet.to_process)
            if errnum == 0 and len(ba_data) > 0:
                readlen = len(ba_data)
                bytes_received += readlen
                for idx in xrange(0, readlen):
                    self.in_packet.payload[self.in_packet.pos] = ba_data[idx]
                    self.in_packet.pos += 1
                    self.in_packet.to_process -= 1
            else:
                if errnum == errno.EAGAIN or errnum == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_received
                elif errnum == 0 and len(
                        ba_data) == 0 or errnum == errno.ECONNRESET:
                    return NC.ERR_CONN_LOST, bytes_received
                else:
                    evt = event.EventNeterr(errnum, errmsg)
                    self.push_event(evt)
                    return NC.ERR_UNKNOWN, bytes_received

        #all data for this packet is read
        self.in_packet.pos = 0

        ret = self.packet_handle()

        self.in_packet.packet_cleanup()

        self.last_msg_in = time.time()

        return ret, bytes_received

    def socket_close(self):
        """Close our socket."""
        if self.sock != NC.INVALID_SOCKET:
            self.sock.close()
        self.sock = NC.INVALID_SOCKET

    def build_publish_pkt(self, mid, topic, payload, qos, retain, dup):
        """Build PUBLISH packet."""
        pkt = MqttPkt()
        payloadlen = len(payload)
        packetlen = 2 + len(topic) + payloadlen

        if qos > 0:
            packetlen += 2

        pkt.mid = mid
        pkt.command = NC.CMD_PUBLISH | ((dup & 0x1) << 3) | (qos << 1) | retain
        pkt.remaining_length = packetlen

        ret = pkt.alloc()
        if ret != NC.ERR_SUCCESS:
            return ret, None

        #variable header : Topic String
        pkt.write_string(topic)

        if qos > 0:
            pkt.write_uint16(mid)

        #payloadlen
        if payloadlen > 0:
            pkt.write_bytes(payload, payloadlen)

        return NC.ERR_SUCCESS, pkt

    def send_simple_command(self, cmd):
        """Send simple mqtt commands."""
        pkt = MqttPkt()

        pkt.command = cmd
        pkt.remaining_length = 0

        ret = pkt.alloc()
        if ret != NC.ERR_SUCCESS:
            return ret

        return self.packet_queue(pkt)
Exemplo n.º 3
0
class BaseNyamuk:
    """Base class of nyamuk."""

    def __init__(self, client_id, username, password, server, port, keepalive):
        """ Constructor """
        self.client_id = client_id
        self.username = username
        self.password = password
        self.server = server
        self.port = port

        self.address = ""
        self.keep_alive = keepalive
        self.clean_session = 1
        self.state = NC.CS_NEW
        self.last_msg_in = time.time()
        self.last_msg_out = time.time()
        self.last_mid = 0

        # output packet queue
        self.out_packet = []

        # input packet queue
        self.in_packet = MqttPkt()
        self.in_packet.packet_cleanup()

        # networking
        self.sock = NC.INVALID_SOCKET

        self.will = None

        self.message_retry = NC.MESSAGE_RETRY
        self.last_retry_check = 0
        self.messages = None

        self.bridge = None

        # LOGGING Option:TODO
        self.log_priorities = -1
        self.log_destinations = -1

        self.host = None
        self.port = 1883

        # hack var
        self.as_broker = False

        # event list
        self.event_list = []

    def pop_event(self):
        """Pop an event from event_list."""
        if len(self.event_list) > 0:
            evt = self.event_list.pop(0)
            return evt
        return None

    def push_event(self, evt):
        """Add an event to event_list."""
        self.event_list.append(evt)

    def mid_generate(self):
        """Generate mid. TODO : check."""
        self.last_mid += 1
        if self.last_mid == 0:
            self.last_mid += 1
        return self.last_mid

    def packet_queue(self, pkt):
        """Enqueue packet to out_packet queue."""

        pkt.pos = 0
        pkt.to_process = pkt.packet_length

        self.out_packet.append(pkt)
        return NC.ERR_SUCCESS

    def packet_write(self):
        """Write packet to network."""
        bytes_written = 0

        if self.sock == NC.INVALID_SOCKET:
            return NC.ERR_NO_CONN, bytes_written

        while len(self.out_packet) > 0:
            pkt = self.out_packet[0]
            write_length, status = nyamuk_net.write(self.sock, pkt.payload)
            if write_length > 0:
                pkt.to_process -= write_length
                pkt.pos += write_length

                bytes_written += write_length

                if pkt.to_process > 0:
                    return NC.ERR_SUCCESS, bytes_written
            else:
                if status == errno.EAGAIN or status == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_written
                elif status == errno.ECONNRESET:
                    return NC.ERR_CONN_LOST, bytes_written
                else:
                    return NC.ERR_UNKNOWN, bytes_written

            """
            if pkt.command & 0xF6 == NC.CMD_PUBLISH and self.on_publish is not None:
                self.in_callback = True
                self.on_publish(pkt.mid)
                self.in_callback = False
            """

            # next
            del self.out_packet[0]

            # free data (unnecessary)

            self.last_msg_out = time.time()

        return NC.ERR_SUCCESS, bytes_written

    def packet_read(self):
        """Read packet from network."""
        bytes_received = 0

        if self.sock == NC.INVALID_SOCKET:
            return NC.ERR_NO_CONN

        if self.in_packet.command == 0:
            ba_data, status = nyamuk_net.read(self.sock, 1)
            readlen = len(ba_data)
            if readlen == 1:
                bytes_received += 1
                byte = ba_data[0]
                self.in_packet.command = byte

                if self.as_broker:
                    if self.bridge is None and self.state == NC.CS_NEW and (byte & 0xF0) != NC.CMD_CONNECT:
                        print "RETURN ERR_PROTOCOL"
                        return NC.ERR_PROTOCOL, bytes_received
            else:
                if readlen == 0:
                    return NC.ERR_CONN_LOST, bytes_received
                if status == errno.EAGAIN or status == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_received
                else:
                    if status == errno.ECONNRESET:
                        return NC.ERR_CONN_LOST, bytes_received
                    else:
                        return NC.ERR_UNKNOWN, bytes_received

        if not self.in_packet.have_remaining:
            loop_flag = True
            while loop_flag:
                ba_data, status = nyamuk_net.read(self.sock, 1)
                readlen = len(ba_data)
                byte = ba_data[0]
                if readlen == 1:
                    bytes_received += 1
                    self.in_packet.remaining_count += 1
                    if self.in_packet.remaining_count > 4:
                        return NC.ERR_PROTOCOL, bytes_received

                    self.in_packet.remaining_length += (byte & 127) * self.in_packet.remaining_mult
                    self.in_packet.remaining_mult *= 128
                else:
                    if readlen == 0:
                        return NC.ERR_CONN_LOST, bytes_received

                if (byte & 128) == 0:
                    loop_flag = False

            if self.in_packet.remaining_length > 0:
                self.in_packet.payload = bytearray(self.in_packet.remaining_length)
                if self.in_packet.payload is None:
                    return NC.ERR_NO_MEM, bytes_received
                self.in_packet.to_process = self.in_packet.remaining_length

            self.in_packet.have_remaining = True

        if self.in_packet.to_process > 0:
            ba_data, status = nyamuk_net.read(self.sock, self.in_packet.to_process)
            readlen = len(ba_data)
            if readlen > 0:
                bytes_received += readlen
                for idx in xrange(0, readlen):
                    self.in_packet.payload[self.in_packet.pos] = ba_data[idx]
                    self.in_packet.pos += 1
                    self.in_packet.to_process -= 1
            else:
                if status == errno.EAGAIN or status == errno.EWOULDBLOCK:
                    return NC.ERR_SUCCESS, bytes_received
                else:
                    if status == errno.ECONNRESET:
                        return NC.ERR_CONN_LOST, bytes_received
                    else:
                        return NC.ERR_UNKNOWN, bytes_received

        # all data for this packet is read
        self.in_packet.pos = 0

        ret = self.packet_handle()

        self.in_packet.packet_cleanup()

        self.last_msg_in = time.time()

        return ret, bytes_received

    def socket_close(self):
        """Close our socket."""
        if self.sock != NC.INVALID_SOCKET:
            self.sock.close()
        self.sock = NC.INVALID_SOCKET

    def build_publish_pkt(self, mid, topic, payload, qos, retain, dup):
        """Build PUBLISH packet."""
        pkt = MqttPkt()
        payloadlen = len(payload)
        packetlen = 2 + len(topic) + payloadlen

        if qos > 0:
            packetlen += 2

        pkt.mid = mid
        pkt.command = NC.CMD_PUBLISH | ((dup & 0x1) << 3) | (qos << 1) | retain
        pkt.remaining_length = packetlen

        ret = pkt.alloc()
        if ret != NC.ERR_SUCCESS:
            return ret, None

        # variable header : Topic String
        pkt.write_string(topic)

        if qos > 0:
            pkt.write_uint16(mid)

        # payloadlen
        if payloadlen > 0:
            pkt.write_bytes(payload, payloadlen)

        return NC.ERR_SUCCESS, pkt

    def send_simple_command(self, cmd):
        """Send simple mqtt commands."""
        pkt = MqttPkt()

        pkt.command = cmd
        pkt.remaining_length = 0

        ret = pkt.alloc()
        if ret != NC.ERR_SUCCESS:
            return ret

        return self.packet_queue(pkt)