//: TLink.java
package de.desy.tine.headers;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.util.Arrays;
import java.util.LinkedList;
import de.desy.tine.addrUtils.*;
import de.desy.tine.client.*;
import de.desy.tine.dataUtils.TDataType;
import de.desy.tine.definitions.*;
import de.desy.tine.endianUtils.Swap;
import de.desy.tine.io.TPacket;
import de.desy.tine.server.connections.*;
import de.desy.tine.server.logger.*;
import de.desy.tine.server.properties.*;
// Producer Header structure (published data)
public class TPHdr
{
private static TLinkFactory tlf = null;
private static TLinkFactory getLinkFactory()
{
if (tlf == null) tlf = TLinkFactory.getInstance();
return tlf;
}
public short msgSizeInBytes; // unsigned short
private int umsgSizeInBytes;
public short subId;
public short lnkCompCode; // return code of the eqm call
public short numblks;
public short blknum;
public short mtu; // unsigned short
private int umtu;
public short dFormat; // data format of returned data
public short lnkCounter; // link counter
public short srvProtocol;// tine protocol level
public short xferReason; // transfer reason
public int lnkStarttime; // supplied by caller @ registration (always at byte 20)
public short stsSize; // size of error/status string space
public short stsCode; // status code of call
public int dTimeStamp; // data time stamp, sec part
public int dTimeStampUSEC; // data time stamp, usec part
public int usrStamp; // user-supplied data stamp
public int sysStamp; // systematic data stamp
// non-network fields below ...
static public final int hdrSizeInBytes = (12*2 + 5*4);
static public final int hdrSizeInBytesLegacy = (7*2 + 2*1 + 2*4);
public ByteArrayOutputStream dBuffer;
private byte[] bBuffer = new byte[TPacket.MAX_DATAGRAM_SIZE];
private byte[] stsBuffer = new byte[TStrings.STATUS_SIZE];
// prepare out-going data (server side) ...
private void prepare(int protocolLevel)
{
try
{
dBuffer.reset();
DataOutputStream ds = new DataOutputStream(dBuffer);
ds.writeShort(Swap.Short(msgSizeInBytes));
ds.writeShort(Swap.Short(subId));
ds.writeShort(Swap.Short(lnkCompCode));
ds.writeShort(Swap.Short(numblks));
ds.writeShort(Swap.Short(blknum));
ds.writeShort(Swap.Short(mtu));
if (protocolLevel > 5)
{
ds.writeShort(Swap.Short(dFormat));
ds.writeShort(Swap.Short(lnkCounter));
ds.writeShort(Swap.Short(srvProtocol));
ds.writeShort(Swap.Short(xferReason));
ds.writeInt(Swap.Long(lnkStarttime));
ds.writeShort(Swap.Short(stsSize));
ds.writeShort(Swap.Short(stsCode));
ds.writeInt(Swap.Long(dTimeStamp));
ds.writeInt(Swap.Long(dTimeStampUSEC));
ds.writeInt(Swap.Long(usrStamp));
ds.writeInt(Swap.Long(sysStamp));
}
else
{ // msgSizeInBytes has already been set correctly
ds.writeShort(Swap.Short(dTimeStampUSEC/1000));
ds.writeByte(dFormat);
ds.writeByte(lnkCounter);
ds.writeInt(Swap.Long(dTimeStamp));
ds.writeInt(Swap.Long(lnkStarttime));
}
ds.close();
}
catch (IOException e)
{
e.printStackTrace();
MsgLog.log("TPHdr.prepare",e.toString(),TErrorList.code_failure,e,0);
}
}
private String getStsSting(byte[] b,int offset,int length )
{
int len = 0;
for (int i=0; i<length; i++)
{
if (b[i+offset] == 0) break;
len++;
}
return new String(b,offset,len).trim();
}
public static int UnsignedShort(short sval)
{
int ival = (int)sval;
if (ival < 0) ival += 65536;
return ival;
}
public static short UnsignedShort(int ival)
{
if (ival > 32767) ival -= 65536;
return (short)ival;
}
private LinkedList<TLink> lnks = new LinkedList<TLink>();
// prepare in-coming data (client side) ...
// must examine the status code for 'illegal_protocol' !
public TLink[] toStruct(InetAddress inetAddr, int port, byte[] data, int length,int transport)
{
lnks.clear();
TLink lnk;
int bytesread = 0, pktsread = 0, hdrSize = hdrSizeInBytes;
int datasize, fmtsize, doutsize, extbytes, extsize, extptr;
int len, nlnks = 0;
byte[] d;
boolean isLegacy = false;
boolean isStream = transport == TTransport.STREAM;
ByteArrayInputStream dinBuffer;
long ltime = System.currentTimeMillis();
try
{
dinBuffer = new ByteArrayInputStream(data);
DataInputStream ds = new DataInputStream(dinBuffer);
// overall message length:
if (!isStream)
{ // normal case
len = TPHdr.UnsignedShort(Swap.Short(ds.readShort()));
}
else
{ // a stream combines the 1st 4 bytes into the total (no reassembly)
len = Swap.Long(ds.readInt());
// now do some fancy footwork ...
umsgSizeInBytes = len - 2; // keep the byte counting intact ...
ds.reset(); // go back to the beginning and ...
ds.readShort(); // move over the first 2 bytes
}
if (TLinkFactory.debugLevel > 1) DbgLog.log("TPHdr","recv : " + length + " bytes (hdr " + len + " bytes)");
if (len < length)
{
if (TLinkFactory.debugLevel > 0) DbgLog.log("TPHdr","recv error : abort ! ");
return null;
}
bytesread = 2;
boolean needLinkWatchDogCycle = false;
boolean applyStatusLater = false;
while (bytesread < length)
{
msgSizeInBytes = Swap.Short(ds.readShort());
if (!isStream) umsgSizeInBytes = TPHdr.UnsignedShort(msgSizeInBytes);
if (umsgSizeInBytes < TPHdr.hdrSizeInBytesLegacy)
{ // this is corrupt !
break;
}
subId = Swap.Short(ds.readShort());
lnkCompCode = Swap.Short(ds.readShort());
numblks = Swap.Short(ds.readShort());
blknum = Swap.Short(ds.readShort());
mtu = Swap.Short(ds.readShort());
umtu = TPHdr.UnsignedShort(mtu);
ds.mark(umsgSizeInBytes);
dFormat = Swap.Short(ds.readShort());
lnkCounter = Swap.Short(ds.readShort());
srvProtocol = Swap.Short(ds.readShort());
xferReason = Swap.Short(ds.readShort());
lnkStarttime = Swap.Long(ds.readInt());
if (lnkCompCode == TErrorList.illegal_protocol)
{ // if illegal_protocol then stop reading the stream and try to find the link via inet addr
if ((lnk=tf.findLink(inetAddr,port)) == null)
{ // assume the worst and bail out ...
if (TLinkFactory.debugLevel > 0)
DbgLog.log("TPHdr","link for " + inetAddr.getHostAddress() + " not found!");
break;
}
}
else
{
if (lnkStarttime == TFecEntry.BCAST_ID)
{ // incoming multi-cast
lnk = tf.findLink((int)subId,inetAddr,port);
}
else
{ // a 'normal' link
lnk = tf.findTLink((int)subId,lnkStarttime);
}
if (lnk == null)
{ // one small hope (could be a packed multicast)
if (TLinkFactory.debugLevel > 2) DbgLog.log("TPHdr","id " + subId + " not found!");
bytesread += umsgSizeInBytes;
if (bytesread < length)
{
ds.skipBytes(umsgSizeInBytes-24);
continue;
}
break; // assume the worst and bail out ...
}
if (lnk.getTineProtocol() > 5)
{ // normally true
stsSize = Swap.Short(ds.readShort());
stsCode = Swap.Short(ds.readShort());
dTimeStamp = Swap.Long(ds.readInt());
dTimeStampUSEC = Swap.Long(ds.readInt());
usrStamp = Swap.Long(ds.readInt());
sysStamp = Swap.Long(ds.readInt());
}
}
if (numblks > lnk.dOutput.numblks)
{
lnk.dOutput.numblks = numblks;
lnk.dOutput.reassignBuffers();
}
if (TLinkFactory.debugLevel > 1)
DbgLog.log("TPHdr","data : " + "bytes " + umsgSizeInBytes + ", blknum " + blknum + " from " + numblks + " <" + lnkCompCode + ">");
bytesread += umsgSizeInBytes;
if (lnk.getTineProtocol() == 5)
{ // go back to the mark
ds.reset();
dTimeStampUSEC = (int)Swap.Short(ds.readShort()) * 1000;
dFormat = (short)ds.readByte();
lnkCounter = (short)ds.readByte();
dTimeStamp = Swap.Long(ds.readInt());
lnkStarttime = Swap.Long(ds.readInt());
stsSize = lnkCompCode == 0 ? (short)0 : TStrings.STATUS_SHORTSIZE;
stsCode = lnkCompCode;
usrStamp = 0;
sysStamp = 0;
hdrSize = hdrSizeInBytesLegacy;
isLegacy = true;
}
if (numblks == 1 && blknum != 1)
{ // trap a legacy bug !
blknum = 1;
}
lnk.dOutput.numblks = numblks;
lnk.linkStatusSource = TLink.STATUS_REMOTE;
applyStatusLater = TErrorList.isCoercive(lnkCompCode);
if (lnk.linkStatus != TErrorList.link_blacklisted && !applyStatusLater)
lnk.linkStatus = lnkCompCode;
if (lnk.getRenewalMultiplier() < 2 && lnkCounter > TContract.CTR_RENEWAL)
{ // learn from the server how this was set
lnk.setRenewalMultiplier((short)(lnkCounter/TContract.CTR_RENEWAL));
}
lnk.linkCounter = lnkCounter;
//lnk.linkCompletion = stsCode;
//lnk.xferReason = xferReason;
datasize = lnk.dOutput.dArrayLength * TFormat.formatSizeOf(dFormat)
+ TFormat.getFormatHeaderSize(dFormat);// size of incoming data in bytes
doutsize = umsgSizeInBytes - hdrSize; // size of data + msg in bytes
extsize = 0; extptr = 0;
pktsread++;
boolean addbytes = false;
TSubscription sub = lnk.getSubscription();
if (usrStamp < 0 && lnkCompCode == TErrorList.property_is_mca)
{ // trap this early
lnk.linkStatus = lnkCompCode = TErrorList.illegal_device;
}
switch (lnkCompCode)
{
case TErrorList.mcast_access_required:
short mode = sub != null ? TMode.getBaseMode(sub.mode) : TMode.CM_CANCEL;
switch (mode)
{ // strip off any CM_CONNECT, CM_STREAM, etc. ...
case TMode.CM_TIMER:
case TMode.CM_DATACHANGE:
case TMode.CM_EVENT:
sub.mode |= TMode.CM_NETWORK;
break;
default:
lnk.close();
break;
}
needLinkWatchDogCycle = true;
break;
case TErrorList.call_redirection:
case TErrorList.server_redirection:
Arrays.fill(stsBuffer, (byte)0);
d = stsBuffer;
ds.read(d,0,stsSize); // redirection names
int offset = 0;
String ctx = null;
String srv = null;
String dev = null;
String prp = null;
if (isLegacy)
{ // redirection info squeezed into 32 chars
if (d[offset] != 0) srv = getStsSting(d,offset,16);
offset += 16;
if (d[offset] != 0) prp = getStsSting(d,offset,16);
}
else
{
if (d[offset] != 0) ctx = getStsSting(d,offset,TStrings.CONTEXT_NAME_SIZE);
offset += TStrings.CONTEXT_NAME_SIZE;
if (d[offset] != 0) srv = getStsSting(d,offset,TStrings.EXPORT_NAME_SIZE);
offset += TStrings.EXPORT_NAME_SIZE;
if (d[offset] != 0) dev = getStsSting(d,offset,TStrings.DEVICE_NAME_SIZE);
offset += TStrings.DEVICE_NAME_SIZE;
if (d[offset] != 0) prp = getStsSting(d,offset,TStrings.PROPERTY_NAME_SIZE);
}
if (lnk.getRedirectionKey().length() == 0 && lnk.srvAddr.fecName.compareTo("GENS") == 0)
{ // update local group db cache
getLinkFactory().addItemToGroupCache(lnk.cntName, lnk.expName, srv, lnk.devName);
}
getLinkFactory().addLinkToRedirectionList(lnk, ctx, srv, dev, prp);
if (ctx != null) lnk.cntName = ctx;
if (srv != null) lnk.expName = srv;
if (dev != null) lnk.devName = dev;
if (prp != null)
{
String meta = TMetaProperties.getMetaExtension(lnk.devProperty);
if (meta != null && !TMetaProperties.isMetaProperty(prp)
&& srv.compareToIgnoreCase("HISTORY") != 0) prp += meta;
lnk.devProperty = prp;
}
lnk.rmvBucket();
MsgLog.log("TPHdr", "redirect "+lnk.getRedirectionKey()+" to "+lnk.getFullDeviceNameAndProperty(),0,null,1);
needLinkWatchDogCycle = true;
break;
case TErrorList.has_bitfield_tag:
case TErrorList.has_structure_tag:
Arrays.fill(stsBuffer, (byte)0);
d = stsBuffer;
ds.read(d,0,TStrings.TAG_NAME_SIZE); // tag name
String tag = getStsSting(d,0,TStrings.TAG_NAME_SIZE);// new String(d).trim();
lnk.dOutput.setTag(tag);
needLinkWatchDogCycle = true;
break;
case TErrorList.property_is_mca:
if (usrStamp < 0)
{
lnk.linkStatus = lnkCompCode = TErrorList.illegal_device;
lnk.linkStale = true;
break;
}
if (sysStamp < 0)
{ // gotta be robust !
lnk.linkStatus = lnkCompCode = TErrorList.code_failure;
lnk.linkStale = true;
break;
}
Arrays.fill(stsBuffer, (byte)0);
d = stsBuffer;
ds.read(d,0,stsSize); // is passed a device string ?
String mcadevTag = getStsSting(d,0,8);
if (mcadevTag.compareTo(TStrings.MCADEV_TAG) == 0)
{ // has been passed a device string
dev = getStsSting(d,8,TStrings.DEVICE_NAME_SIZE);
}
else
{
dev = "#0";
}
TMcaLink mca = TLinkFactory.getMcaLinkForReuse(lnk.cntName,lnk.expName,dev,lnk.devProperty);
if (lnk.dOutput.dFormat == TFormat.CF_DEFAULT)
{
lnk.dOutput.dFormat = dFormat;
lnk.dOutput.setArrayLength(1);
lnk.dOutput.setDataObject(1, dFormat);
lnk.dOutput.dCompletionLength = 1;
//lnk.dOutput.blksin = 1; => kept = 0 => don't add to links that notify
}
TLink plnk = null;
if (mca == null)
{ // not yet known, make new (length given by system stamp)
mca = new TMcaLink(lnk,dev,sysStamp);
lnk.linkStatusSource = TLink.STATUS_LOCAL;
lnk.linkStatus = mca.getParent().linkStatus;
if (lnk.linkStatus == TErrorList.not_signalled || lnk.linkStatus < 0)
lnk.linkStatus = 0;
TLinkFactory.addMcaLink(mca);
}
else
{ // is known !
lnk.linkStatusSource = TLink.STATUS_LOCAL;
lnk.linkStatus = 0;
plnk = mca.getParent();
int pollp = plnk.getLinkPollingInterval();
int polld = lnk.getLinkPollingInterval();
if (polld < pollp)
{ // faster rate required
String msg = plnk.getFullDeviceNameAndProperty()+" change to faster polling interval: "+pollp+" -> "+polld+" msec";
MsgLog.log("TPHdr", msg,0,null,1);
plnk.isLinkReassignment = true;
plnk.attach(plnk.getSubscription().mode, mca, polld);
plnk.linkStatus = 0;
}
}
if (mca != null)
{ // set the mcaIndex (from the user stamp)
lnk.setMcaIndex(usrStamp+1);
if (lnk.getMcaDevice() == null) lnk.setMcaDevice(dev);
lnk.setBoundLink(mca.getParent());
lnk.dOutput.setArrayLength(1);
lnk.dOutput.dCompletionLength = 1;
lnk.getSubscription().mode = TMode.CM_REGISTER;
mca.add(lnk);
if (TLinkFactory.debugLevel > 2) DbgLog.log("TPHdr", "add "+lnk.getFullDeviceNameAndProperty()+" (id "+lnk.linkId+")" + " to mca parent "+mca.getParent().getFullDeviceNameAndProperty()+" (id "+mca.getParent().linkId+")");
}
if (plnk != null && plnk.hasNotifiedOnce)
{ // have to make sure the parent mca link gets notified !
if (plnk.dOutput != null && plnk.dOutput.blksin == 0)
{ // likely due to DATACHANGE ACK. (a sendLinkRequest which doesn't send anything back)
plnk.dOutput.blksin = plnk.dOutput.numblks;
MsgLog.log("TPHdr","reset MCA parent "+plnk.getFullDeviceNameAndProperty()+" output block counter",lnkCompCode,null,2);
}
plnk.hasNotifiedOnce = false;
plnk.linkStale = true;
lnks.add(plnk); // add him in the notifiers list ...
nlnks++;
MsgLog.log("TPHdr","reset MCA parent "+plnk.getFullDeviceNameAndProperty()+" notification",lnkCompCode,null,2);
}
break;
case TErrorList.invalid_datarequest:
lnk.canTimeout = false;
if (lnk.dOutput.dArrayLength > sysStamp && lnk.dOutput.dFormat == usrStamp)
{
MsgLog.log("TPHdr", lnk.getFullDeviceNameAndProperty()+ " adjust data length "+lnk.dOutput.dArrayLength+" to "+sysStamp,lnkCompCode,null,1);
lnk.dOutput.dArrayLength = sysStamp;
needLinkWatchDogCycle = true;
}
else
{
short f = TFormat.getFormatDataType((short)usrStamp);
TLinkFactory.getInstance().addLinkToReLinkList(lnk, sysStamp, f);
String fmt = TFormat.toString(lnk.dOutput.dFormat);
MsgLog.log("TPHdr", lnk.getFullDeviceNameAndProperty()+ " adjust data length and type from "+lnk.dOutput.dArrayLength+" "+fmt+
" to "+sysStamp+" "+TFormat.toString(f),lnkCompCode,null,1);
needLinkWatchDogCycle = true;
}
break;
case TErrorList.invalid_interval:
MsgLog.log("TPHdr", lnk.getFullDeviceNameAndProperty()+ " adjust polling interval from "+lnk.devTimeout+" to "+sysStamp,lnkCompCode,null,1);
if (sub != null) sub.pollingInterval = sysStamp;
lnk.devTimeout = sysStamp;
needLinkWatchDogCycle = true;
break;
case TErrorList.reacquire_address:
MsgLog.log("TPHdr", lnk.getFullDeviceNameAndProperty()+ " received reacquire address",lnkCompCode,null,1);
needLinkWatchDogCycle = true;
break;
case TErrorList.illegal_protocol:
if (!isLegacy)
{ // set it back and try again
//lnk.setTineProtocol(5);
}
// TODO:
// find the entry and switch to 5 if I was at 6
// if CM_MCAST -> gotta join the legacy MCAST group
break;
case TErrorList.get_subscription_id:
lnk.srvId = Swap.Short(ds.readShort());
break;
case TErrorList.non_existent_elem:
lnk.linkInvalidCount++;
default:
// non-zero code
lnk.linkStale = true;
if (doutsize < stsSize && lnk.dOutput.blksin == 0)
{ // no accompanying status string ?
lnk.dOutput.bytesin = 0;
continue;
}
if ((lnkCompCode & TErrorList.CE_SENDDATA) != TErrorList.CE_SENDDATA)
{ // no accompanying data
datasize = 0;
}
extsize = 0;
extbytes = doutsize*blknum - datasize;
//TODO: this logic is faulty: datasize refers to original request
if (blknum == numblks || extbytes > 0)
{ // either last or next to last block ...
if (blknum == numblks)
{ // last block contains the last piece (or all) of the status string
if (numblks == 1 && doutsize < stsSize)
{ // how ?
continue;
}
extsize = doutsize < stsSize ? doutsize : stsSize;
extptr = stsSize - extsize;
}
else if (extbytes > 0)
{ // this will occasionally be true (2nd to last block has some room)
extsize = extbytes;
extptr = 0;
}
doutsize -= extsize;
lnk.dOutput.bytesin += extsize;
}
if (datasize == 0)
{ // as set above -> don't fall thru
lnk.dOutput.blknum = blknum;
lnk.dOutput.blksin = 1;
lnk.dOutput.numblks = 1;
break;
}
case 0:
lnk.linkStale = true;
if (lnk.dOutput.dFormat == TFormat.CF_DEFAULT) synchronized (lnk.dOutput)
{
lnk.dOutput.dFormat = dFormat;
if ((fmtsize = TFormat.formatSizeOf(lnk.dOutput.dFormat)) < 1) continue;
// worst case array length calculation :
lnk.dOutput.dArrayLength = (doutsize/fmtsize) * lnk.dOutput.numblks;
lnk.dOutput.dArrayLength -= TFormat.getFormatHeaderSize(dFormat)/fmtsize;
if (dFormat != TFormat.CF_STRUCT && lnk.dOutput.getDataObject() == null)
{
lnk.dOutput.setDataObject(lnk.dOutput.dArrayLength,lnk.dOutput.dFormat);
}
if (lnk.hasDependencies())
{ // already has dependencies ? (a jDDD specialty)
TLink xlnk;
LinkedList<TLink> xlst = lnk.getDependencies();
TDataType dout;
for (int k=0; k<xlst.size(); k++)
{
if ((xlnk = (TLink)xlst.get(k)) == null) continue;
dout = xlnk.getOutputDataObject();
if (dout.dFormat != TFormat.CF_DEFAULT) continue;
int dlen = lnk.dOutput.dArrayLength;
if (xlnk.getMcaDevice() != null) dlen = 1;
dout.setDataObject(dlen,lnk.dOutput.dFormat);
dout.dArrayLength = dlen;
dout.dFormat = lnk.dOutput.dFormat;
dout.dTimestamp = (long) dTimeStamp * 1000 + (long) (dTimeStampUSEC / 1000);
dout.timestamp = dTimeStamp;
dout.timestampMSEC = dTimeStampUSEC / 1000;
dout.timestampUSEC = dTimeStampUSEC;
dout.usrDataStamp = usrStamp;
dout.sysDataStamp = sysStamp;
dout.xferReason = xferReason;
}
}
// will be adjusted properly in InterpretIncomingData() from the factory
lnk.adjustDefaultValues = true;
}
// push this data set into the corresponding TDataType object
int sizeInBytes = umsgSizeInBytes-hdrSize-extsize;
d = bBuffer;
ds.read(d,0,sizeInBytes);
addbytes = lnk.dOutput.update(d,0,sizeInBytes,blknum,lnkCounter);
break;
}
if (extsize > 0)
{ // there is an accompanying status string
d = new byte[extsize];
ds.read(d,0,d.length);
if (extptr + extsize <= TStrings.STATUS_SIZE)
{
System.arraycopy(d,0,lnk.linkStatusStringBuffer,extptr,extsize);
}
else
{
MsgLog.log("TPHdr.toStruct", "status string size mismatch: "+extsize+" bytes at position "+extptr,TErrorList.remitted_data_lost,null,0);
}
}
if (applyStatusLater) lnk.linkStatus = lnkCompCode;
if (lnk.linkStatus == TErrorList.link_blacklisted)
{ // link has been black-listed : overwrite any incoming status string
d = TErrorList.getErrorString(TErrorList.link_blacklisted).getBytes();
extsize = d.length; extptr = 0;
if (extsize > lnk.linkStatusStringBuffer.length) extsize = lnk.linkStatusStringBuffer.length;
System.arraycopy(d,0,lnk.linkStatusStringBuffer,extptr,extsize);
}
if (addbytes) lnk.dOutput.bytesin += doutsize;
if (lnk.dOutput.blksin == lnk.dOutput.numblks)
{
// lnk.dOutput.bytesin = 0; < not here! reset in InterpretIncomingData().
lnk.canTimeout = false;
lnk.dOutput.resetBuffersReady();
lnk.dOutput.timestamp = dTimeStamp;
lnk.dOutput.timestampMSEC = dTimeStampUSEC / 1000;
lnk.dOutput.timestampUSEC = dTimeStampUSEC;
lnk.dOutput.dTimestamp = (long) dTimeStamp * 1000 + (long) (dTimeStampUSEC / 1000);
lnk.dOutput.usrDataStamp = usrStamp;
lnk.dOutput.sysDataStamp = sysStamp;
lnk.dOutput.xferReason = xferReason;
lnk.getSubscription().linkLastTime = ltime;
lnks.add(lnk);
if (TLinkFactory.debugLevel > 1) DbgLog.log("TPHdr","adding link "+lnk.getFullDeviceNameAndProperty()+" to incoming links list");
nlnks++;
}
}
if (TLinkFactory.debugLevel > 1) DbgLog.log("TPHdr",pktsread + " incoming contracts scanned");
ds.close();
dinBuffer.close();
if (needLinkWatchDogCycle) TLinkFactory.watchdogCycle();
}
catch (IOException e)
{
e.printStackTrace();
MsgLog.log("TPHdr.toStruct",e.toString(),TErrorList.code_failure,e,0);
}
return lnks.toArray(new TLink[0]);
}
TLinkFactory tf;
/**
* Attach the object to a client link factory ...
* Creation date: (8/21/01 6:33:36 PM)
*/
public TPHdr(TLinkFactory tfactory)
{
tf = tfactory;
}
// going out (server-side) ...
public TPHdr(int msgsize,TClientEntry clnTblEntry,TContractTable conTblEntry)
{
boolean isStream = TTransport.isStream(clnTblEntry.cln.inetProtocol);
umsgSizeInBytes = msgsize;
msgSizeInBytes = (short)msgsize; // will be set by caller to appropriate size (P5 or P6)
srvProtocol = 6; // TODO make a constant somewhere
if (clnTblEntry != null && clnTblEntry.sts != null)
{
subId = clnTblEntry.sts.id;
lnkCompCode = clnTblEntry.sts.statusCode;
if (lnkCompCode != 0) stsSize = TStrings.STATUS_SIZE;
numblks = clnTblEntry.sts.numblks;
blknum = clnTblEntry.sts.blknum;
umtu = clnTblEntry.sts.mtu;
mtu = UnsignedShort(umtu);
lnkCounter = clnTblEntry.sts.counter;
lnkStarttime = (int)(clnTblEntry.sts.starttime/1000);
xferReason = clnTblEntry.sts.Stale;
stsCode = (short)TErrorList.getErrorCode(conTblEntry.compStatus);
}
if (conTblEntry != null)
{
srvProtocol = clnTblEntry.cln.tineProtocol;
dTimeStampUSEC = (int)((conTblEntry.dtimestamp%1000)*1000);
dTimeStamp = (int)(conTblEntry.dtimestamp/1000);
usrStamp = conTblEntry.usrstamp;
sysStamp = conTblEntry.sysstamp;
if (conTblEntry.contract != null) dFormat = conTblEntry.contract.dataFormatOut;
}
dBuffer = new ByteArrayOutputStream(hdrSizeInBytes);
if (isStream) numblks = blknum = 1;
prepare(srvProtocol);
}
}