001package org.vishia.guiViewCfg; 002 003import java.text.ParseException; 004import java.util.Map; 005import java.util.TreeMap; 006 007import org.vishia.communication.Address_InterProcessComm; 008import org.vishia.communication.InspcDataExchangeAccess; 009import org.vishia.communication.InterProcessComm; 010import org.vishia.communication.InterProcessCommFactory; 011import org.vishia.mainCmd.Report; 012 013/**This class organizes the receiving of data from a automation device. An own thread is created. 014 * In its run-routine the thread waits for receiving data via socket or another adequate 015 * interprocess-communication. 016 * For evaluating the received data the routine {@link OamShowValues#show(byte[], int, int)} is called. 017 * <br><br> 018 * A datagram may contain more as one data-set. The datagram is defined with the inspector-datagram- 019 * definition, see {@link InspcDataExchangeAccess}. 020 * @author Hartmut Schorrig 021 * 022 */ 023public class OamRcvValue implements Runnable 024{ 025 026 /**Associated class which shows the values */ 027 private final OamShowValues showValues; 028 029 /**The thread. Composition. */ 030 private final Thread thread; 031 032 boolean bRun; 033 034 int ctCorruptData; 035 036 boolean bIpcOpened; 037 038 private final Map<String, String> indexUnknownVariable = new TreeMap<String, String>(); 039 040 InspcDataExchangeAccess.InspcDatagram datagramRcv = new InspcDataExchangeAccess.InspcDatagram(); 041 042 InspcDataExchangeAccess.Inspcitem infoEntity = new InspcDataExchangeAccess.Inspcitem(); 043 044 final Report log; 045 046 047 private final InterProcessComm ipc; 048 049 private final Address_InterProcessComm targetAddr = InterProcessCommFactory.getInstance().createAddress("UDP:localHost:60083"); 050 051 byte[] recvData = new byte[1500]; 052 053 byte[] sendData = new byte[1500]; 054 055 public OamRcvValue( 056 OamShowValues showValues 057 , Report log 058 ) 059 { 060 thread = new Thread(this, "oamRcv"); 061 this.log = log; 062 this.showValues = showValues; 063 String ownAddr = "UDP:0.0.0.0:0xeab2"; 064 065 ipc = InterProcessCommFactory.getInstance().create(ownAddr); //It creates and opens the UDP-Port. 066 ipc.open(null, true); //InterProcessComm.receiverShouldbeBlocking); 067 if(ipc != null){ 068 bIpcOpened = true; 069 } 070 } 071 072 /**Starts the receiver thread. */ 073 public void start() 074 { 075 bRun = true; 076 thread.start(); 077 } 078 079 080 /**If the application is stopped, the thread have to be stopped firstly. 081 * The socket will be closed in the receiver-thread, when it is stopped. */ 082 public void stopThread(){ 083 bRun = false; 084 } 085 086 @Override public void run() 087 { 088 int[] result = new int[1]; 089 Address_InterProcessComm sender = ipc.createAddress(); 090 while(bRun){ 091 ipc.receiveData(result, recvData, sender); 092 if(result[0] > 0) { 093 try{ evalTelg(recvData, result[0]); } 094 catch(ParseException exc){ 095 ctCorruptData +=1; 096 } 097 } 098 } 099 ipc.close(); 100 bIpcOpened = false; 101 } 102 103 104 private void evalTelg(byte[] recvData, int nrofBytes) throws ParseException 105 { 106 datagramRcv.assign(recvData, nrofBytes); 107 datagramRcv.setBigEndian(true); 108 int nrofBytesInfoHead = infoEntity.getLengthHead(); 109 int catastrophicalCount = 1000; 110 while(datagramRcv.sufficingBytesForNextChild(infoEntity.getLengthHead()) && --catastrophicalCount >=0){ 111 datagramRcv.addChild(infoEntity); 112 int nrofBytesInfo = infoEntity.getLenInfo(); 113 if(nrofBytesInfo < nrofBytesInfoHead) throw new ParseException("head of info corrupt, nrofBytes", nrofBytesInfo); 114 infoEntity.setLengthElement(nrofBytesInfo); 115 int posBuffer = infoEntity.getPositionInBuffer() + nrofBytesInfoHead; 116 int nrofBytes1 = nrofBytesInfo - nrofBytesInfoHead; 117 this.showValues.show(recvData, nrofBytes1, posBuffer); 118 } 119 this.showValues.showRedraw(); 120 if(catastrophicalCount <0) throw new RuntimeException("unterminated while-loop"); 121 } 122 123 124 public void sendRequest() 125 { 126 try{ Thread.sleep(300);} 127 catch (InterruptedException e) 128 { //dialogZbnfConfigurator.terminate(); 129 } 130 131 ipc.send(sendData, 10, targetAddr); 132 } 133 134 135 136 /**Sheet anchor: close the socket before the object is removed. 137 * @see java.lang.Object#finalize() 138 */ 139 @Override public void finalize() 140 { 141 if(bIpcOpened){ 142 ipc.close(); 143 bIpcOpened = false; 144 } 145 } 146 147 148}