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 * ISOChannel implementation - CS standard Channel<br>
030 * We at <a href="http://www.cs.com.uy">CS</a>, have used
031 * the so called ISOChannels for a long time. This class
032 * talks with our legacy C++ based systems.<br>
033 *
034 * @author apr@cs.com.uy
035 * @version $Id$
036 * @see ISOMsg
037 * @see ISOException
038 * @see ISOChannel
039 */
040public class CSChannel extends BaseChannel {
041    private boolean replyKeepAlive = true;
042    /**
043     * Public constructor (used by Class.forName("...").newInstance())
044     */
045    public CSChannel () {
046        super();
047    }
048    /**
049     * Construct client ISOChannel
050     * @param host  server TCP Address
051     * @param port  server port number
052     * @param p     an ISOPackager
053     * @see ISOPackager
054     */
055    public CSChannel (String host, int port, ISOPackager p) {
056        super(host, port, p);
057    }
058    /**
059     * Construct server ISOChannel
060     * @param p     an ISOPackager
061     * @exception IOException
062     * @see ISOPackager
063     */
064    public CSChannel (ISOPackager p) throws IOException {
065        super(p);
066    }
067    /**
068     * constructs a server ISOChannel associated with a Server Socket
069     * @param p     an ISOPackager
070     * @param serverSocket where to accept a connection
071     * @exception IOException
072     * @see ISOPackager
073     */
074    public CSChannel (ISOPackager p, ServerSocket serverSocket)
075        throws IOException
076    {
077        super(p, serverSocket);
078    }
079    /**
080     * @param len the packed Message len
081     * @exception IOException
082     */
083    protected void sendMessageLength(int len) throws IOException {
084        serverOut.write (len >> 8);
085        serverOut.write (len);
086        serverOut.write (0);
087        serverOut.write (0);
088    }
089    /**
090     * @return the Message len
091     * @exception IOException, ISOException
092     */
093    protected int getMessageLength() throws IOException, ISOException {
094        int l = 0;
095        byte[] b = new byte[4];
096        while (l == 0) {
097            serverIn.readFully(b,0,4);
098            l = ((int)b[0] &0xFF) << 8 | (int)b[1] &0xFF;
099            if (l == 0 &&
100                (replyKeepAlive || isExpectKeepAlive()))
101            {
102                serverOutLock.lock();
103                try {
104                    serverOut.write(b);
105                    serverOut.flush();
106                } finally {
107                    serverOutLock.unlock();
108                }
109            }
110        }
111        return l;
112    }
113    protected int getHeaderLength() {
114        // CS Channel does not support header
115        return 0;
116    }
117    protected void sendMessageHeader(ISOMsg m, int len) {
118        // CS Channel does not support header
119    }
120
121    @Override
122    public void setConfiguration (Configuration cfg) throws ConfigurationException {
123        super.setConfiguration(cfg);
124        replyKeepAlive = cfg.getBoolean("reply-keepalive", true);
125    }
126}