📄 asyncframewrapper.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 + -