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.*;
024
025import java.io.IOException;
026import java.net.ServerSocket;
027
028/**
029 * Talks with TCP based NACs
030 * Sends [LEN][TPDU][ISOMSG]
031 * (len=2 bytes network byte order)
032 *
033 * @author Alejandro P. Revilla
034 * @version $Revision$ $Date$
035 * @see ISOMsg
036 * @see ISOException
037 * @see ISOChannel
038 */
039public class NACChannel extends BaseChannel {
040    /**
041     * Public constructor 
042     */
043    boolean tpduSwap = true;
044    int lenlen = 0;
045
046    /** Default constructor. */
047    public NACChannel () {
048        super();
049    }
050    /**
051     * Construct client ISOChannel
052     * @param host  server TCP Address
053     * @param port  server port number
054     * @param p     an ISOPackager
055     * @param TPDU  an optional raw header (i.e. TPDU)
056     * @see ISOPackager
057     */
058    public NACChannel (String host, int port, ISOPackager p, byte[] TPDU) {
059        super(host, port, p);
060        this.header = TPDU;
061    }
062    /**
063     * Construct server ISOChannel
064     * @param p     an ISOPackager
065     * @param TPDU  an optional raw header (i.e. TPDU)
066     * @exception IOException on error
067     * @see ISOPackager
068     */
069    public NACChannel (ISOPackager p, byte[] TPDU) throws IOException {
070        super(p);
071        this.header = TPDU;
072    }
073    /**
074     * constructs server ISOChannel associated with a Server Socket
075     * @param p     an ISOPackager
076     * @param TPDU  an optional raw header (i.e. TPDU)
077     * @param serverSocket where to accept a connection
078     * @exception IOException on error
079     * @see ISOPackager
080     */
081    public NACChannel (ISOPackager p, byte[] TPDU, ServerSocket serverSocket) 
082        throws IOException
083    {
084        super(p, serverSocket);
085        this.header = TPDU;
086    }
087    protected void sendMessageLength(int len) throws IOException {
088        len += lenlen;
089        serverOut.write (len >> 8);
090        serverOut.write (len);
091    }
092    protected int getMessageLength() throws IOException, ISOException {
093        byte[] b = new byte[2];
094        serverIn.readFully(b,0,2);
095        return (((int)b[0] &0xFF) << 8 | (int)b[1] &0xFF) - lenlen;
096    }
097    protected void sendMessageHeader(ISOMsg m, int len) throws IOException { 
098        byte[] h = m.getHeader();
099        if (h != null) {
100            if (tpduSwap && h.length == 5) {
101                // swap src/dest address
102                byte[] tmp = new byte[2];
103                System.arraycopy (h,   1, tmp, 0, 2);
104                System.arraycopy (h,   3,   h, 1, 2);
105                System.arraycopy (tmp, 0,   h, 3, 2);
106            }
107        }
108        else 
109            h = header;
110        if (h != null) 
111            serverOut.write(h);
112    }
113    /**
114     * New QSP compatible signature (see QSP's ConfigChannel)
115     * @param header String as seen by QSP
116     */
117    public void setHeader (String header) {
118        super.setHeader (ISOUtil.str2bcd(header, false));
119    }
120    public void setConfiguration (Configuration cfg) 
121        throws ConfigurationException
122    {
123        super.setConfiguration (cfg);
124        tpduSwap = cfg.getBoolean ("tpdu-swap", true);
125        lenlen = cfg.getBoolean ("include-header-length", false) ? 2 : 0;
126    }
127}
128