All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cosylab.epics.caj.impl.requests.ReadNotifyRequest 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>

There is a newer version: 2.4.10
Show newest version
/*
 * 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.requests;

import gov.aps.jca.CAStatus;
import gov.aps.jca.dbr.DBR;
import gov.aps.jca.dbr.DBRType;
import gov.aps.jca.event.ContextExceptionEvent;
import gov.aps.jca.event.GetEvent;
import gov.aps.jca.event.GetListener;

import java.io.IOException;
import java.nio.ByteBuffer;

import com.cosylab.epics.caj.CAJChannel;
import com.cosylab.epics.caj.CAJContext;
import com.cosylab.epics.caj.impl.DBRDecoder;
import com.cosylab.epics.caj.impl.NotifyResponseRequest;
import com.cosylab.epics.caj.impl.Transport;

/**
 * CA read notify.
 * @author Matej Sekoranja
 * @version $id$
 */
public class ReadNotifyRequest extends AbstractCARequest implements NotifyResponseRequest {

	/**
	 * Context.
	 */
	protected CAJContext context;

	/**
	 * I/O ID given by the context when registered.
	 */
	protected int ioid;

	/**
	 * Channel server ID.
	 */
	protected int sid;

	/**
	 * Response callback listener.
	 */
	protected GetListener callback;

	/**
	 * DBR to be set (sync. request).
	 */
	protected DBR dbr;

	/**
	 * Sync. request flag.
	 */
	protected boolean sync;

	/**
	 * IO sequence number.
	 */
	protected int sequenceNumberIO;

	/**
	 * Channel.
	 */
	protected CAJChannel channel;

	/**
	 * Requested data type.
	 */
	protected int requestedDataType;
	
	/**
	 * Requested data count.
	 */
	protected int requestedDataCount;

	/**
	 * Requested data count.
	 */
	protected boolean prohibitIOCancel = false;

	/**
	 * @param channel 
	 * @param callback
	 * @param dbr
	 * @param transport
	 * @param sid
	 * @param dataType
	 * @param dataCount
	 */
	public ReadNotifyRequest(CAJChannel channel, GetListener callback, DBR dbr,
							 Transport transport, int sid, int dataType, int dataCount) {
		super(transport);

		this.channel = channel;
		this.callback = callback;
		this.dbr = dbr; 
		this.sid = sid;
		this.requestedDataType = dataType;
		
		if (dataCount == 0 && channel.getTransport().getMinorRevision() < 13)
			dataCount = channel.getElementCount();

		this.requestedDataCount = dataCount;
		
		sync = (dbr != null); 
		// TODO not clean
		context = (CAJContext)transport.getContext(); // or channel.getContext()
		ioid = context.registerResponseRequest(this);
		channel.registerResponseRequest(this);
		
	    requestMessage = insertCAHeader(transport, null,
	            						(short)15, 0, (short)dataType, dataCount,
	            						sid, ioid);
	}

	/**
	 * @see com.cosylab.epics.caj.impl.ResponseRequest#getIOID()
	 */
	public int getIOID() {
		return ioid;
	}

	/**
	 * @see com.cosylab.epics.caj.impl.NotifyResponseRequest#response(int, short, int, java.nio.ByteBuffer)
	 */
	public void response(
		int status,
		short dataType,
		int dataCount,
		ByteBuffer dataPayloadBuffer) {

		try
		{			
			// HexDump.hexDump(description, dataPayloadBuffer.array(), dataPayloadBuffer.limit());
	
			CAStatus caStatus = CAStatus.forStatusCode(status);
			if (caStatus == CAStatus.NORMAL)
				dbr = DBRDecoder.getDBR(dbr, dataType, dataCount, dataPayloadBuffer);
			else
				// do not decrement pending IO, if non-callback read is used
				prohibitIOCancel = true;
			
			// notify
			if (callback != null )
				context.getEventDispatcher().dispatch(
				        new GetEvent(channel, dbr, caStatus),
						callback
					);
		}
		finally
		{
			// allways cancel request
			cancel();
		}
	}

	/**
	 * If sync. request (i.e. w/o callback), additionally increment context pending requests.
	 * @see com.cosylab.epics.caj.impl.Request#submit()
	 */
	public void submit() throws IOException {
		super.submit();
		if (sync)
			sequenceNumberIO = context.incrementPendingRequests();
	}

	/**
	 * @see com.cosylab.epics.caj.impl.ResponseRequest#cancel()
	 */
	public void cancel() {
		// unregister response request
		boolean alreadyCanceled = (context.unregisterResponseRequest(this) == null);
		if (!alreadyCanceled && sync && !prohibitIOCancel)
			context.decrementPendingRequests(sequenceNumberIO);
		channel.unregisterResponseRequest(this);
	}

	/**
	 * @see com.cosylab.epics.caj.impl.ResponseRequest#timeout()
	 */
	public void timeout() {

		// do not decrement pending IO, if non-callback read is used
		prohibitIOCancel = true;

		cancel();
		// ... and notify
		if (callback != null)
			context.getEventDispatcher().dispatch(
			        new GetEvent(channel, null, CAStatus.TIMEOUT),
					callback
				);
	}

	/**
	 * @see com.cosylab.epics.caj.impl.ResponseRequest#exception(int, java.lang.String)
	 */
	public void exception(int errorCode, String errorMessage) {
		
		// do not decrement pending IO, if non-callback read is used
		prohibitIOCancel = true;

		cancel();

		// TODO no status is dispatched 
		if (errorMessage == null)
		{
			CAStatus status = CAStatus.forStatusCode(errorCode);
			if (status != null)
				errorMessage = status.getMessage();
		}
		ContextExceptionEvent cee = new ContextExceptionEvent(context, channel,
				DBRType.forValue(requestedDataType), requestedDataCount, dbr, errorMessage);
		context.notifyException(cee);

		/*
		// ... and notify
		if (callback != null)
		{
			CAStatus status = CAStatus.forValue(errorCode);
			if (status == null)
			    status = CAStatus.GETFAIL;

			context.getEventDispatcher().dispatch(
			        new GetEvent(channel, null, status),
					callback
				);
		}
		*/
		
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy