Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: com/synchrona/jred/irlap/AsyncFrameWrapper.java


1   /*
2   **************************************************************************
3   ** $Header: /cvsroot/jred/jred/src/com/synchrona/jred/irlap/AsyncFrameWrapper.java,v 1.1.1.1 2000/07/05 04:41:52 mpatters Exp $
4   **
5   ** Copyright (C) 2000 Synchrona, Inc. All rights reserved.
6   **
7   ** This file is part of JRed, a 100% Java implementation of the IrDA
8   ** infrared communications protocols.
9   **
10  ** This file may be distributed under the terms of the Synchrona Public
11  ** License as defined by Synchrona, Inc. and appearing in the file
12  ** LICENSE included in the packaging of this file. The Synchrona Public
13  ** License is based on the Q Public License as defined by Troll Tech AS
14  ** of Norway; it differs only in its use of the courts of Florida, USA
15  ** rather than those of Oslo, Norway.
16  **************************************************************************
17  */
18  package com.synchrona.jred.irlap;
19  
20  import com.synchrona.util.Log;
21  import java.io.DataInputStream;
22  import java.io.DataOutputStream;
23  import java.io.IOException;
24  import java.io.PrintWriter;
25  
26  /**
27   * Implements asynchronous frame wrapping, which IrLAP uses at
28   * 9600bps - 115200bps
29   */
30  class AsyncFrameWrapper implements iFrameWrapper {
31    /**
32     * Users of AsyncFrameWrapper can safely size frame buffers
33     * at MAX_FRAME_LENGTH (255 bytes).
34     */
35    public static final int MAX_FRAME_LENGTH  = 255;
36  
37    private static final byte BOF               = (byte) 0xC0;
38    private static final byte CE                = (byte) 0x7D;
39    private static final int  DEFAULT_BOF_COUNT = 11;
40    private static final byte EOF               = (byte) 0xC1;
41    private static final byte XBOF              = (byte) 0xFF;
42  
43    private byte []          m_ayInputFrame  = new byte[MAX_FRAME_LENGTH * 2];;
44    private byte []          m_ayOutputFrame = new byte[MAX_FRAME_LENGTH * 2];;
45    private CheckCRC         m_crc           = new CheckCRC();
46    private DataInputStream  m_in;
47    private Log              m_log;
48    private int              m_nBOFCount     = DEFAULT_BOF_COUNT;
49    private DataOutputStream m_out;
50  
51    public AsyncFrameWrapper(Log log, DataInputStream in, DataOutputStream out) {
52      m_in  = in;
53      m_log = log;
54      m_out = out;
55    }
56  
57    //----------------------------------------------------------------
58    // Implementation of iFrameWrapper
59    //----------------------------------------------------------------
60  
61    /**
62     * @param  ayDestination destination frame
63     * @param  nOffset       offset into destination frame at which writing should begin
64     * @param  nLength       maximum number of bytes that can be written into destination frame
65     *
66     * @return Number of bytes written into destination frame (0 if no data was available)
67     */
68    public int receive(byte [] ayDestination, int nOffset,  int nLength) throws Exception {
69      verifyFrameArgs(ayDestination, nOffset, nLength);
70      if ( null == m_in ) {
71        throw new Exception("DataInputStream is null");
72      } 
73      int nBytesRead = 0;
74      try {
75        nBytesRead = reallyReceive(ayDestination, nOffset, nLength);
76      } catch ( Exception e ) {
77        nBytesRead = 0;
78      }
79      return nBytesRead;
80    }
81  
82    public void send(byte [] aySource, int nOffset, int nLength) throws Exception {
83      verifyFrameArgs(aySource, nOffset, nLength);
84      if ( null == m_out ) {
85        throw new Exception("DataOutputStream is null");
86      } 
87      reallySend(aySource, nOffset, nLength);
88    }
89  
90    public void setLog(PrintWriter log) {
91    }
92  
93    public void setLogging(boolean bDoLogging) {
94    }
95  
96    public void setNumberOfBOFs(int nBOFCount) {
97      m_nBOFCount = nBOFCount;
98    }
99  
100   //----------------------------------------------------------------
101   // End of iFrameWrapper implementation
102   //----------------------------------------------------------------
103 
104   /**
105    * @return Number of bytes written into destination buffer
106    */
107   private int reallyReceive(byte [] ayDestination, int nOffset, int nLength) throws Exception {
108     // Read the inter-frame filler (0xFF). If your port speed is higher
109     // than JavaComm supports, JavaComm claims to read nothing but 0xFF,
110     // which is why you need to be able to break out of this loop.
111     byte yBOF       = XBOF;
112     byte nXBOFCount = -1;
113     while ( (BOF != yBOF) && (nXBOFCount < (m_nBOFCount * 2)) ) {
114       yBOF = m_in.readByte();
115       nXBOFCount++;
116     }
117     if ( nXBOFCount >= m_nBOFCount ) {
118       throw new Exception("Expected to get " + m_nBOFCount + " XBOF characters, got " + nXBOFCount + " instead.");
119     }
120     if ( BOF != yBOF ) {
121       throw new Exception("Expected IrLAP BOF, got " + yBOF + " instead.");
122     }
123 
124     int     nPosition = 0;
125     boolean bContinue = true;
126     while ( bContinue ) {
127       byte b = m_in.readByte();
128       if ( EOF == b ) {
129         // got an EOF, drop out before we store this byte
130         bContinue = false;
131       } else if ( nPosition >= m_ayInputFrame.length ) {
132         throw new Exception("Data exceeds internal buffer length.");
133       } else {
134         if ( CE == b ) {
135           b = m_in.readByte();
136           b ^= (byte) 0x20;
137         }
138         m_ayInputFrame[nPosition++] = b;
139       }
140     }
141 
142     //---------------------------------------------------------------
143     // TBD: Verify Frame Check Sequence. So far my version of the
144     //      algorithm is more incorrect than the stuff coming over
145     //      the wire, so I'm not too worried about what other devices
146     //      send us.
147     //---------------------------------------------------------------
148 
149     // Decrement position so we don't copy the Frame Check Sequence
150     nPosition -= 2;
151 
152     for ( int i = 0; (i < nPosition) && ((nOffset + i) < nLength); i++ ) {
153       ayDestination[nOffset + i] = m_ayInputFrame[i];
154     }
155 
156     m_log.debugBytes("AsyncFrameWrapper", "recv'd this: ", ayDestination, nOffset, nOffset + nPosition);
157     return nPosition;
158   }
159 
160   private void reallySend(byte [] ayFrame, int nOffset, int nLength) throws Exception {
161     m_log.debugBytes("AsyncFrameWrapper", "got this: ", ayFrame, nOffset, nLength);
162     int i         = 0;
163     int nPosition = 0;
164 
165     for ( i = 0; i < (m_nBOFCount -1); i++ ) {
166       m_ayOutputFrame[nPosition++] = XBOF;
167     }
168     m_ayOutputFrame[nPosition++] = BOF;
169 
170     for ( i = 0; i < nLength; i++ ) {
171       byte yCurrent = ayFrame[nOffset + i];
172 
173       switch ( yCurrent ) {
174         case BOF:
175           // fall through
176         case EOF:
177           // fall through
178         case CE:
179           yCurrent ^= (byte) 0x20;
180           m_ayOutputFrame[nPosition++] = CE;
181           // fall through
182         default:
183           m_ayOutputFrame[nPosition++] = yCurrent;
184         break;
185       }
186     }
187 
188     // XBOF and BOF are not part of CRC calculation
189     int fcs = m_crc.getCRC(ayFrame, nOffset, nLength);
190 
191     m_ayOutputFrame[nPosition++] = (byte)  (fcs & 0x000000FF);
192     m_ayOutputFrame[nPosition++] = (byte) ((fcs & 0x0000FF00) >> 8);
193 
194     m_ayOutputFrame[nPosition++] = EOF;
195 
196     m_log.debugBytes("AsyncFrameWrapper", "sending this: ", m_ayOutputFrame, 0, nPosition);
197 
198     m_out.write(m_ayOutputFrame, 0, nPosition);
199   }
200 
201   private void verifyFrameArgs(byte [] ayFrame, int nOffset, int nLength) throws Exception {
202     if ( null == ayFrame ) {
203       throw new Exception("The frame is null.");
204     } else if ( nOffset < 0 ) {
205       throw new Exception("The frame offset is negative.");
206     } else if ( nOffset >= nLength ) {
207       throw new Exception("The frame offset is greater than or equal to the frame length.");
208     } else if ( nLength > MAX_FRAME_LENGTH ) {
209       throw new Exception("The frame's length is greater than or equal to the maximum frame length (" + MAX_FRAME_LENGTH + ").");
210     } else if ( ayFrame.length < (nOffset + nLength) ) {
211       throw new Exception("The frame's length and offset are inconsistent with array bounds.");
212     }
213   }
214 }