Beispiel #1
0
    def connect(self, version = 3, clean_session = 1, will = None):
        """Connect to server."""
        self.clean_session = clean_session
        self.will          = None
        
        if will is not None:
            self.will = NyamukMsg(
                topic = will['topic'],
                # unicode text needs to be utf8 encoded to be sent on the wire
                # str or bytearray are kept as it is
                payload = utf8encode(will.get('message','')),
                qos = will.get('qos', 0),
                retain = will.get('retain', False)
            )

        #CONNECT packet
        pkt = MqttPkt()
        pkt.connect_build(self, self.keep_alive, clean_session, version = version)
        
        #create socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if self.ssl:
            opts = {
                'do_handshake_on_connect': True,
                'ssl_version': ssl.PROTOCOL_TLSv1
            }
            opts.update(self.ssl_opts)
            #print opts, self.port

            try:
                self.sock = ssl.wrap_socket(self.sock, **opts)
            except Exception, e:
                self.logger.error("failed to initiate SSL connection: {0}".format(e))
                return NC.ERR_UNKNOWN
Beispiel #2
0
 def connect(self, hostname = "localhost", port = 1883, username = None, password = None,clean_session = True):
     """Connect to server."""
     self.hostnamne = hostname
     self.port = port
     self.username = username
     self.password = password
     self.port = port
     self.clean_session = clean_session
     
     #CONNECT packet
     pkt = MqttPkt()
     pkt.connect_build(self, self.keep_alive, clean_session)
     
     #create socket
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     nyamuk_net.setkeepalives(self.sock)
     
     self.logger.info("Connecting to server ....%s",hostname)
     ret = nyamuk_net.connect(self.sock,(hostname, port))
     
     if ret != 0:
         return NC.ERR_NO_CONN
     
     #set to nonblock
     self.sock.setblocking(0)
     
     return self.packet_queue(pkt)
Beispiel #3
0
 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)
Beispiel #4
0
    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)
Beispiel #5
0
    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)
Beispiel #6
0
    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 = []
Beispiel #7
0
 def send_subscribe(self, dup, topic, qos):
     """Send subscribe COMMAND to server."""
     pkt = MqttPkt()
     
     pktlen = 2 + 2 + len(topic) + 1
     pkt.command = NC.CMD_SUBSCRIBE | (dup << 3) | (1 << 1)
     pkt.remaining_length = pktlen
     
     ret = pkt.alloc()
     if ret != NC.ERR_SUCCESS:
         return ret
     
     #variable header
     mid = self.mid_generate()
     pkt.write_uint16(mid)
     
     #payload
     pkt.write_string(topic)
     pkt.write_byte(qos)
     
     return self.packet_queue(pkt)
Beispiel #8
0
    def connect(self, clean_session=1):
        """Connect to server."""
        self.clean_session = clean_session

        #CONNECT packet
        pkt = MqttPkt()
        pkt.connect_build(self, self.keep_alive, clean_session)

        #create socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        nyamuk_net.setkeepalives(self.sock)

        self.logger.info("Connecting to server ....%s", self.server)
        err = nyamuk_net.connect(self.sock, (self.server, self.port))

        if err != None:
            self.logger.error(err[1])
            return NC.ERR_UNKNOWN

        #set to nonblock
        self.sock.setblocking(0)

        return self.packet_queue(pkt)
Beispiel #9
0
    def connect(self, clean_session = 1):
        """Connect to server."""
        self.clean_session = clean_session
        
        #CONNECT packet
        pkt = MqttPkt()
        pkt.connect_build(self, self.keep_alive, clean_session)
        
        #create socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if self.ssl:
            opts = {
                'do_handshake_on_connect': True,
                'ssl_version': ssl.PROTOCOL_TLSv1
            }
            opts.update(self.ssl_opts)
            #print opts, self.port

            try:
                self.sock = ssl.wrap_socket(self.sock, **opts)
            except Exception, e:
                self.logger.error("failed to initiate SSL connection: {0}".format(e))
                return NC.ERR_UNKNOWN
Beispiel #10
0
 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
Beispiel #11
0
 def connect(self, clean_session = 1):
     """Connect to server."""
     self.clean_session = clean_session
     
     #CONNECT packet
     pkt = MqttPkt()
     pkt.connect_build(self, self.keep_alive, clean_session)
     
     #create socket
     self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     nyamuk_net.setkeepalives(self.sock)
     
     self.logger.info("Connecting to server ....%s", self.server)
     err = nyamuk_net.connect(self.sock,(self.server, self.port))
     
     if err != None:
         self.logger.error(err[1])
         return NC.ERR_UNKNOWN
     
     #set to nonblock
     self.sock.setblocking(0)
     
     return self.packet_queue(pkt)
Beispiel #12
0
    def connect(self, version=3, clean_session=1, will=None):
        """Connect to server."""
        self.clean_session = clean_session
        self.will = None

        if will is not None:
            self.will = NyamukMsg(
                topic=will['topic'],
                # unicode text needs to be utf8 encoded to be sent on the wire
                # str or bytearray are kept as it is
                payload=utf8encode(will.get('message', '')),
                qos=will.get('qos', 0),
                retain=will.get('retain', False))

        #CONNECT packet
        pkt = MqttPkt()
        pkt.connect_build(self,
                          self.keep_alive,
                          clean_session,
                          version=version)

        #create socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if self.ssl:
            opts = {
                'do_handshake_on_connect': True,
                'ssl_version': ssl.PROTOCOL_TLSv1
            }
            opts.update(self.ssl_opts)
            #print opts, self.port

            try:
                self.sock = ssl.wrap_socket(self.sock, **opts)
            except Exception, e:
                self.logger.error(
                    "failed to initiate SSL connection: {0}".format(e))
                return NC.ERR_UNKNOWN
Beispiel #13
0
    def send_unsubscribe(self, dup, topic):
        """Send unsubscribe COMMAND to server."""
        pkt = MqttPkt()

        pktlen = 2 + 2 + len(topic)
        pkt.command = NC.CMD_UNSUBSCRIBE | (dup << 3) | (1 << 1)
        pkt.remaining_length = pktlen

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

        #variable header
        mid = self.mid_generate()
        pkt.write_uint16(mid)

        #payload
        pkt.write_string(topic)

        return self.packet_queue(pkt)
Beispiel #14
0
    def connect(self, clean_session=1):
        """Connect to server."""
        self.clean_session = clean_session

        #CONNECT packet
        pkt = MqttPkt()
        pkt.connect_build(self, self.keep_alive, clean_session)

        #create socket
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        if self.ssl:
            opts = {
                'do_handshake_on_connect': True,
                'ssl_version': ssl.PROTOCOL_TLSv1
            }
            opts.update(self.ssl_opts)
            #print opts, self.port

            try:
                self.sock = ssl.wrap_socket(self.sock, **opts)
            except Exception, e:
                self.logger.error(
                    "failed to initiate SSL connection: {0}".format(e))
                return NC.ERR_UNKNOWN
Beispiel #15
0
 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 = []
Beispiel #16
0
    def pubcomp(self, mid):
        """Send PUBCOMP response to server."""
        if self.sock == NC.INVALID_SOCKET:
            return NC.ERR_NO_CONN

        self.logger.info("Send PUBCOMP (msgid=%s)", mid)
        pkt = MqttPkt()

        pkt.command = NC.CMD_PUBCOMP
        pkt.remaining_length = 2

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

        #variable header: acknowledged message id
        pkt.write_uint16(mid)

        return self.packet_queue(pkt)
Beispiel #17
0
    def pubcomp(self, mid):
        """Send PUBCOMP response to server."""
        if self.sock == NC.INVALID_SOCKET:
            return NC.ERR_NO_CONN

        self.logger.info("Send PUBCOMP (msgid=%s)", mid)
        pkt = MqttPkt()

        pkt.command = NC.CMD_PUBCOMP
        pkt.remaining_length = 2

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

        #variable header: acknowledged message id
        pkt.write_uint16(mid)

        return self.packet_queue(pkt)
Beispiel #18
0
    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
Beispiel #19
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)
Beispiel #20
0
 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
Beispiel #21
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)
Beispiel #22
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)