
com.cosylab.epics.caj.impl.handlers.AbstractCAResponseHandler Maven / Gradle / Ivy
Go to download
JCA is an EPICS Channel Access library for Java. For more information concerning EPICS or Channel Access please refer to the <a href="http://www.aps.anl.gov/epics">EPICS Web pages</a> or read the <a href="http://www.aps.anl.gov/epics/base/R3-14/8-docs/CAref.html">Channel Access manual (3.14)</a>.
<p>This module also includes CAJ, A 100% pure Java implementation of the EPICS Channel Access library.</p>
/*
* Copyright (c) 2004 by Cosylab
*
* The full license specifying the redistribution, modification, usage and other
* rights and obligations is included with the distribution of this project in
* the file "LICENSE-CAJ". If the license is not included visit Cosylab web site,
* .
*
* THIS SOFTWARE IS PROVIDED AS-IS WITHOUT WARRANTY OF ANY KIND, NOT EVEN THE
* IMPLIED WARRANTY OF MERCHANTABILITY. THE AUTHOR OF THIS SOFTWARE, ASSUMES
* _NO_ RESPONSIBILITY FOR ANY CONSEQUENCE RESULTING FROM THE USE, MODIFICATION,
* OR REDISTRIBUTION OF THIS SOFTWARE.
*/
package com.cosylab.epics.caj.impl.handlers;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import com.cosylab.epics.caj.CAJConstants;
import com.cosylab.epics.caj.impl.CAConstants;
import com.cosylab.epics.caj.impl.ResponseHandler;
import com.cosylab.epics.caj.impl.Transport;
import com.cosylab.epics.caj.util.HexDump;
/**
* @author Matej Sekoranja
* @version $id$
*/
public abstract class AbstractCAResponseHandler implements ResponseHandler {
/**
* CA response description.
*/
protected String description;
/**
* Command field of the header.
*/
protected short command;
/**
* Payload size field of the header.
*/
protected int payloadSize;
/**
* Data type field of the header.
*/
protected short dataType;
/**
* Data count field of the header.
* NOTE: extended
*/
protected int dataCount;
/**
* Parameter 1 field of the header.
*/
protected int parameter1;
/**
* Parameter 2 field of the header.
*/
protected int parameter2;
/**
* Debug flag.
*/
protected boolean debug = false;
/**
* @param description
*/
public AbstractCAResponseHandler(String description) {
this.description = description;
// TODO tmp
debug = System.getProperties().containsKey(CAJConstants.CAJ_DEBUG);
}
/**
* NOTE: (Extended) header buffer size validation should have been already done.
* response
is array of maximum of 2 elments:
* #UDP: contains whole response
* #TCP: first element contains complete standard or extended response message header, second whole payload.
* No buffer size checking is done.
* @see com.cosylab.epics.caj.impl.ResponseHandler#handleResponse(java.net.InetSocketAddress, com.cosylab.epics.caj.impl.Transport, java.nio.ByteBuffer[])
*/
public void handleResponse(
InetSocketAddress responseFrom,
Transport transport,
ByteBuffer[] response)
{
parseHeader(response[0]);
// TODO remove debug output
if (debug)
{
// payload dump
if (payloadSize > 0 && response.length > 1 && response[1].hasArray())
{
HexDump.hexDump(description + " payload", response[1].array(),
response[1].position(),
response[1].limit() - response[1].position());
}
}
internalHandleResponse(responseFrom, transport, response);
}
/**
* Called after header is parsed by parseHeader()
method.
* @see com.cosylab.epics.caj.impl.ResponseHandler#handleResponse(java.net.InetSocketAddress, com.cosylab.epics.caj.impl.Transport, java.nio.ByteBuffer[])
*/
protected abstract void internalHandleResponse(
InetSocketAddress responseFrom,
Transport transport,
ByteBuffer[] response);
/**
* Parse CA response header.
* @param headerBuffer response header to be parsed.
*/
protected void parseHeader(ByteBuffer headerBuffer)
{
// TODO remove debug
int startPos = headerBuffer.position();
boolean isExtended = false;
//
// read fields
//
command = headerBuffer.getShort();
// signed short conversion -> signed int
payloadSize = headerBuffer.getShort() & 0xFFFF;
dataType = headerBuffer.getShort();
// signed short conversion -> signed int
dataCount = headerBuffer.getShort() & 0xFFFF;
parameter1 = headerBuffer.getInt();
parameter2 = headerBuffer.getInt();
// TODO remove debug
if (payloadSize == 0xFFFF)
isExtended = true;
// extended header
if (payloadSize == 0xFFFF)
{
/*
* Because Java can't represent negative int as a 32 bit positive integer, it has to be promoted to a long:
* (1) Assign it to a long.
* (2) Clear the upper 32 bit of the long by logical AND with 0x00000000FFFFFFFF.
* (3) The resulting long is a positive number.
*
* Anyway, maximum buffer size is limited w/ Integer.MAX_VALUE,
* so int type us used and values > Integer.MAX_VALUE are not supported.
*/
payloadSize = headerBuffer.getInt();
dataCount = headerBuffer.getInt();
}
// TODO remove debug output
if (debug)
{
if (headerBuffer.hasArray())
{
// payload is stored in response[1]
HexDump.hexDump(description, headerBuffer.array(),
startPos,
isExtended ? CAConstants.CA_EXTENDED_MESSAGE_HEADER_SIZE:
CAConstants.CA_MESSAGE_HEADER_SIZE);
}
else
{
int len = isExtended ? CAConstants.CA_EXTENDED_MESSAGE_HEADER_SIZE:
CAConstants.CA_MESSAGE_HEADER_SIZE;
ByteBuffer bb = ByteBuffer.allocate(len);
if (!isExtended)
{
bb.putShort((byte)command);
bb.putShort((short)payloadSize);
bb.putShort((short)dataType);
bb.putShort((short)dataCount);
bb.putInt((int)parameter1);
bb.putInt((int)parameter2);
}
else
{
bb.putShort((byte)command);
bb.putShort((short)0xFFFF);
bb.putShort((short)dataType);
bb.putShort((short)0x0000);
bb.putInt((int)parameter1);
bb.putInt((int)parameter2);
bb.putInt((int)payloadSize);
bb.putInt((int)dataCount);
}
HexDump.hexDump(description, bb.array(),
0,
len);
}
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy