⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asyncframewrapper.java

📁 JRed is a 100% Java implementation of the IrDA infrared communications protocols. JRed lets you beam
💻 JAVA
字号:
/*
**************************************************************************
** $Header: /cvsroot/jred/jred/src/com/synchrona/jred/irlap/AsyncFrameWrapper.java,v 1.1.1.1 2000/07/05 04:41:52 mpatters Exp $
**
** Copyright (C) 2000 Synchrona, Inc. All rights reserved.
**
** This file is part of JRed, a 100% Java implementation of the IrDA
** infrared communications protocols.
**
** This file may be distributed under the terms of the Synchrona Public
** License as defined by Synchrona, Inc. and appearing in the file
** LICENSE included in the packaging of this file. The Synchrona Public
** License is based on the Q Public License as defined by Troll Tech AS
** of Norway; it differs only in its use of the courts of Florida, USA
** rather than those of Oslo, Norway.
**************************************************************************
*/
package com.synchrona.jred.irlap;

import com.synchrona.util.Log;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * Implements asynchronous frame wrapping, which IrLAP uses at
 * 9600bps - 115200bps
 */
class AsyncFrameWrapper implements iFrameWrapper {
	/**
	 * Users of AsyncFrameWrapper can safely size frame buffers
	 * at MAX_FRAME_LENGTH (255 bytes).
	 */
	public static final int MAX_FRAME_LENGTH  = 255;

	private static final byte BOF               = (byte) 0xC0;
	private static final byte CE                = (byte) 0x7D;
	private static final int  DEFAULT_BOF_COUNT = 11;
	private static final byte EOF               = (byte) 0xC1;
	private static final byte XBOF              = (byte) 0xFF;

	private byte []          m_ayInputFrame  = new byte[MAX_FRAME_LENGTH * 2];;
	private byte []          m_ayOutputFrame = new byte[MAX_FRAME_LENGTH * 2];;
	private CheckCRC         m_crc           = new CheckCRC();
	private DataInputStream  m_in;
	private Log              m_log;
	private int              m_nBOFCount     = DEFAULT_BOF_COUNT;
	private DataOutputStream m_out;

	public AsyncFrameWrapper(Log log, DataInputStream in, DataOutputStream out) {
		m_in  = in;
		m_log = log;
		m_out = out;
	}

	//----------------------------------------------------------------
	// Implementation of iFrameWrapper
	//----------------------------------------------------------------

	/**
	 * @param  ayDestination destination frame
	 * @param  nOffset       offset into destination frame at which writing should begin
	 * @param  nLength       maximum number of bytes that can be written into destination frame
	 *
	 * @return Number of bytes written into destination frame (0 if no data was available)
	 */
	public int receive(byte [] ayDestination, int nOffset,  int nLength) throws Exception {
		verifyFrameArgs(ayDestination, nOffset, nLength);
		if ( null == m_in ) {
			throw new Exception("DataInputStream is null");
		} 
		int nBytesRead = 0;
		try {
			nBytesRead = reallyReceive(ayDestination, nOffset, nLength);
		} catch ( Exception e ) {
			nBytesRead = 0;
		}
		return nBytesRead;
	}

	public void send(byte [] aySource, int nOffset, int nLength) throws Exception {
		verifyFrameArgs(aySource, nOffset, nLength);
		if ( null == m_out ) {
			throw new Exception("DataOutputStream is null");
		} 
		reallySend(aySource, nOffset, nLength);
	}

	public void setLog(PrintWriter log) {
	}

	public void setLogging(boolean bDoLogging) {
	}

	public void setNumberOfBOFs(int nBOFCount) {
		m_nBOFCount = nBOFCount;
	}

	//----------------------------------------------------------------
	// End of iFrameWrapper implementation
	//----------------------------------------------------------------

	/**
	 * @return Number of bytes written into destination buffer
	 */
	private int reallyReceive(byte [] ayDestination, int nOffset, int nLength) throws Exception {
		// Read the inter-frame filler (0xFF). If your port speed is higher
		// than JavaComm supports, JavaComm claims to read nothing but 0xFF,
		// which is why you need to be able to break out of this loop.
		byte yBOF       = XBOF;
		byte nXBOFCount = -1;
		while ( (BOF != yBOF) && (nXBOFCount < (m_nBOFCount * 2)) ) {
			yBOF = m_in.readByte();
			nXBOFCount++;
		}
		if ( nXBOFCount >= m_nBOFCount ) {
			throw new Exception("Expected to get " + m_nBOFCount + " XBOF characters, got " + nXBOFCount + " instead.");
		}
		if ( BOF != yBOF ) {
			throw new Exception("Expected IrLAP BOF, got " + yBOF + " instead.");
		}

		int     nPosition = 0;
		boolean bContinue = true;
		while ( bContinue ) {
			byte b = m_in.readByte();
			if ( EOF == b ) {
				// got an EOF, drop out before we store this byte
				bContinue = false;
			} else if ( nPosition >= m_ayInputFrame.length ) {
				throw new Exception("Data exceeds internal buffer length.");
			} else {
				if ( CE == b ) {
					b = m_in.readByte();
					b ^= (byte) 0x20;
				}
				m_ayInputFrame[nPosition++] = b;
			}
		}

		//---------------------------------------------------------------
		// TBD: Verify Frame Check Sequence. So far my version of the
		//      algorithm is more incorrect than the stuff coming over
		//      the wire, so I'm not too worried about what other devices
		//      send us.
		//---------------------------------------------------------------

		// Decrement position so we don't copy the Frame Check Sequence
		nPosition -= 2;

		for ( int i = 0; (i < nPosition) && ((nOffset + i) < nLength); i++ ) {
			ayDestination[nOffset + i] = m_ayInputFrame[i];
		}

		m_log.debugBytes("AsyncFrameWrapper", "recv'd this: ", ayDestination, nOffset, nOffset + nPosition);
		return nPosition;
	}

	private void reallySend(byte [] ayFrame, int nOffset, int nLength) throws Exception {
		m_log.debugBytes("AsyncFrameWrapper", "got this: ", ayFrame, nOffset, nLength);
		int i         = 0;
		int nPosition = 0;

		for ( i = 0; i < (m_nBOFCount -1); i++ ) {
			m_ayOutputFrame[nPosition++] = XBOF;
		}
		m_ayOutputFrame[nPosition++] = BOF;

		for ( i = 0; i < nLength; i++ ) {
			byte yCurrent = ayFrame[nOffset + i];

			switch ( yCurrent ) {
				case BOF:
					// fall through
				case EOF:
					// fall through
				case CE:
					yCurrent ^= (byte) 0x20;
					m_ayOutputFrame[nPosition++] = CE;
					// fall through
				default:
					m_ayOutputFrame[nPosition++] = yCurrent;
				break;
			}
		}

		// XBOF and BOF are not part of CRC calculation
		int fcs = m_crc.getCRC(ayFrame, nOffset, nLength);

		m_ayOutputFrame[nPosition++] = (byte)  (fcs & 0x000000FF);
		m_ayOutputFrame[nPosition++] = (byte) ((fcs & 0x0000FF00) >> 8);

		m_ayOutputFrame[nPosition++] = EOF;

		m_log.debugBytes("AsyncFrameWrapper", "sending this: ", m_ayOutputFrame, 0, nPosition);

		m_out.write(m_ayOutputFrame, 0, nPosition);
	}

	private void verifyFrameArgs(byte [] ayFrame, int nOffset, int nLength) throws Exception {
		if ( null == ayFrame ) {
			throw new Exception("The frame is null.");
		} else if ( nOffset < 0 ) {
			throw new Exception("The frame offset is negative.");
		} else if ( nOffset >= nLength ) {
			throw new Exception("The frame offset is greater than or equal to the frame length.");
		} else if ( nLength > MAX_FRAME_LENGTH ) {
			throw new Exception("The frame's length is greater than or equal to the maximum frame length (" + MAX_FRAME_LENGTH + ").");
		} else if ( ayFrame.length < (nOffset + nLength) ) {
			throw new Exception("The frame's length and offset are inconsistent with array bounds.");
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -