Esempio n. 1
0
    def handle_request(self, query, request):
        """
        when a request is received, handle it and returns the response pdu
        """
        request_pdu = ""
        try:
            #extract the pdu and the slave id
            (slave_id, request_pdu) = query.parse_request(request)

            #get the slave and let him executes the action
            if slave_id == 0:
                #broadcast
                for key in self._slaves:
                    self._slaves[key].handle_request(request_pdu, broadcast=True)
                return
            else:
                slave = self.get_slave(slave_id)
                response_pdu = slave.handle_request(request_pdu)
                #make the full response
                response = query.build_response(response_pdu)
                return response
        except Exception as excpt:
            call_hooks("modbus.Databank.on_error", (self, excpt, request_pdu))
            LOGGER.error("handle request failed: " + str(excpt))

        #If the request was not handled correctly, return a server error response
        func_code = 1
        if len(request_pdu) > 0:
            (func_code, ) = struct.unpack(">B", request_pdu[0])
        return struct.pack(">BB", func_code+0x80, defines.SLAVE_DEVICE_FAILURE)
Esempio n. 2
0
    def handle_request(self, query, request):
        """
        when a request is received, handle it and returns the response pdu
        """
        request_pdu = ""
        try:
            #extract the pdu and the slave id
            (slave_id, request_pdu) = query.parse_request(request)

            #get the slave and let him executes the action
            if slave_id == 0:
                #broadcast
                for key in self._slaves:
                    self._slaves[key].handle_request(request_pdu,
                                                     broadcast=True)
                return
            else:
                slave = self.get_slave(slave_id)
                response_pdu = slave.handle_request(request_pdu)
                #make the full response
                response = query.build_response(response_pdu)
                return response
        except Exception, excpt:
            call_hooks("modbus.Databank.on_error", (self, excpt, request_pdu))
            LOGGER.error("handle request failed: " + str(excpt))
Esempio n. 3
0
    def handle_request(self, query, request):
        """
        when a request is received, handle it and returns the response pdu
        """
        request_pdu = ""
        try:
            # extract the pdu and the slave id
            (slave_id, request_pdu) = query.parse_request(request)

            # get the slave and let him executes the action
            if slave_id == 0:
                # broadcast
                for key in self._slaves:
                    self._slaves[key].handle_request(request_pdu, broadcast=True)
                return
            else:
                slave = self.get_slave(slave_id)
                response_pdu = slave.handle_request(request_pdu)
                # make the full response
                response = query.build_response(response_pdu)
                return response
        except Exception as excpt:
            call_hooks("modbus.Databank.on_error", (self, excpt, request_pdu))
            LOGGER.error("handle request failed: " + str(excpt))

        # If the request was not handled correctly, return a server error response
        func_code = 1
        if len(request_pdu) > 0:
            (func_code, ) = struct.unpack(">B", request_pdu[0:1])

        return struct.pack(">BB", func_code + 0x80, defines.SLAVE_DEVICE_FAILURE)
Esempio n. 4
0
    def _do_run(self):
        """main function of the server"""
        try:
            #check the status of every socket
            response = ""
            request = ""
            read_bytes = "dummy"
            while read_bytes:
                read_bytes = self._serial.read(128)
                request += read_bytes

            #parse the request
            if request:
                retval = call_hooks("modbus_rtu.RtuServer.after_read", (self, request))
                if retval is not None:
                    request = retval
                response = self._handle(request)

                #send back the response
                retval = call_hooks("modbus_rtu.RtuServer.before_write", (self, response))
                if retval is not None:
                    response = retval

                if response:
                    self._serial.write(response)
                    time.sleep(self.get_timeout())

        except Exception as excpt:
            LOGGER.error("Error while handling request, Exception occurred: %s", excpt)
            call_hooks("modbus_rtu.RtuServer.on_error", (self, excpt))
Esempio n. 5
0
    def _do_run(self):
        """main function of the server"""
        try:
            #check the status of every socket
            response = ""
            request = ""
            read_bytes = "dummy"
            while read_bytes:
                read_bytes = self._serial.read(128)
                request += read_bytes

            #parse the request
            if request:
                retval = call_hooks("modbus_rtu.RtuServer.after_read",
                                    (self, request))
                if retval is not None:
                    request = retval
                response = self._handle(request)

                #send back the response
                retval = call_hooks("modbus_rtu.RtuServer.before_write",
                                    (self, response))
                if retval is not None:
                    response = retval

                if response:
                    self._serial.write(response)
                    time.sleep(self.get_timeout())

        except Exception as excpt:
            LOGGER.error(
                "Error while handling request, Exception occurred: %s", excpt)
            call_hooks("modbus_rtu.RtuServer.on_error", (self, excpt))
Esempio n. 6
0
    def _do_run(self):
        """main function of the server"""
        try:
            # check the status of every socket
            request = utils.to_data('')
            if self._block_on_first_byte:
                # do a blocking read for first byte
                self._serial.timeout = None
                try:
                    read_bytes = self._serial.read(1)
                    request += read_bytes
                except Exception as e:
                    self._serial.close()
                    self._serial.open()
                self._serial.timeout = self._timeout

            # Read rest of the request
            while True:
                try:
                    read_bytes = self._serial.read(128)
                    if not read_bytes:
                        break
                except Exception as e:
                    self._serial.close()
                    self._serial.open()
                    break
                request += read_bytes

            # parse the request
            if request:

                retval = call_hooks("modbus_rtu.RtuServer.after_read", (self, request))
                if retval is not None:
                    request = retval

                response = self._handle(request)

                # send back the response
                retval = call_hooks("modbus_rtu.RtuServer.before_write", (self, response))
                if retval is not None:
                    response = retval

                if response:
                    if self._serial.in_waiting > 0:
                        # Most likely master timed out on this request and started a new one
                        # for which we already received atleast 1 byte
                        LOGGER.warning("Not sending response because there is new request pending")
                    else:
                        self._serial.write(response)
                        self._serial.flush()
                        time.sleep(self.get_timeout())

                call_hooks("modbus_rtu.RtuServer.after_write", (self, response))

        except Exception as excpt:
            LOGGER.error("Error while handling request, Exception occurred: %s", excpt)
            call_hooks("modbus_rtu.RtuServer.on_error", (self, excpt))
Esempio n. 7
0
    def _do_run(self):
        """main function of the server"""
        try:
            # check the status of every socket
            request = utils.to_data('')
            if self._block_on_first_byte:
                # do a blocking read for first byte
                self._serial.timeout = None
                try:
                    read_bytes = self._serial.read(1)
                    request += read_bytes
                except Exception as e:
                    self._serial.close()
                    self._serial.open()
                self._serial.timeout = self._timeout

            # Read rest of the request
            while True:
                try:
                    read_bytes = self._serial.read(128)
                    if not read_bytes:
                        break
                except Exception as e:
                    self._serial.close()
                    self._serial.open()
                    break
                request += read_bytes

            # parse the request
            if request:

                retval = call_hooks("modbus_rtu.RtuServer.after_read", (self, request))
                if retval is not None:
                    request = retval

                response = self._handle(request)

                # send back the response
                retval = call_hooks("modbus_rtu.RtuServer.before_write", (self, response))
                if retval is not None:
                    response = retval

                if response:
                    if self._serial.in_waiting > 0:
                        # Most likely master timed out on this request and started a new one
                        # for which we already received atleast 1 byte
                        LOGGER.warning("Not sending response because there is new request pending")
                    else:
                        self._serial.write(response)
                        self._serial.flush()
                        time.sleep(self.get_timeout())

                call_hooks("modbus_rtu.RtuServer.after_write", (self, response))

        except Exception as excpt:
            LOGGER.error("Error while handling request, Exception occurred: %s", excpt)
            call_hooks("modbus_rtu.RtuServer.on_error", (self, excpt))
Esempio n. 8
0
 def _run(self):
     """main function of the thread execute _main_fct until stop is called"""
     #pylint: disable=broad-except
     try:
         if self._fcts[0]:
             self._fcts[0](*self._args)
         while self._go.isSet():
             self._fcts[1](*self._args)
     except Exception, excpt:
         LOGGER.error("error: %s", str(excpt))
Esempio n. 9
0
 def _run_server(self):
     """main function of the main thread"""
     try:
         self._do_init()
         while self._go.isSet():
             self._do_run()
         LOGGER.info("%s has stopped", self.__class__)
         self._do_exit()
     except Exception, excpt:
         LOGGER.error("server error: %s", str(excpt))
Esempio n. 10
0
 def _run(self):
     """main function of the thread execute _main_fct until stop is called"""
     #pylint: disable=broad-except
     try:
         if self._fcts[0]:
             self._fcts[0](*self._args)
         while self._go.isSet():
             self._fcts[1](*self._args)
     except Exception, excpt:
         LOGGER.error("error: %s", str(excpt))
Esempio n. 11
0
 def _run_server(self):
     """main function of the main thread"""
     try:
         self._do_init()
         while self._go.isSet():
             self._do_run()
         LOGGER.info("%s has stopped", self.__class__)
         self._do_exit()
     except Exception, excpt:
         LOGGER.error("server error: %s", str(excpt))
Esempio n. 12
0
 def _run_server(self):
     """main function of the main thread"""
     try:
         self._do_init()
         while self._go.isSet():
             self._do_run()
         LOGGER.debug("%s has stopped", self.__class__)
         self._do_exit()
     except Exception as excpt:
         LOGGER.error("server error: %s", str(excpt))
     # make possible to rerun in future
     self._make_thread()
Esempio n. 13
0
 def _send(self, request):
     """Send request to the slave"""
     retval = call_hooks("modbus_tcp.TcpMaster.before_send", (self, request))
     if retval is not None:
         request = retval
     try:
         flush_socket(self._sock, 3)
     except Exception as msg:
         #if we can't flush the socket successfully: a disconnection may happened
         #try to reconnect
         LOGGER.error('Error while flushing the socket: {0}'.format(msg))
         self._do_open()
     self._sock.send(request)
Esempio n. 14
0
 def _send(self, request):
     """Send request to the slave"""
     retval = call_hooks("modbus_tcp.TcpMaster.before_send", (self, request))
     if retval is not None:
         request = retval
     try:
         flush_socket(self._sock, 3)
     except Exception as msg:
         #if we can't flush the socket successfully: a disconnection may happened
         #try to reconnect
         LOGGER.error('Error while flushing the socket: {0}'.format(msg))
         self._do_open()
     self._sock.send(request)
Esempio n. 15
0
    def handle_request(self, query, request):
        """
        when a request is received, handle it and returns the response pdu
        """
        request_pdu = ""
        try:
            if "\x00+" in request:
                slave_id = 1
                request_pdu = struct.unpack('!HHHBBBBB', request)
                print(request_pdu)

            else:
                # extract the pdu and the slave id
                (slave_id, request_pdu) = query.parse_request(request)
                print("The request", request)

            # get the slave and let him executes the action
            if slave_id == 0:
                # broadcast
                for key in self._slaves:
                    self._slaves[key].handle_request(request_pdu,
                                                     broadcast=True)
                return
            else:
                try:
                    slave = self.get_slave(slave_id)
                except MissingKeyError:
                    if self.error_on_missing_slave:
                        raise
                    else:
                        return ""

                response_pdu = slave.handle_request(request_pdu)
                # make the full response
                print("the response pdu:", response_pdu)
                response = query.build_response(response_pdu)
                print("The response", response)
                return response
        except ModbusInvalidRequestError as excpt:
            # Request is invalid, do not send any response
            LOGGER.error("invalid request: " + str(excpt))
            return ""
        except MissingKeyError as excpt:
            # No slave with this ID in server, do not send any response
            LOGGER.error("handle request failed: " + str(excpt))
            return ""
        except Exception as excpt:
            call_hooks("modbus.Databank.on_error", (self, excpt, request_pdu))
            LOGGER.error("handle request failed: " + str(excpt))

        # If the request was not handled correctly, return a server error response
        func_code = 1
        if len(request_pdu) > 0:
            (func_code, ) = struct.unpack(">B", request_pdu[0:1])

        return struct.pack(">BB", func_code + 0x80,
                           defines.SLAVE_DEVICE_FAILURE)
Esempio n. 16
0
    def handle_request(self, query, request):
        """
        when a request is received, handle it and returns the response pdu
        """
        request_pdu = ""
        try:
            # extract the pdu and the slave id
            (slave_id, request_pdu) = query.parse_request(request)

            # get the slave and let him executes the action
            if slave_id == 0:
                # broadcast
                for key in self._slaves:
                    self._slaves[key].handle_request(request_pdu, broadcast=True)
                return
            else:
                slave = self.get_slave(slave_id)
                response_pdu = slave.handle_request(request_pdu)
                # make the full response
                response = query.build_response(response_pdu)
                return response
        except Exception, excpt:
            call_hooks("modbus.Databank.on_error", (self, excpt, request_pdu))
            LOGGER.error("handle request failed: " + str(excpt))
Esempio n. 17
0
    def _do_run(self):
        """called in a almost-for-ever loop by the server"""
        # check the status of every socket
        inputready = select.select(self._sockets, [], [], 1.0)[0]
        #print(inputready)

        # handle data on each a socket
        for sock in inputready:
            try:
                if sock == self._sock:
                    #print (self._sock)
                    # handle the server socket
                    #print ("Receiveeeeeeeeeeeeeeeeeeeee")
                    client, address = self._sock.accept()
                    client.setblocking(0)
                    LOGGER.debug("%s is connected with socket %d...",
                                 str(address), client.fileno())
                    self._sockets.append(client)
                    call_hooks("modbus_tcp.TcpServer.on_connect",
                               (self, client, address))
                    return
                else:
                    if len(sock.recv(1, socket.MSG_PEEK)) == 0:
                        # socket is disconnected
                        LOGGER.debug("%d is disconnected" % (sock.fileno()))
                        call_hooks("modbus_tcp.TcpServer.on_disconnect",
                                   (self, sock))
                        sock.close()
                        self._sockets.remove(sock)
                        break

                    # handle all other sockets
                    sock.settimeout(1.0)
                    request = to_data("")
                    is_ok = True

                    # read the 7 bytes of the mbap
                    while (len(request) < 7) and is_ok:
                        new_byte = sock.recv(1)
                        if len(new_byte) == 0:
                            is_ok = False
                        else:
                            request += new_byte

                    retval = call_hooks("modbus_tcp.TcpServer.after_recv",
                                        (self, sock, request))
                    if retval is not None:
                        request = retval

                    if is_ok:
                        # read the rest of the request
                        length = self._get_request_length(request)
                        while (len(request) < (length + 6)) and is_ok:
                            new_byte = sock.recv(1)
                            if len(new_byte) == 0:
                                is_ok = False
                            else:
                                request += new_byte

                    if is_ok:
                        response = ""
                        # parse the request
                        try:
                            response = self._handle(request)
                        except Exception as msg:
                            LOGGER.error(
                                "Error while handling a request, Exception occurred: %s",
                                msg)

                        # send back the response
                        if response:
                            try:
                                retval = call_hooks(
                                    "modbus_tcp.TcpServer.before_send",
                                    (self, sock, response))
                                if retval is not None:
                                    response = retval
                                sock.send(response)
                                call_hooks("modbus_tcp.TcpServer.after_send",
                                           (self, sock, response))
                            except Exception as msg:
                                is_ok = False
                                LOGGER.error(
                                    "Error while sending on socket %d, Exception occurred: %s",
                                    sock.fileno(), msg)
            except Exception as excpt:
                LOGGER.warning("Error while processing data on socket %d: %s",
                               sock.fileno(), excpt)
                call_hooks("modbus_tcp.TcpServer.on_error",
                           (self, sock, excpt))
                sock.close()
                self._sockets.remove(sock)
Esempio n. 18
0
    def _do_run(self):
        """called in a almost-for-ever loop by the server"""
        # check the status of every socket
        inputready = select.select(self._sockets, [], [], 1.0)[0]

        # handle data on each a socket
        for sock in inputready:
            try:
                if sock == self._sock:
                    # handle the server socket
                    client, address = self._sock.accept()
                    client.setblocking(0)
                    LOGGER.info("%s is connected with socket %d...", str(address), client.fileno())
                    self._sockets.append(client)
                    call_hooks("modbus_tcp.TcpServer.on_connect", (self, client, address))
                else:
                    if len(sock.recv(1, socket.MSG_PEEK)) == 0:
                        # socket is disconnected
                        LOGGER.info("%d is disconnected" % (sock.fileno()))
                        call_hooks("modbus_tcp.TcpServer.on_disconnect", (self, sock))
                        sock.close()
                        self._sockets.remove(sock)
                        break

                    # handle all other sockets
                    sock.settimeout(1.0)
                    request = to_data("")
                    is_ok = True

                    # read the 7 bytes of the mbap
                    while (len(request) < 7) and is_ok:
                        new_byte = sock.recv(1)
                        if len(new_byte) == 0:
                            is_ok = False
                        else:
                            request += new_byte

                    retval = call_hooks("modbus_tcp.TcpServer.after_recv", (self, sock, request))
                    if retval is not None:
                        request = retval

                    if is_ok:
                        # read the rest of the request
                        length = self._get_request_length(request)
                        while (len(request) < (length + 6)) and is_ok:
                            new_byte = sock.recv(1)
                            if len(new_byte) == 0:
                                is_ok = False
                            else:
                                request += new_byte

                    if is_ok:
                        response = ""
                        # parse the request
                        try:
                            response = self._handle(request)
                        except Exception as msg:
                            LOGGER.error("Error while handling a request, Exception occurred: %s", msg)

                        # send back the response
                        if response:
                            try:
                                retval = call_hooks("modbus_tcp.TcpServer.before_send", (self, sock, response))
                                if retval is not None:
                                    response = retval
                                sock.send(response)
                                call_hooks("modbus_tcp.TcpServer.after_send", (self, sock, response))
                            except Exception as msg:
                                is_ok = False
                                LOGGER.error(
                                    "Error while sending on socket %d, Exception occurred: %s", sock.fileno(), msg
                                )
            except Exception as excpt:
                LOGGER.warning("Error while processing data on socket %d: %s", sock.fileno(), excpt)
                call_hooks("modbus_tcp.TcpServer.on_error", (self, sock, excpt))
                sock.close()
                self._sockets.remove(sock)