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.*;
022import org.jpos.util.LogEvent;
023import org.jpos.util.Logger;
024import org.jpos.core.Configuration;
025import org.jpos.core.ConfigurationException;
026
027import java.io.IOException;
028import java.net.ServerSocket;
029
030/**
031 * Talks with TCP based NCCs
032 * Sends [LEN][TPDU][ISOMSG]
033 * (len=2 bytes BCD)
034 *
035 * @author Alejandro P. Revilla
036 * @version $Revision$ $Date$
037 * @see ISOMsg
038 * @see ISOException
039 * @see ISOChannel
040 */
041public class NCCChannel extends BaseChannel {
042    /**
043     * Public constructor 
044     */
045    boolean tpduSwap = true;
046    /** Default constructor. */
047    public NCCChannel () {
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 NCCChannel (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 I/O error
067     * @see ISOPackager
068     */
069    public NCCChannel (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 I/O error
079     * @see ISOPackager
080     */
081    public NCCChannel (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        try {
089            serverOut.write (
090                ISOUtil.str2bcd (
091                    ISOUtil.zeropad (Integer.toString (len % 10000), 4), true
092                )
093            );
094        } 
095        catch (ISOException e) {
096            Logger.log (new LogEvent (this, "send-message-length", e));
097        }
098    }
099    protected int getMessageLength() throws IOException, ISOException {
100        byte[] b = new byte[2];
101        serverIn.readFully(b,0,2);
102        return Integer.parseInt (
103            ISOUtil.bcd2str (b, 0, 4, true)
104        );
105    }
106    protected void sendMessageHeader(ISOMsg m, int len) throws IOException { 
107        byte[] h = m.getHeader();
108        if (h != null) {
109            if (tpduSwap && h.length == 5) {
110                // swap src/dest address
111                byte[] tmp = new byte[2];
112                System.arraycopy (h,   1, tmp, 0, 2);
113                System.arraycopy (h,   3,   h, 1, 2);
114                System.arraycopy (tmp, 0,   h, 3, 2);
115            }
116        }
117        else
118            h = header ;
119        if (h != null) 
120            serverOut.write(h);
121    }
122    /**
123     * New QSP compatible signature (see QSP's ConfigChannel)
124     * @param header String as seen by QSP
125     */
126    public void setHeader (String header) {
127        super.setHeader (ISOUtil.str2bcd(header, false));
128    }
129    public void setConfiguration (Configuration cfg) 
130        throws ConfigurationException
131    {
132        super.setConfiguration (cfg);
133        tpduSwap = cfg.getBoolean ("tpdu-swap", true);
134    }
135}
136