Esempio n. 1
0
	def HandleRequest(self, ReceivedData):
		""" Convert a Modbus server request message into a Modbus 
			server reply message.
		ReceivedData - Binary string with raw request message.
		Returns - Binary string with completed raw reply message. If a 
			server error occurs, an empty string will be returned instead.
		This method handles Modbus protocol functions 1, 2, 3, 4, 5, 6, 15, and 16.
		"""

		# Decode message. 'RequestData' may mean either number of coils or sent data, depending
		# upon the function code being received. For functions 15 and 16, it is a tuple containing
		# data and quantity.
		try:
			TransID, UnitID, FunctionCode, Start, Qty, RequestData, ExceptionCode = \
				self._MBServerMsg.MBRequest(ReceivedData)

		except:
			# Something is wrong with the message, and we can't decode it.
			TransID = 0
			UnitID = 0
			FunctionCode = 0
			Start = 0
			Qty = 0
			RequestData = 0
			ExceptionCode = 0

		try:
			# Read coils. RequestData = quantity.
			if FunctionCode == 1:
				MsgData = MBDataTable.MemMap.GetCoils(Start, Qty)
				ReplyData = self._MBServerMsg.MBResponse(TransID, UnitID, FunctionCode, Start, MsgData)

			# Read discrete inputs.	RequestData = quantity.
			elif FunctionCode == 2:
				MsgData = MBDataTable.MemMap.GetDiscreteInputs(Start, Qty)
				ReplyData = self._MBServerMsg.MBResponse(TransID, UnitID, FunctionCode, Start, MsgData)

			# Read holding registers. RequestData = quantity.
			elif FunctionCode == 3:
				# Get the expanded address.
				if self._ExpAddressing:
					try:
						dtstart = self._DTOffsets[UnitID] + Start
					except:
						raise ExpDTError, self._ExpDTError
				else:
					dtstart = Start

				MsgData = MBDataTable.MemMap.GetHoldingRegisters(dtstart, Qty)
				ReplyData = self._MBServerMsg.MBResponse(TransID, UnitID, FunctionCode, Start, MsgData)

			# Read input registers. RequestData = quantity.
			elif FunctionCode == 4:
				MsgData = MBDataTable.MemMap.GetInputRegisters(Start, Qty)
				ReplyData = self._MBServerMsg.MBResponse(TransID, UnitID, FunctionCode, Start, MsgData)

			# Write single coil. RequestData contains data.
			elif FunctionCode == 5:
				MBDataTable.MemMap.SetCoils(Start, 1, RequestData)
				ReplyData = self._MBServerMsg.MBResponse(TransID, UnitID, FunctionCode, Start, RequestData)

			# Write single holding register. RequestData contains data.
			elif FunctionCode == 6:
				# Get the expanded register maps.
				if self._ExpAddressing:
					try:
						dtstart = self._DTOffsets[UnitID] + Start
					except:
						raise ExpDTError, self._ExpDTError
				else:
					dtstart = Start

				MBDataTable.MemMap.SetHoldingRegisters(dtstart, 1, RequestData)
				ReplyData = self._MBServerMsg.MBResponse(TransID, UnitID, FunctionCode, Start, RequestData)

			# Write multiple coils. RequestData is a tuple.
			elif FunctionCode == 15:
				MBDataTable.MemMap.SetCoils(Start, Qty, RequestData)
				ReplyData = self._MBServerMsg.MBResponse(TransID, UnitID, FunctionCode, \
					Start, ModbusDataLib.Int2BinStr(Qty))

			# Write multiple holding registers. RequestData is a tuple.
			elif FunctionCode == 16:
				# Get the expanded register maps.
				if self._ExpAddressing:
					try:
						dtstart = self._DTOffsets[UnitID] + Start
					except:
						raise ExpDTError, self._ExpDTError
				else:
					dtstart = Start

				MBDataTable.MemMap.SetHoldingRegisters(dtstart, Qty, RequestData)
				ReplyData = self._MBServerMsg.MBResponse(TransID, UnitID, FunctionCode, \
					Start, ModbusDataLib.Int2BinStr(Qty))

			# Modbus exception.
			elif FunctionCode > 127:
				ReplyData = self._MBServerMsg.MBErrorResponse(TransID, UnitID, FunctionCode, ExceptionCode)

			# Something is wrong here and we don't understand the message.
			else:
				ReplyData = self._MBServerMsg.MBErrorResponse(TransID, UnitID, FunctionCode + 128, 1)

		# Extended addressing errors.
		except ExpDTError:
			# Modbus exception 2. The extended UID is not known.
			ReplyData = self._MBServerMsg.MBErrorResponse(TransID, UnitID, FunctionCode + 128, 2)

		except:
			# Modbus exception 4. An error has occured in reading or writing a memory location.
			ReplyData = self._MBServerMsg.MBErrorResponse(TransID, UnitID, FunctionCode + 128, 4)

		# Return the result.
		return ReplyData
Esempio n. 2
0
    def handle_read(self):

        try:
            ReceivedData = self.recv(8192)
        except:
            ReceivedData = None

        if ReceivedData:

            # Decode message. 'RequestData' may mean either number of coils or sent data, depending
            # upon the function code being received. For functions 15 and 16, it is a tuple containing
            # data and quantity.
            try:
                TransID, UnitID, FunctionCode, Start, Qty, RequestData, ExceptionCode = \
                  MBServerMSg.MBRequest(ReceivedData)

            # We can't decode this message at all, so just drop the request and stop here.
            # Can't decode the message, because the length is invalid.
            except ModbusTCPLib.MessageLengthError:
                print('Server %d - Invalid message length. %s' %
                      (CmdOpts.GetFieldPort(), time.ctime()))
                TransID, UnitID, FunctionCode, Start, Qty, RequestData, ExceptionCode = self._GetDefaultData(
                )

            except:
                TransID, UnitID, FunctionCode, Start, Qty, RequestData, ExceptionCode = self._GetDefaultData(
                )

            # Log the incoming messages for reporting purposes.
            StatusReporter.Report.AddFieldRequest(ModbusStatusReportMsg.ModbusServerFieldRequest(TransID, \
              UnitID, FunctionCode, Start, Qty, RequestData))

            ReplyData = ''
            MsgData = [0]
            # Decode messages. If we get an error in reading/writing memory or in constructing messages,
            # we will consider this to be a Modbus exception.
            try:
                if FunctionCode == 1:  # Read coils.
                    MsgData = MemMap.GetCoils(Start, Qty)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       MsgData)

                elif FunctionCode == 2:  # Read discrete inputs.
                    MsgData = MemMap.GetDiscreteInputs(Start, Qty)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       MsgData)

                elif FunctionCode == 3:  # Read holding registers.
                    MsgData = MemMap.GetHoldingRegisters(Start, Qty)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       MsgData)

                elif FunctionCode == 4:  # Read input registers.
                    MsgData = MemMap.GetInputRegisters(Start, Qty)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       MsgData)

                elif FunctionCode == 5:  # Write single coil. RequestData contains data.
                    MemMap.SetCoils(Start, 1, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       RequestData)

                elif FunctionCode == 6:  # Write single holding register. RequestData contains data.
                    MemMap.SetHoldingRegisters(Start, 1, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID,
                                                       FunctionCode, Start,
                                                       RequestData)

                elif FunctionCode == 15:  # Write multiple coils.
                    MemMap.SetCoils(Start, Qty, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID, FunctionCode, \
                      Start, ModbusDataLib.Int2BinStr(Qty))

                elif FunctionCode == 16:  # Write multiple holding registers.
                    MemMap.SetHoldingRegisters(Start, Qty, RequestData)
                    ReplyData = MBServerMSg.MBResponse(TransID, UnitID, FunctionCode, \
                      Start, ModbusDataLib.Int2BinStr(Qty))

                elif FunctionCode > 127:  # Modbus exception.
                    ReplyData = MBServerMSg.MBErrorResponse(
                        TransID, UnitID, FunctionCode, ExceptionCode)
                else:
                    print('Server %d - Unsupported function call' %
                          CmdOpts.GetFieldPort())
                    ReplyData = MBServerMSg.MBErrorResponse(
                        TransID, UnitID, FunctionCode + 128, 1)

            except:
                # Modbus exception 4. An error has occured in reading or writing a memory location.
                ReplyData = MBServerMSg.MBErrorResponse(
                    TransID, UnitID, FunctionCode + 128, 4)

            # Send the reply.
            try:
                self.send(ReplyData)
            except:
                # If we have an error here, there's not much we can do about it.
                print('Server %d - Could not reply to request.' %
                      CmdOpts.GetFieldPort())

            # Log the response messages for reporting purposes.
            StatusReporter.Report.AddFieldResponse(ModbusStatusReportMsg.ModbusServerFieldResponse(TransID, \
               FunctionCode, MsgData, RequestData, Qty, ExceptionCode))

        else:
            self.close()