def _port_pollin(self): chars = self._port.drain() if self._buffer is None: self._buffer = array.array('c') self._packet_length = 4 #shortest legit packet self._buffer.extend(chars) if len( self._buffer ) >= self._packet_length: #might be a good packet, otherwise wait for more packet_type = ord(self._buffer[1]) if not packet_type_vs_length.has_key( packet_type): #don't crock this one self._buffer = None #reset the packet processing return packet_length = packet_type_vs_length[packet_type] if packet_length < 0: #must be variable length packet packet_length = abs(packet_length) if len(self._buffer ) < packet_length: #not enough of the packet in yet return #try again when more comes in packet_length = packet_length + ord( self._buffer[packet_length - 3]) #calc variable length packet size if len(self._buffer) >= packet_length: #enought to test the crc chars = self._buffer self._buffer = None #reset packet parsing regardless of what happens below bbuffer = array.array('B', chars[:packet_length].tostring()) #is checksum good? if crc(bbuffer) == 0: #things is gud if debug: print 'command' dump(chars) response = self.owner.command(chars) if response is None: # message sent to a Modbus that does not exist return response.append_crc() if debug: print 'response:', response dump(response.buffer) self._port.write(response.buffer) # If this is a Megatron RS485 port then consume echoed transmit characters # Wait for up to 2 seconds to see our echoed transmit data. if self.megatron_485: try: self.port.read(array.array('c'), len(response.buffer), 2.0) except: msglog.exception() else: if debug: print 'crc failed - might be response' return
def _port_pollin(self): chars = self._port.drain() if self._buffer is None: self._buffer = array.array("c") self._packet_length = 4 # shortest legit packet self._buffer.extend(chars) if len(self._buffer) >= self._packet_length: # might be a good packet, otherwise wait for more packet_type = ord(self._buffer[1]) if not packet_type_vs_length.has_key(packet_type): # don't crock this one self._buffer = None # reset the packet processing return packet_length = packet_type_vs_length[packet_type] if packet_length < 0: # must be variable length packet packet_length = abs(packet_length) if len(self._buffer) < packet_length: # not enough of the packet in yet return # try again when more comes in packet_length = packet_length + ord(self._buffer[packet_length - 3]) # calc variable length packet size if len(self._buffer) >= packet_length: # enought to test the crc chars = self._buffer self._buffer = None # reset packet parsing regardless of what happens below bbuffer = array.array("B", chars[:packet_length].tostring()) # is checksum good? if crc(bbuffer) == 0: # things is gud if debug: print "command" dump(chars) response = self.owner.command(chars) if response is None: # message sent to a Modbus that does not exist return response.append_crc() if debug: print "response:", response dump(response.buffer) self._port.write(response.buffer) # If this is a Megatron RS485 port then consume echoed transmit characters # Wait for up to 2 seconds to see our echoed transmit data. if self.megatron_485: try: self.port.read(array.array("c"), len(response.buffer), 2.0) except: msglog.exception() else: if debug: print "crc failed - might be response" return
def dump(self, msg, hdr=None, offset=0): return dump(msg, hdr, offset, self.dump_cpl)
def _service_bbmd_queue( BBMD_queue ): #loop forever getting messages from the queue and servicing them global _module_lock while 1: # a tuple of network number, Addr, string a_message = BBMD_queue.get() #process the incoming message answer = None network = a_message[0] addr = Addr(a_message[1]) message_string = a_message[2] if debug > 1: print "BBMD recv: network=",network print "BBMD recv: from=",addr dump(message_string, "BBMD recv") if not BBMD_servers.has_key(network): continue bbmd = BBMD_servers[network] bdt = bbmd.bdt fdt = bbmd.fdt if ord(message_string[0]) != 0x81: #not bvlc frame # @fixme Just log it and toss the message. raise EInvalidValue('frame_type', ord(message_string[0]), text='Not a BVLC frame') # extract the 'BVLC Function' octet bvlc_function = ord(message_string[1]) if (bvlc_function == 0x0A): #OriginalUnicastNPDU if debug > 2: print "BBMD rcvd: OriginalUnicastNPDU:",network elif (bvlc_function == 0x0B): #OriginalBroadcastNPDU if debug > 2: print "BBMD rcvd: OriginalBroadcastNPDU:",network if bbmd.enable: obn = OriginalBroadcastNPDU(decode=message_string).npdu if debug > 2: print "BBMD send: ForwardedNPDU network:",network print "BBMD send: for=",addr dump(obn, "BBMD npdu") bdt.forward_original_broadcast_message(network, addr, obn) fdt.forward_original_broadcast_message(network, addr, obn) elif (bvlc_function == 0x00): #Result if debug > 2: print "BBMD rcvd: Result:",network pass elif (bvlc_function == 0x01): #WriteBroadcastDistributionTable if debug > 2: print "BBMD rcvd: WriteBroadcastDistributionTable:",network answer = bdt.write_new_table_contents( WriteBroadcastDistributionTable(decode=message_string)) elif (bvlc_function == 0x02): #ReadBroadcastDistributionTable if debug > 2: print "BBMD rcvd: ReadBroadcastDistributionTable:",network answer = bdt.read_table() elif (bvlc_function == 0x03): #ReadBroadcastDistributionTableAck if debug > 2: print "BBMD rcvd: ReadBroadcastDistributionTableAck:",network if bbmd.report_bdt: bbmd.report_bdt.read_broadcast_distributioan_table_ack( network, addr, ReadBroadcastDistributionTableAck( decode=message_string)) elif (bvlc_function == 0x04): #ForwardedNPDU if debug > 2: print "BBMD rcvd: ForwardedNPDU network",network if bbmd.enable: fnpdu = ForwardedNPDU(decode=message_string) if debug > 2: print "BBMD Broadcast ForwardedNPDU network",network print "BBMD broadcast for=", fnpdu.originating_address dump(fnpdu.npdu, "BBMD npdu") bdt.broadcast_forwarded_message(network, fnpdu) fdt.broadcast_forwarded_message(network, fnpdu) elif (bvlc_function == 0x05): #RegisterForeignDevice if debug > 2: print "BBMD rcvd: RegisterForeignDevice network",network if bbmd.enable: answer = fdt.register_foreign_device( RegisterForeignDevice(addr, decode=message_string)) elif (bvlc_function == 0x06): #ReadForeignDeviceTable answer = fdt.read_table() elif (bvlc_function == 0x07): #ReadForeignDeviceTableAck pass elif (bvlc_function == 0x08): #DeleteForeignDeviceTableEntry answer = fdt.delete_entry(DeleteForeignDeviceTableEntry( decode=message_string)) elif (bvlc_function == 0x09): #DistributeBroadcastToNetwork if debug > 2: print "BBMD rcvd: DistributeBroadcastToNetwork network",\ network if bbmd.enable: try: dbtn = DistributeBroadcastToNetwork( decode=message_string) answer = ForwardedNPDU (addr, dbtn.npdu) bdt.distribute(network, addr, answer) fdt.distribute(network, addr, answer) #locally broadcast the forwared npdu addr = Addr(bbmd.broadcast_address) except: msglog.exception() answer = Result(0x0060) else: if debug > 2: print "BBMD rcvd: Unknown message" if (answer): if debug > 1: _dump_send(network, addr.address, answer.encoding) send(network, addr.address, answer.encoding)
def _dump_send(network, address, msg): print "BBMD send: network =", network print "BBMD send: address =", Addr(address) dump(msg, "BBMD send:")
def _service_bbmd_queue(BBMD_queue): #loop forever getting messages from the queue and servicing them global _module_lock while 1: # a tuple of network number, Addr, string a_message = BBMD_queue.get() #process the incoming message answer = None network = a_message[0] addr = Addr(a_message[1]) message_string = a_message[2] if debug > 1: print "BBMD recv: network=", network print "BBMD recv: from=", addr dump(message_string, "BBMD recv") if not BBMD_servers.has_key(network): continue bbmd = BBMD_servers[network] bdt = bbmd.bdt fdt = bbmd.fdt if ord(message_string[0]) != 0x81: #not bvlc frame # @fixme Just log it and toss the message. raise EInvalidValue('frame_type', ord(message_string[0]), text='Not a BVLC frame') # extract the 'BVLC Function' octet bvlc_function = ord(message_string[1]) if (bvlc_function == 0x0A): #OriginalUnicastNPDU if debug > 2: print "BBMD rcvd: OriginalUnicastNPDU:", network elif (bvlc_function == 0x0B): #OriginalBroadcastNPDU if debug > 2: print "BBMD rcvd: OriginalBroadcastNPDU:", network if bbmd.enable: obn = OriginalBroadcastNPDU(decode=message_string).npdu if debug > 2: print "BBMD send: ForwardedNPDU network:", network print "BBMD send: for=", addr dump(obn, "BBMD npdu") bdt.forward_original_broadcast_message(network, addr, obn) fdt.forward_original_broadcast_message(network, addr, obn) elif (bvlc_function == 0x00): #Result if debug > 2: print "BBMD rcvd: Result:", network pass elif (bvlc_function == 0x01): #WriteBroadcastDistributionTable if debug > 2: print "BBMD rcvd: WriteBroadcastDistributionTable:", network answer = bdt.write_new_table_contents( WriteBroadcastDistributionTable(decode=message_string)) elif (bvlc_function == 0x02): #ReadBroadcastDistributionTable if debug > 2: print "BBMD rcvd: ReadBroadcastDistributionTable:", network answer = bdt.read_table() elif (bvlc_function == 0x03): #ReadBroadcastDistributionTableAck if debug > 2: print "BBMD rcvd: ReadBroadcastDistributionTableAck:", network if bbmd.report_bdt: bbmd.report_bdt.read_broadcast_distributioan_table_ack( network, addr, ReadBroadcastDistributionTableAck(decode=message_string)) elif (bvlc_function == 0x04): #ForwardedNPDU if debug > 2: print "BBMD rcvd: ForwardedNPDU network", network if bbmd.enable: fnpdu = ForwardedNPDU(decode=message_string) if debug > 2: print "BBMD Broadcast ForwardedNPDU network", network print "BBMD broadcast for=", fnpdu.originating_address dump(fnpdu.npdu, "BBMD npdu") bdt.broadcast_forwarded_message(network, fnpdu) fdt.broadcast_forwarded_message(network, fnpdu) elif (bvlc_function == 0x05): #RegisterForeignDevice if debug > 2: print "BBMD rcvd: RegisterForeignDevice network", network if bbmd.enable: answer = fdt.register_foreign_device( RegisterForeignDevice(addr, decode=message_string)) elif (bvlc_function == 0x06): #ReadForeignDeviceTable answer = fdt.read_table() elif (bvlc_function == 0x07): #ReadForeignDeviceTableAck pass elif (bvlc_function == 0x08): #DeleteForeignDeviceTableEntry answer = fdt.delete_entry( DeleteForeignDeviceTableEntry(decode=message_string)) elif (bvlc_function == 0x09): #DistributeBroadcastToNetwork if debug > 2: print "BBMD rcvd: DistributeBroadcastToNetwork network",\ network if bbmd.enable: try: dbtn = DistributeBroadcastToNetwork(decode=message_string) answer = ForwardedNPDU(addr, dbtn.npdu) bdt.distribute(network, addr, answer) fdt.distribute(network, addr, answer) #locally broadcast the forwared npdu addr = Addr(bbmd.broadcast_address) except: msglog.exception() answer = Result(0x0060) else: if debug > 2: print "BBMD rcvd: Unknown message" if (answer): if debug > 1: _dump_send(network, addr.address, answer.encoding) send(network, addr.address, answer.encoding)