示例#1
0
 def testCrc16ReturnsDifferentForDifferentStrings(self):
     """Check that the CRC16 returns a different value if strings are different"""
     test_strings = ("hello world", "a", "12345678910111213141516", "", "modbus-tk", "www.apidev.fr")
     for s in test_strings:
         s1 = to_data(s)
         s2 = to_data(s + '_')
         self.assertNotEqual(modbus_tk.utils.calculate_crc(s1), modbus_tk.utils.calculate_crc(s2))
示例#2
0
 def testCrc16ReturnsDifferentForDifferentStrings(self):
     """Check that the CRC16 returns a different value if strings are different"""
     test_strings = ("hello world", "a", "12345678910111213141516", "", "modbus-tk", "www.apidev.fr")
     for s in test_strings:
         s1 = to_data(s)
         s2 = to_data(s + '_')
         self.assertNotEqual(modbus_tk.utils.calculate_crc(s1), modbus_tk.utils.calculate_crc(s2))
 def testBuildRequestWithPdu(self):
     """Test the mbap returned by building a request with a pdu"""
     query = modbus_tcp.TcpQuery()
     for pdu in ["", "a", "a" * 127, "abcdefghi"]:
         request = query.build_request(to_data(pdu), 0)
         self.assertEqual(
             struct.pack(">HHHB" + str(len(pdu)) + "s",
                         query._request_mbap.transaction_id, 0,
                         len(pdu) + 1, 0, to_data(pdu)), request)
示例#4
0
 def testParseRequest(self):
     """Test that Modbus Rtu part of the request is understood"""
     query = modbus_rtu.RtuQuery()
     i = 0
     for pdu in ["", "a", "a" * 127, "abcdefghi"]:
         request = query.build_request(to_data(pdu), i)
         (slave, extracted_pdu) = query.parse_request(request)
         self.assertEqual(extracted_pdu, to_data(pdu))
         self.assertEqual(slave, i)
         i += 1
示例#5
0
 def testBuildRequestWithPdu(self):
     """Test the request returned by building a request with a pdu"""
     query = modbus_rtu.RtuQuery()
     for i in range(247):
         for pdu in ["", "a", "a"*127, "abcdefghi"]:
             request = query.build_request(to_data(pdu), i)
             expected = struct.pack(">B"+str(len(pdu))+"s", i, to_data(pdu))
             expected_crc = crc16_alternative(expected)
             expected += struct.pack(">H", expected_crc)
             self.assertEqual(expected, request)
示例#6
0
 def testBuildRequestWithPdu(self):
     """Test the request returned by building a request with a pdu"""
     query = modbus_rtu.RtuQuery()
     for i in range(247):
         for pdu in ["", "a", "a"*127, "abcdefghi"]:
             request = query.build_request(to_data(pdu), i)
             expected = struct.pack(">B"+str(len(pdu))+"s", i, to_data(pdu))
             expected_crc = crc16_alternative(expected)
             expected += struct.pack(">H", expected_crc)
             self.assertEqual(expected, request)
示例#7
0
 def testBuildResponse(self):
     """Test that the response of an request is build properly"""
     query = modbus_rtu.RtuQuery()
     i = 0
     for pdu in ["", "a", "a" * 127, "abcdefghi"]:
         request = query.build_request(to_data(pdu), i)
         response = query.build_response(to_data(pdu))
         response_pdu = query.parse_response(response)
         self.assertEqual(to_data(pdu), response_pdu)
         i += 1
示例#8
0
 def testParseRequest(self):
     """Test that Modbus Rtu part of the request is understood"""
     query = modbus_rtu.RtuQuery()
     i = 0
     for pdu in ["", "a", "a"*127, "abcdefghi"]:
         request = query.build_request(to_data(pdu), i)
         (slave, extracted_pdu) = query.parse_request(request)
         self.assertEqual(extracted_pdu, to_data(pdu))
         self.assertEqual(slave, i)
         i += 1
示例#9
0
 def testBuildResponse(self):
     """Test that the response of an request is build properly"""
     query = modbus_rtu.RtuQuery()
     i = 0
     for pdu in ["", "a", "a"*127, "abcdefghi"]:
         request = query.build_request(to_data(pdu), i)
         response = query.build_response(to_data(pdu))
         response_pdu = query.parse_response(response)
         self.assertEqual(to_data(pdu), response_pdu)
         i += 1
 def testParseWrongLengthResponse(self):
     """Test an error is raised if the length is not ok"""
     query = modbus_tcp.TcpQuery()
     pdu = to_data('a')
     request = query.build_request(pdu, 0)
     response = struct.pack(">HHHB" + str(len(pdu)) + "s",
                            query._request_mbap.transaction_id,
                            query._request_mbap.protocol_id + 1, len(pdu),
                            query._request_mbap.unit_id, to_data('pdu'))
     self.assertRaises(modbus_tk.modbus_tcp.ModbusInvalidMbapError,
                       query.parse_response, response)
示例#11
0
 def testParseRespone(self):
     """Test that Modbus Rtu part of the response is understood"""
     query = modbus_rtu.RtuQuery()
     for i in range(247):
         for pdu in ["", "a", "a"*127, "abcdefghi"]:
             request = query.build_request(to_data(pdu), i)
             response = struct.pack(">B"+str(len(pdu))+"s", i, to_data(pdu))
             response_crc = crc16_alternative(response)
             response += struct.pack(">H", response_crc)
             extracted = query.parse_response(response)
             self.assertEqual(extracted, to_data(pdu))
示例#12
0
 def testParseRespone(self):
     """Test that Modbus Rtu part of the response is understood"""
     query = modbus_rtu.RtuQuery()
     for i in range(247):
         for pdu in ["", "a", "a"*127, "abcdefghi"]:
             request = query.build_request(to_data(pdu), i)
             response = struct.pack(">B"+str(len(pdu))+"s", i, to_data(pdu))
             response_crc = crc16_alternative(response)
             response += struct.pack(">H", response_crc)
             extracted = query.parse_response(response)
             self.assertEqual(extracted, to_data(pdu))
 def testParseRespone(self):
     """Test that Modbus TCP part of the response is understood"""
     query = modbus_tcp.TcpQuery()
     for pdu in ["", "a", "a" * 127, "abcdefghi"]:
         request = query.build_request(to_data(pdu), 0)
         response = struct.pack(">HHHB" + str(len(pdu)) + "s",
                                query._request_mbap.transaction_id,
                                query._request_mbap.protocol_id,
                                len(pdu) + 1, query._request_mbap.unit_id,
                                to_data(pdu))
         extracted = query.parse_response(response)
         self.assertEqual(extracted, to_data(pdu))
示例#14
0
 def testParseWrongLengthResponse(self):
     """Test an error is raised if the length is not ok"""
     query = modbus_tcp.TcpQuery()
     pdu = to_data('a')
     request = query.build_request(pdu, 0)
     response = struct.pack(
         ">HHHB"+str(len(pdu))+"s",
         query._request_mbap.transaction_id,
         query._request_mbap.protocol_id+1,
         len(pdu),
         query._request_mbap.unit_id,
         to_data('pdu')
     )
     self.assertRaises(modbus_tk.modbus_tcp.ModbusInvalidMbapError, query.parse_response, response)
示例#15
0
 def testParseRespone(self):
     """Test that Modbus TCP part of the response is understood"""
     query = modbus_tcp.TcpQuery()
     for pdu in ["", "a", "a"*127, "abcdefghi"]:
         request = query.build_request(to_data(pdu), 0)
         response = struct.pack(
             ">HHHB" + str(len(pdu)) + "s",
             query._request_mbap.transaction_id,
             query._request_mbap.protocol_id,
             len(pdu) + 1,
             query._request_mbap.unit_id,
             to_data(pdu)
         )
         extracted = query.parse_response(response)
         self.assertEqual(extracted, to_data(pdu))
示例#16
0
 def testCrc16ForAllCharValues(self):
     """Check that the CRC16 is generated properly for all chars"""
     s = to_data('')
     for i in range(256):
         s += struct.pack(">B", i)
         self.assertEqual(crc16_alternative(s),
                          modbus_tk.utils.calculate_crc(s))
 def testBuildRequest(self):
     """Test the mbap returned by building a request"""
     query = modbus_tcp.TcpQuery()
     request = query.build_request(to_data(""), 0)
     self.assertEqual(
         struct.pack(">HHHB", query._request_mbap.transaction_id, 0, 1, 0),
         request)
示例#18
0
    def _recv(self, expected_length=-1):
        """Receive the response from the slave"""
        response = utils.to_data("")
        start_time = time.time() if self.use_sw_timeout else 0
        readed_len = 0
        while True:
            if self._serial.timeout:
                # serial.read() says if a timeout is set it may return less characters as requested
                # we should update expected_length by readed_len
                read_bytes = self._serial.read(expected_length - readed_len if (expected_length - readed_len) > 0 else 1)
            else:
                read_bytes = self._serial.read(expected_length if expected_length > 0 else 1)
            if self.use_sw_timeout:
                read_duration = time.time() - start_time
            else:
                read_duration = 0
            if (not read_bytes) or (read_duration > self._serial.timeout):
                break
            response += read_bytes
            if expected_length >= 0 and len(response) >= expected_length:
                # if the expected number of byte is received consider that the response is done
                # improve performance by avoiding end-of-response detection by timeout
                break
            readed_len += len(read_bytes)

        retval = call_hooks("modbus_rtu.RtuMaster.after_recv", (self, response))
        if retval is not None:
            return retval
        return response
 def testParseRequestInvalidLength(self):
     """Test that an error is raised if the length is not valid"""
     query = modbus_tcp.TcpQuery()
     i = 0
     for pdu in ["", "a", "a" * 127, "abcdefghi"]:
         request = struct.pack(">HHHB", 0, 0, (len(pdu) + 2), 0)
         self.assertRaises(modbus_tk.modbus_tcp.ModbusInvalidMbapError,
                           query.parse_request, request + to_data(pdu))
 def testBuildRequestWithSlave(self):
     """Test the mbap returned by building a request with a slave"""
     query = modbus_tcp.TcpQuery()
     for i in range(0, 255):
         request = query.build_request(to_data(""), i)
         self.assertEqual(
             struct.pack(">HHHB", query._request_mbap.transaction_id, 0, 1,
                         i), request)
示例#21
0
 def testCrc16ReturnsAlwaysTheSame(self):
     """Check that the CRC16 returns the same result for the same value"""
     test_strings = ("hello world", "a", "12345678910111213141516", "",
                     "modbus-tk", "www.apidev.fr")
     for s in test_strings:
         s = to_data(s)
         self.assertEqual(modbus_tk.utils.calculate_crc(s),
                          modbus_tk.utils.calculate_crc(s))
示例#22
0
 def testCrc16(self):
     """Check that the CRC16 is generated properly"""
     test_strings = ("hello world", "a", "12345678910111213141516", "",
                     "modbus-tk", "www.apidev.fr")
     for s in test_strings:
         s = to_data(s)
         self.assertEqual(crc16_alternative(s),
                          modbus_tk.utils.calculate_crc(s))
示例#23
0
 def testBuildRequest(self):
     """Test the string returned by building a request"""
     query = modbus_rtu.RtuQuery()
     request = query.build_request(to_data(""), 0)
     expected = struct.pack(">B", 0)
     expected_crc = crc16_alternative(expected)
     expected += struct.pack(">H", expected_crc)
     self.assertEqual(expected, request)
示例#24
0
 def testBuildRequest(self):
     """Test the string returned by building a request"""
     query = modbus_rtu.RtuQuery()
     request = query.build_request(to_data(""), 0)
     expected = struct.pack(">B", 0)
     expected_crc = crc16_alternative(expected)
     expected += struct.pack(">H", expected_crc)
     self.assertEqual(expected, request)
示例#25
0
 def testBuildRequestWithSlave(self):
     """Test the mbap returned by building a request with a slave"""
     query = modbus_tcp.TcpQuery()
     for i in range(0, 255):
         request = query.build_request(to_data(""), i)
         self.assertEqual(
             struct.pack(">HHHB", query._request_mbap.transaction_id, 0, 1, i),
             request
         )
示例#26
0
 def testIncIdOfRequest(self):
     """Check that the transaction id is increased when building the request"""
     queries = [modbus_tcp.TcpQuery() for i in range(100)]
     
     for i in range(len(queries)):
         queries[i].build_request(to_data(""), 0)
     
     for i in range(len(queries)-1):
         self.assertEqual(queries[i]._request_mbap.transaction_id+1, queries[i+1]._request_mbap.transaction_id)
示例#27
0
 def testIncIdOfRequest(self):
     """Check that the transaction id is increased when building the request"""
     queries = [modbus_tcp.TcpQuery() for i in range(100)]
     
     for i in range(len(queries)):
         queries[i].build_request(to_data(""), 0)
     
     for i in range(len(queries)-1):
         self.assertEqual(queries[i]._request_mbap.transaction_id+1, queries[i+1]._request_mbap.transaction_id)
示例#28
0
 def testBuildRequestWithSlave(self):
     """Test the string returned by building a request with a slave"""
     query = modbus_rtu.RtuQuery()
     for i in range(0, 256):
         request = query.build_request(to_data(""), i)
         expected = struct.pack(">B", i)
         expected_crc = crc16_alternative(expected)
         expected += struct.pack(">H", expected_crc)
         self.assertEqual(expected, request)
示例#29
0
 def testBuildRequestWithSlave(self):
     """Test the string returned by building a request with a slave"""
     query = modbus_rtu.RtuQuery()
     for i in range(0, 256):
         request = query.build_request(to_data(""), i)
         expected = struct.pack(">B", i)
         expected_crc = crc16_alternative(expected)
         expected += struct.pack(">H", expected_crc)
         self.assertEqual(expected, request)
示例#30
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))
示例#31
0
 def testParseWrongCrcResponse(self):
     """Test an error is raised if wrong transaction id"""
     query = modbus_rtu.RtuQuery()
     pdu = to_data("a")
     request = query.build_request(pdu, 5)
     response = struct.pack(">B" + str(len(pdu)) + "s", 5, pdu)
     response_crc = crc16_alternative(response)+1
     response += struct.pack(">H", response_crc)
     self.assertRaises(modbus_tk.modbus.ModbusInvalidResponseError, query.parse_response, response)
示例#32
0
 def testParseWrongCrcResponse(self):
     """Test an error is raised if wrong transaction id"""
     query = modbus_rtu.RtuQuery()
     pdu = to_data("a")
     request = query.build_request(pdu, 5)
     response = struct.pack(">B" + str(len(pdu)) + "s", 5, pdu)
     response_crc = crc16_alternative(response)+1
     response += struct.pack(">H", response_crc)
     self.assertRaises(modbus_tk.modbus.ModbusInvalidResponseError, query.parse_response, response)
示例#33
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))
示例#34
0
 def testParseRequestInvalidLength(self):
     """Test that an error is raised if the length is not valid"""
     query = modbus_tcp.TcpQuery()
     i = 0
     for pdu in ["", "a", "a"*127, "abcdefghi"]:
         request = struct.pack(">HHHB", 0, 0, (len(pdu)+2), 0)
         self.assertRaises(
             modbus_tk.modbus_tcp.ModbusInvalidMbapError,
             query.parse_request,
             request + to_data(pdu)
         )
示例#35
0
 def testBuildRequestWithPdu(self):
     """Test the mbap returned by building a request with a pdu"""
     query = modbus_tcp.TcpQuery()
     for pdu in ["", "a", "a"*127, "abcdefghi"]:
         request = query.build_request(to_data(pdu), 0)
         self.assertEqual(
             struct.pack(
                 ">HHHB"+str(len(pdu))+"s", query._request_mbap.transaction_id, 0, len(pdu)+1, 0, to_data(pdu)
             ),
             request
         )
示例#36
0
 def _recv(self, expected_length=-1):
     """Receive the response from the slave"""
     response = to_data('')
     length = 255
     while len(response) < length:
         rcv_byte = self._sock.recv(1)
         if rcv_byte:
             response += rcv_byte
         if expected_length >= 0 and len(response) >= expected_length:
             break
     retval = call_hooks("modbus_rtu_over_tcp.RtuOverTcpMaster.after_recv",
                         (self, response))
     if retval is not None:
         return retval
     return response
示例#37
0
    def _recv(self, expected_length=-1):
        """Receive the response from the slave"""
        response = utils.to_data("")
        while True:
            read_bytes = self._serial.read(expected_length if expected_length > 0 else 1)
            if not read_bytes:
                break
            response += read_bytes
            if expected_length >= 0 and len(response) >= expected_length:
                #if the expected number of byte is received consider that the response is done
                #improve performance by avoiding end-of-response detection by timeout
                break

        retval = call_hooks("modbus_rtu.RtuMaster.after_recv", (self, response))
        if retval is not None:
            return retval
        return response
示例#38
0
    def _recv(self, expected_length=-1):
        """Receive the response from the slave"""
        response = utils.to_data("")
        while True:
            read_bytes = self._serial.read(expected_length if expected_length > 0 else 1)
            if not read_bytes:
                break
            response += read_bytes
            if expected_length >= 0 and len(response) >= expected_length:
                #if the expected number of byte is received consider that the response is done
                #improve performance by avoiding end-of-response detection by timeout
                break

        retval = call_hooks("modbus_rtu.RtuMaster.after_recv", (self, response))
        if retval is not None:
            return retval
        return response
示例#39
0
    def _do_run(self):
        """main function of the server"""
        try:
            # check the status of every socket
            request = utils.to_data('')
            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:
                    self._serial.write(response)
                    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))
示例#40
0
 def _recv(self, expected_length=-1):
     """
     Receive the response from the slave
     Do not take expected_length into account because the length of the response is
     written in the mbap. Used for RTU only
     """
     response = to_data('')
     length = 255
     while len(response) < length:
         rcv_byte = self._sock.recv(1)
         if rcv_byte:
             response += rcv_byte
             if len(response) == 6:
                 to_be_recv_length = struct.unpack(">HHH", response)[2]
                 length = to_be_recv_length + 6
         else:
             break
     retval = call_hooks("modbus_tcp.TcpMaster.after_recv", (self, response))
     if retval is not None:
         return retval
     return response
示例#41
0
 def _recv(self, expected_length=-1):
     """
     Receive the response from the slave
     Do not take expected_length into account because the length of the response is
     written in the mbap. Used for RTU only
     """
     response = to_data('')
     length = 255
     while len(response) < length:
         rcv_byte = self._sock.recv(1)
         if rcv_byte:
             response += rcv_byte
             if len(response) == 6:
                 to_be_recv_length = struct.unpack(">HHH", response)[2]
                 length = to_be_recv_length + 6
         else:
             break
     retval = call_hooks("modbus_tcp.TcpMaster.after_recv", (self, response))
     if retval is not None:
         return retval
     return response
示例#42
0
    def _do_run(self):
        """main function of the server"""
        try:
            #check the status of every socket
            request = utils.to_data('')
            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:
                    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))
示例#43
0
 def testParseTooShortRequest(self):
     """Test an error is raised if the request is too short"""
     query = modbus_rtu.RtuQuery()
     for i in range(3):
         self.assertRaises(modbus_tk.modbus.ModbusInvalidRequestError,
                           query.parse_request, to_data("a" * i))
示例#44
0
 def testCrc16ForAllCharValues(self):
     """Check that the CRC16 is generated properly for all chars"""
     s = to_data('')
     for i in range(256):
         s += struct.pack(">B", i)
         self.assertEqual(crc16_alternative(s), modbus_tk.utils.calculate_crc(s))
示例#45
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)
示例#46
0
 def testCrc16(self):
     """Check that the CRC16 is generated properly"""
     test_strings = ("hello world", "a", "12345678910111213141516", "", "modbus-tk", "www.apidev.fr")
     for s in test_strings:
         s = to_data(s)
         self.assertEqual(crc16_alternative(s), modbus_tk.utils.calculate_crc(s))
示例#47
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)
示例#48
0
 def testCrc16ReturnsAlwaysTheSame(self):
     """Check that the CRC16 returns the same result for the same value"""
     test_strings = ("hello world", "a", "12345678910111213141516", "", "modbus-tk", "www.apidev.fr")
     for s in test_strings:
         s = to_data(s)
         self.assertEqual(modbus_tk.utils.calculate_crc(s), modbus_tk.utils.calculate_crc(s))
示例#49
0
 def testBuildRequest(self):
     """Test the mbap returned by building a request"""
     query = modbus_tcp.TcpQuery()
     request = query.build_request(to_data(""), 0)
     self.assertEqual(struct.pack(">HHHB", query._request_mbap.transaction_id, 0, 1, 0), request)
示例#50
0
 def testParseTooShortRequest(self):
     """Test an error is raised if the request is too short"""
     query = modbus_rtu.RtuQuery()
     for i in range(3):
         self.assertRaises(modbus_tk.modbus.ModbusInvalidRequestError, query.parse_request, to_data("a" * i))