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.core.Configuration;
022import org.jpos.core.ConfigurationException;
023import org.jpos.iso.*;
024import org.jpos.util.LogEvent;
025import org.jpos.util.Logger;
026
027import java.io.BufferedReader;
028import java.io.EOFException;
029import java.io.IOException;
030import java.io.InterruptedIOException;
031import java.net.ServerSocket;
032
033/**
034 * Implements an ISOChannel suitable to be used to connect to an X.25 PAD.
035 *
036 * @author  <a href="mailto:apr@cs.com.uy">Alejandro P. Revilla</a>
037 * @version $Id$
038 *
039 * @see ISOMsg
040 * @see ISOException
041 * @see ISOChannel
042 */
043public class PADChannel extends BaseChannel {
044    BufferedReader reader = null;
045    long delay = 0L;
046    /**
047     * No-args constructor
048     */
049    public PADChannel () {
050        super();
051    }
052    /**
053     * Constructs client ISOChannel
054     * @param host  server TCP Address
055     * @param port  server port number
056     * @param p     an ISOPackager
057     * @see ISOPackager
058     */
059    public PADChannel (String host, int port, ISOPackager p) {
060        super(host, port, p);
061    }
062    /**
063     * Construct server ISOChannel
064     * @param p     an ISOPackager
065     * @see ISOPackager
066     * @exception IOException
067     */
068    public PADChannel (ISOPackager p) throws IOException {
069        super(p);
070    }
071    /**
072     * constructs a server ISOChannel associated with a Server Socket
073     * @param p     an ISOPackager
074     * @param serverSocket where to accept a connection
075     * @exception IOException
076     * @see ISOPackager
077     */
078    public PADChannel (ISOPackager p, ServerSocket serverSocket)
079        throws IOException
080    {
081        super (p, serverSocket);
082        if (delay > 0L)
083            ISOUtil.sleep(delay);
084    }
085
086    @Override
087    public ISOMsg receive() throws IOException, ISOException {
088        byte[] header = null;
089        ISOMsg m = createISOMsg();
090        m.setPackager (packager);
091        m.setSource (this);
092        int hLen = getHeaderLength();
093        LogEvent evt = new LogEvent (this, "receive");
094        try {
095            try {
096                serverInLock.lock();
097                if (hLen > 0) {
098                    header = new byte [hLen];
099                    serverIn.readFully(header);
100                }
101                m.unpack (serverIn);
102            } finally {
103                serverInLock.unlock();
104            }
105            m.setHeader (header);
106            m.setDirection(ISOMsg.INCOMING);
107            evt.addMessage (m);
108            m = applyIncomingFilters (m, evt);
109            m.setDirection(ISOMsg.INCOMING);
110            cnt[RX]++;
111            setChanged();
112            notifyObservers(m);
113        } catch (ISOException e) {
114            evt.addMessage (e);
115            throw e;
116        } catch (EOFException e) {
117            evt.addMessage ("<peer-disconnect/>");
118            throw e;
119        } catch (InterruptedIOException e) {
120            evt.addMessage ("<io-timeout/>");
121            throw e;
122        } catch (IOException e) {
123            if (usable)
124                evt.addMessage (e);
125            throw e;
126        } catch (Exception e) {
127            evt.addMessage (e);
128            throw new ISOException ("unexpected exception", e);
129        } finally {
130            Logger.log (evt);
131        }
132        return m;
133    }
134    @Override
135    public void send (ISOMsg m) throws IOException, ISOException {
136        super.send(m);
137    }
138    @Override
139    public void setConfiguration (Configuration cfg)
140            throws ConfigurationException {
141        super.setConfiguration(cfg);
142        delay = cfg.getLong("delay", 0L);
143    }
144
145    /**
146     * @param header Hex representation of header
147     */
148    public void setHeader (String header) {
149        super.setHeader (
150            ISOUtil.hex2byte (header.getBytes(), 0, header.length() / 2)
151        );
152    }
153}