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