FileDocCategorySizeDatePackage
TCPMessageProcessor.javaAPI DocphoneME MR2 API (J2ME)7892Wed May 02 18:00:42 BST 2007gov.nist.siplite.stack

TCPMessageProcessor

public class TCPMessageProcessor extends MessageProcessor implements Runnable
TCP Message Processor.
version
1.0

Fields Summary
private int
localPort
Local Port number.
private ServerSocketConnection
serverSocket
Inbound server socket connection.
public boolean
ERROR_SOCKET
Current error socket disabled.
private SIPMessageStack
sipStack
Our stack (that created us).
private Thread
incomingHandler
Thread of TCP server.
private Vector
tcpMsgChannels
Array of registered message channels.
Constructors Summary
public TCPMessageProcessor(SIPMessageStack ss, int lp)
Creates new TCPMessageProcessor.

param
ss the current SIP stack context
param
lp Local port number for messages

        sipStack = ss;
        localPort = lp;
    
Methods Summary
public MessageChannelcreateMessageChannel(HostPort targetHostPort)
Creates and return new TCPMessageChannel for the given host/port.

param
targetHostPort target host and port address
return
a new message channel

        TCPMessageChannel tmc;
        synchronized (tcpMsgChannels) {
            for (int i = 0; i < tcpMsgChannels.size(); i++) {
                tmc = ((TCPMessageChannel)tcpMsgChannels.elementAt(i));
                if (tmc.getPeerHostPort().equals(targetHostPort)) {
                    tmc.incrementUseCounter();
                    return tmc;
                }
            }
        }
        tmc = new TCPMessageChannel(targetHostPort, sipStack, this);
        tcpMsgChannels.addElement(tmc);
        return tmc;
    
public intgetPort()
Gets the local port identifier.

return
the port for this message processor.

        return localPort;
    
public SIPMessageStackgetSIPStack()
Gets the SIP stack context.

return
the currenit SIP stack

        return sipStack;
    
public SIPMessageStackgetSipStack()
Gets the SIP Stack.

return
the sip stack.

        return sipStack;
    
public java.lang.StringgetTransport()
Gets the transport string.

return
A string that indicates the transport. (i.e. "tcp" or "udp")

        return SIPConstants.TRANSPORT_TCP;
    
public booleanisSecure()
Checks if the currenttransport is secure channel

return
always false

        return false;
    
public voidnotifyClose(TCPMessageChannel tmc)
Notification about message channel shutting down. Now it cat be removed from registration vector.

param
tmc channel that was closed

        tcpMsgChannels.removeElement(tmc);
    
public voidrun()
Main loop for TCP message handling.

    
               
       
        TCPMessageChannel tmc;
        try {
            while (!exitFlag) {
                SocketConnection sock =
                        (SocketConnection) serverSocket.acceptAndOpen();
                if (sock != null) {
                    tmc = new TCPMessageChannel(sock, sipStack, this);
					tcpMsgChannels.addElement(tmc);
				}
            }
        } catch (IOException ex) {
            /*
             * If IOEXception occurs after main thread closes serversocket, 
             * ignore it
             */
            if (!exitFlag) {
                if (Logging.REPORT_LEVEL <= Logging.ERROR) {
                    Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
                        "Server socket exception. "+
                        "Shutting down of incoming handler thread!");
                }
            }
        }
    
public synchronized voidstart()
Starts our thread.

exception
IOException if the connection failed

        /*
         * Original NIST method for opening the serversocket connection
         * has been replaced by direct calls to instantiate the protocol 
         * handler, in order to pass the security token for use of lower 
         * level transport connection. 
         * Original NIST sequence is :
         *
         * serverSocket =  (ServerSocketConnection)
         *    Connector.open("socket://:"+getPort());
         */
        com.sun.midp.io.j2me.socket.Protocol conn =
            new com.sun.midp.io.j2me.socket.Protocol();
        
        serverSocket = (ServerSocketConnection)conn.openPrim(
                sipStack.getSecurityToken(), "//:" + localPort);
        
        // A serversocket needs to be created to handle incoming data.
        // This part of the code is used while creating 
        // a SipConnectionNotifier with TCP transport
        // 
        // Also under error conditions, the server may attempt to open 
        // a new connection to send the response. To handle this case,
        // the transport layer MUST also be prepared to receive
        // an incoming connection on the source IP address from which
        // the request was sent and port number in 
        // the "sent-by" field (RFC3261, p.143)
        incomingHandler = new Thread(this);
        incomingHandler.start();
    
public synchronized voidstop()
Stops the current processor.

        try {
            exitFlag = true;
            if (serverSocket != null) {
                serverSocket.close();
                try {
                    incomingHandler.join();
                } catch (InterruptedException exc) { 
                    // ignore
                }
                serverSocket = null;
            }
            Object[] arr;
            synchronized (tcpMsgChannels) {
                arr = new Object[tcpMsgChannels.size()];
                tcpMsgChannels.copyInto(arr);
            }
            TCPMessageChannel tmc;
            for (int i = 0; i < arr.length; i++) {
                tmc = (TCPMessageChannel)arr[i];
                tmc.exit();
            }
        } catch (IOException ex) {
            if (Logging.REPORT_LEVEL <= Logging.ERROR) {
                Logging.report(Logging.ERROR, LogChannels.LC_JSR180,
                    "SYSTEM, TCPMessageProcessor, stop(), " +
                    "exception raised: " + ex);
            }
        }