
com.cosylab.epics.caj.impl.handlers.AbstractCAResponseHandler Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of jca Show documentation
Show all versions of jca Show documentation
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