Source code: com/synchrona/jred/Test.java
1 /*
2 **************************************************************************
3 ** $Header: /cvsroot/jred/jred/src/com/synchrona/jred/Test.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;
19
20 import com.synchrona.jred.irlap.ConnectionInformation;
21 import com.synchrona.jred.irlap.DiscoveryInformation;
22 import com.synchrona.jred.irlap.iIrLAPListener;
23 import com.synchrona.jred.irlap.IrLAPContext;
24 import com.synchrona.jred.irlap.IrLAPFramer;
25 import com.synchrona.util.Log;
26 import com.synchrona.util.Utilities;
27 import java.io.FileOutputStream;
28 import java.io.FileNotFoundException;
29 import java.io.PrintWriter;
30 import javax.comm.CommPortIdentifier;
31 import javax.comm.NoSuchPortException;
32 import javax.comm.PortInUseException;
33 import javax.comm.SerialPort;
34 import javax.comm.UnsupportedCommOperationException;
35
36 /**
37 * Will become IrLMP
38 */
39 public class Test implements Runnable, iIrLAPListener {
40 private static final String PORT_NAME_PROPERTY = "serialPort";
41 private static final byte OPCODE_CONNECT_REQUEST = (byte) 0x01;
42 private static final byte OPCODE_CONNECT_CONFIRM = (byte) 0x81;
43
44 private static final byte MASK_COMMAND_BIT = (byte) 0x80;
45
46 private iIrLMPService [] m_aServices;
47 private boolean m_bDoLogging;
48 private IrLAPContext m_irlap;
49 private Log m_log;
50 private int m_yConnection;
51
52 public static void main(String [] astrArgs) {
53 Test t = new Test();
54 t.run();
55 }
56
57 public void run() {
58 String portName = "(uninitialized)";
59
60 try {
61 portName = getPortName();
62
63 PrintWriter logfile = new PrintWriter(new FileOutputStream("irlap.txt"), true);
64 m_log = new Log(logfile);
65
66 IrLAPContext irlap = new IrLAPContext(m_log);
67 CommPortIdentifier portId = CommPortIdentifier.getPortIdentifier(portName);
68 SerialPort port = (SerialPort) portId.open("JRed", 2000);
69 IrLAPFramer framer = new IrLAPFramer(m_log, port);
70
71 m_irlap = irlap;
72 m_bDoLogging = true;
73
74 irlap.setFramer(framer);
75 irlap.addIrLAPListener(this);
76
77 m_aServices = new iIrLMPService[10];
78
79 // IAS is required, and serves at LSAP=0 per the IrLMP spec.
80 IrIAS ias = IrIAS.getInstance();
81 ias.setLog(m_log);
82 m_aServices[0] = IrIAS.getInstance();
83
84 // For now, add IrOBEX at offset 5. IrOBEX uses TinyTP
85 // for flow control. It should really be hidden inside
86 // IrOBEX, because IrLMP doesn't care.
87 m_aServices[5] = new TinyTP(m_log, this, new IrOBEX(m_log));
88
89 Thread t = new Thread(framer);
90 t.start();
91 } catch ( NoSuchPortException noSuchPort ) {
92 System.err.println("No port named " + portName + ": " + noSuchPort);
93 noSuchPort.printStackTrace(System.err);
94 } catch ( PortInUseException portInUse ) {
95 System.err.println(portName + " is in use: " + portInUse);
96 portInUse.printStackTrace(System.err);
97 } catch ( FileNotFoundException fileNotFound ) {
98 System.err.println("Couldn't open log file 'irlap.txt':" + fileNotFound);
99 fileNotFound.printStackTrace(System.err);
100 } catch ( Exception e ) {
101 System.err.println(e);
102 e.printStackTrace(System.err);
103 }
104 }
105
106 public void connectIndication(IrLAPContext context, ConnectionInformation connectionInfo) {
107 try {
108 m_yConnection = connectionInfo.getConnection();
109 int nRemote = connectionInfo.getRemoteAddress();
110 byte [] ayParameters = connectionInfo.getCommParameters();
111 context.connectResponse(nRemote, (byte) m_yConnection, ayParameters);
112 } catch ( Exception e ) {
113 System.err.println(e);
114 e.printStackTrace(System.err);
115 }
116 }
117
118 public void dataIndication(IrLAPContext context, ConnectionInformation connInfo, byte [] ayData) {
119 m_log.debug("IrLMP", "data length: " + ayData.length);
120
121 boolean bCommand = (0 != (0x80 & ayData[0]));
122 byte yDLSAP_SEL = (byte) (0x7F & ayData[0]);
123 byte ySLSAP_SEL = (byte) (0x7F & ayData[1]);
124 byte yOpcode = ayData[2];
125
126 m_log.debug("IrLMP", "bCommand: " + bCommand);
127 m_log.debug("IrLMP", "yDLSAP_SEL: " + Utilities.byteToString(yDLSAP_SEL));
128 m_log.debug("IrLMP", "ySLSAP_SEL: " + Utilities.byteToString(ySLSAP_SEL));
129 m_log.debug("IrLMP", "yOpcode: " + Utilities.byteToString(yOpcode));
130
131 if ( (yDLSAP_SEL >= 0)
132 && (yDLSAP_SEL < m_aServices.length)
133 && (null != m_aServices[yDLSAP_SEL]) ) {
134
135 IrLMPConnection irlmpConn = new IrLMPConnection(this, yDLSAP_SEL, ySLSAP_SEL, connInfo);
136
137 if ( bCommand ) {
138 boolean bConfirm = ((ayData[2] & 0x80) != 0);
139 byte yParams = ayData[3];
140 String strMessage = "(unknown)";
141
142 switch ( yOpcode ) {
143 case OPCODE_CONNECT_REQUEST:
144 strMessage = (bConfirm ? "Connect (confirm)" : "Connect");
145 // frame length - dest - source - opcode - reserved byte
146 byte [] ayUserData = null;
147 if ( ayData.length > 4 ) {
148 ayUserData = new byte[ayData.length - 4];
149 for ( int i = 0; i < ayUserData.length; i++ ) {
150 ayUserData[i] = ayData[i + 4];
151 }
152 }
153 m_aServices[yDLSAP_SEL].connectRequest(this, yDLSAP_SEL, ySLSAP_SEL, ayUserData);
154 break;
155 case 2: strMessage = "Disconnect"; break;
156 case 3: strMessage = (bConfirm ? "Access Mode (confirm)" : "Access Mode"); break;
157 }
158 m_log.debug("IrLMP", strMessage);
159 } else {
160 try {
161 m_aServices[yDLSAP_SEL].serviceRequest(this, irlmpConn, ayData, 0, ayData.length);
162 } catch ( Exception e ) {
163 m_log.debug("IrLMP", "Caught this " + e);
164 //e.printStackTrace(m_log);
165 }
166 }
167 }
168 }
169
170 public void discoveryIndication(IrLAPContext context, DiscoveryInformation discoveryInfo) {
171 }
172
173 public void sendData(byte yDestination, byte ySource, byte [] ayData, int nOffset, int nLength) {
174 try {
175 byte [] ayFrame = new byte[2 + nLength];
176 ayFrame[0] = yDestination;
177 ayFrame[1] = ySource;
178 for ( int i = 0; i < nLength; i++ ) {
179 ayFrame[i + 2] = ayData[nOffset + i];
180 }
181
182 m_irlap.sendData((byte) m_yConnection, ayFrame, 0, ayFrame.length);
183 } catch ( Exception e ) {
184 m_log.debug("IrLMP ", e.toString());
185 //e.printStackTrace(m_log);
186 }
187 }
188
189 public void connectConfirm(byte yDestination, byte ySource, byte [] ayUserData) {
190 byte [] ayConfirmMsg = new byte[255];
191 int nConfirmLength = 0;
192 ayConfirmMsg[nConfirmLength++] = (byte) (0x80 | yDestination);
193 ayConfirmMsg[nConfirmLength++] = ySource;
194 ayConfirmMsg[nConfirmLength++] = OPCODE_CONNECT_CONFIRM;
195 ayConfirmMsg[nConfirmLength++] = (byte) 0x00; // optional 0x00
196 if ( null != ayUserData ) {
197 for ( int i = 0; i < ayUserData.length; i++ ) {
198 ayConfirmMsg[nConfirmLength++] = ayUserData[i];
199 }
200 }
201
202 try {
203 m_irlap.sendData((byte) m_yConnection, ayConfirmMsg, 0, nConfirmLength);
204 } catch ( Exception e ) {
205 m_log.debug("IrLMP", "(connectConfirm) " + e);
206 //e.printStackTrace(m_log);
207 }
208 }
209
210 public void serviceRequestsConnection() {
211 m_log.debug("IrLMP", "(serviceRequestsConnection)");
212 }
213
214 private String getPortName() throws Exception {
215 String portName = System.getProperty(PORT_NAME_PROPERTY);
216 if ( null == portName ) {
217 m_log.error("IrLMP", "(getPortName) " + PORT_NAME_PROPERTY + " is undefined.");
218 throw new Exception(PORT_NAME_PROPERTY + " is undefined.");
219 }
220 return portName;
221 }
222 }