001/* 002 * jPOS Project [http://jpos.org] 003 * Copyright (C) 2000-2026 jPOS Software SRL 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Affero General Public License as 007 * published by the Free Software Foundation, either version 3 of the 008 * License, or (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Affero General Public License for more details. 014 * 015 * You should have received a copy of the GNU Affero General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018 019package org.jpos.iso.channel; 020 021import org.jpos.iso.*; 022 023import java.io.BufferedReader; 024import java.io.EOFException; 025import java.io.IOException; 026import java.io.InputStreamReader; 027import java.net.ServerSocket; 028import java.net.Socket; 029import java.util.Vector; 030 031/** 032 * Implements an ISOChannel suitable to be used to connect to an X.25 PAD. 033 * It waits a limited amount of time to decide when a packet is ready 034 * to be unpacked. 035 * 036 * This channel is based on PADChannel version 1.4. The new version 037 * seems to have some problems dealing with ETXs (we're working on it). 038 * Use this version _only_ if you have problems with current PADChannel 039 * as it will be deprecated some time in the future. 040 * 041 * @author <a href="mailto:apr@cs.com.uy">Alejandro P. Revilla</a> 042 * @version $Id$ 043 * 044 * @see ISOMsg 045 * @see ISOException 046 * @see ISOChannel 047 */ 048@SuppressWarnings("unchecked") 049public class X25Channel extends BaseChannel { 050 /** Buffered reader used to consume the channel's input stream. */ 051 BufferedReader reader = null; 052 /** Optional header bytes prepended to outgoing messages. */ 053 protected byte[] header; 054 /** 055 * No-args constructor 056 */ 057 public X25Channel () { 058 super(); 059 } 060 /** 061 * Constructs client ISOChannel 062 * @param host server TCP Address 063 * @param port server port number 064 * @param p an ISOPackager 065 * @see ISOPackager 066 */ 067 public X25Channel (String host, int port, ISOPackager p) { 068 super(host, port, p); 069 } 070 /** 071 * Construct server ISOChannel 072 * @param p an ISOPackager 073 * @see ISOPackager 074 * @exception IOException on I/O error 075 */ 076 public X25Channel (ISOPackager p) throws IOException { 077 super(p); 078 } 079 /** 080 * constructs a server ISOChannel associated with a Server Socket 081 * @param p an ISOPackager 082 * @param serverSocket where to accept a connection 083 * @exception IOException on I/O error 084 * @see ISOPackager 085 */ 086 public X25Channel (ISOPackager p, ServerSocket serverSocket) 087 throws IOException 088 { 089 super(p, serverSocket); 090 } 091 /** 092 * @return a byte array with the received message 093 * @exception IOException on I/O error 094 */ 095 protected byte[] streamReceive() throws IOException { 096 int c, k=0, len = 1; 097 Vector v = new Vector(); 098 099 c = serverIn.read(); 100 if (c == -1) 101 throw new EOFException ("connection closed"); 102 byte[] b = new byte[1]; 103 b[0] = (byte) c; 104 v.addElement (b); 105 106 // Wait for packets until timeout 107 while ((c = serverIn.available()) > 0) { 108 b = new byte[c]; 109 if (serverIn.read (b) != c) 110 throw new EOFException ("connection closed"); 111 v.addElement (b); 112 len += c; 113 try { 114 Thread.sleep (50); 115 } catch (InterruptedException e) { } 116 } 117 118 byte[] d = new byte[len]; 119 for (int i=0; i<v.size(); i++) { 120 b = (byte[]) v.elementAt(i); 121 System.arraycopy (b, 0, d, k, b.length); 122 k += b.length; 123 } 124 return d; 125 } 126 protected void connect (Socket socket) throws IOException { 127 super.connect (socket); 128 reader = new BufferedReader (new InputStreamReader (serverIn)); 129 } 130 public void disconnect () throws IOException { 131 super.disconnect (); 132 reader = null; 133 } 134 protected int getHeaderLength() { 135 return header != null ? header.length : 0; 136 } 137 public void setHeader (byte[] header) { 138 this.header = header; 139 } 140 /** 141 * @param header Hex representation of header 142 */ 143 public void setHeader (String header) { 144 setHeader ( 145 ISOUtil.hex2byte (header.getBytes(), 0, header.getBytes().length / 2) 146 ); 147 } 148 public byte[] getHeader () { 149 return header; 150 } 151 protected void sendMessageHeader(ISOMsg m, int len) throws IOException { 152 if (m.getHeader() != null) 153 serverOut.write(m.getHeader()); 154 else if (header != null) 155 serverOut.write(header); 156 } 157}