Package org.jvnet.glassfish.comms.sipagent.backend

Source Code of org.jvnet.glassfish.comms.sipagent.backend.SocketController

/*
* The contents of this file are subject to the terms
* of the Common Development and Distribution License
* (the License).  You may not use this file except in
* compliance with the License.
*
* You can obtain a copy of the license at
* https://glassfish.dev.java.net/public/CDDLv1.0.html or
* glassfish/bootstrap/legal/CDDLv1.0.txt.
* See the License for the specific language governing
* permissions and limitations under the License.
*
* When distributing Covered Code, include this CDDL
* Header Notice in each file and include the License file
* at glassfish/bootstrap/legal/CDDLv1.0.txt. 
* If applicable, add the following below the CDDL Header,
* with the fields enclosed by brackets [] replaced by
* you own identifying information:
* "Portions Copyrighted [year] [name of copyright owner]"
*
* Copyright (c) Ericsson AB, 2004-2007. All rights reserved.
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
*/

package org.jvnet.glassfish.comms.sipagent.backend;

import org.jvnet.glassfish.comms.sipagent.model.MySipParser;
import org.jvnet.glassfish.comms.sipagent.model.ParserException;
import org.jvnet.glassfish.comms.sipagent.model.SipMessage;
import org.jvnet.glassfish.comms.sipagent.model.SipRequest;
import org.jvnet.glassfish.comms.sipagent.model.SipResponse;
import org.jvnet.glassfish.comms.sipagent.support.LogSupport;
import org.jvnet.glassfish.comms.sipagent.support.MessageTracer;
import org.jvnet.glassfish.comms.sipagent.model.ModelListener;
import org.jvnet.glassfish.comms.sipagent.support.Constants;
import org.jvnet.glassfish.comms.sipagent.transport.SocketHandler;
import org.jvnet.glassfish.comms.sipagent.transport.TCPSocketHandler;
import org.jvnet.glassfish.comms.sipagent.transport.TransportListener;
import org.jvnet.glassfish.comms.sipagent.transport.UDPSocketHandler;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
*
* @author elnyvbo
*/
public class SocketController implements Controller, TransportListener {
   
    private static Logger theirLogger =
            Logger.getLogger("org.jvnet.glassfish.comms.sipagent.backend.SocketController");
   
    private SocketHandler itsSocketHandler = null;
    private List<ModelListener> itsListeners = null;
    private Constants itsConstants = null;
   
    /**
     * Creates a new instance of SocketController
     */
    public SocketController() {
    }
   
    public void init(Constants aConstants){
        itsConstants = aConstants;
        String host = itsConstants.getProperty(Constants.HOST);
        String port = itsConstants.getProperty(Constants.PORT);
        String localPort = itsConstants.getProperty(Constants.LOCAL_PORT);
        int portNr = 5060;
        int localPortNr = 6060;
        try {
            portNr = Integer.parseInt(port);
        } catch (NumberFormatException nfe) {
            theirLogger.log(Level.FINER,
                    "Illegal SIP server port specified in config, will use 5060",
                    nfe);
        }
        try {
            localPortNr = Integer.parseInt(localPort);
        } catch (NumberFormatException nfe) {
            theirLogger.log(Level.FINER,
                    "Illegal local SIP port specified in config, will use 6060",
                    nfe);
        }
       
        theirLogger.fine(
                "Connecting to host " + host + " on port " +port+ "...");
       
        try {
            InetAddress localHost = InetAddress.getLocalHost();
            InetAddress remoteHost = InetAddress.getByName(host);
            itsSocketHandler =
                Constants.TCP.equals(itsConstants.getProperty(
                    Constants.TRANSPORT))
                ? new TCPSocketHandler(
                        localHost, localPortNr, remoteHost, portNr)
                : new UDPSocketHandler(
                        localHost, localPortNr, remoteHost, portNr);
           
        } catch (UnknownHostException e) {
            theirLogger.severe(
                    "Unable to connect to server: " + LogSupport.stringify(e));
        }
       
        MessageTracer tracer = new MessageTracer();
        itsSocketHandler.setTransportListenerList(
            new Vector<TransportListener>());
        itsSocketHandler.addListener(tracer);
        itsSocketHandler.addListener(this);
        // could add other listeners here e.g. for database storage
        // logging to a file, or whatever.
       
        // Prepare list of consumers
        itsListeners = new Vector<ModelListener>();
       
        new Thread(itsSocketHandler).start();
    }
   
    public SipRequest createRequest(){
        SipRequest result = null;
        try{
            result = this.createRequest(itsConstants.dummyRequest());
        }
        catch (BackendException e){
            // This would be a programmatic error as Constants should return
            // a valid String! result will be null, and may result in a Null
            // PointerException further down the chain. Log the error obviously...
            theirLogger.log(Level.SEVERE,"PROGRAM ERROR ! ",e);
        }
       
        return result;
    }
   
    public SipRequest createRequest(String aBunchOfText)
        throws BackendException {
        SipRequest result;
        try {
            result = (SipRequest)(this.doParse(aBunchOfText));
        }
        catch (Throwable t){
            throw new BackendException(
               "Failed to create a SIP request based on the input text. ", t);
        }
        return result;
    }
   
    public SipResponse createResponse() {
        throw new RuntimeException("NYI");
    }
   
    public SipResponse createResponse(String aBunchOfText)
        throws BackendException {
        SipResponse result;
        try {
            result = (SipResponse)(this.doParse(aBunchOfText));
        }
        catch (Throwable t){
            throw new BackendException(
               "Failed to create a SIP response based on the input text. ", t);
        }
        return result;
    }
   
    private SipMessage doParse(String aText) throws ParserException {
        theirLogger.finer("Parsing text: " + aText);
        ByteBuffer bb = ByteBuffer.wrap(aText.getBytes());
        MySipParser p = MySipParser.getInstance();
        // TODO apparently passing in a bunch of nulls works fine!
        SipMessage result = p.parseMessage(null, bb, null, null, null);
       
        theirLogger.finer("Created message: " + result);
        // fix for parser 'bug' it either returns null or throws an exception...
        if (result == null){
            throw new ParserException(
                "Resulting message after parsing was null");
        }
        return result;
    }
   
    public void sendMessage(SipMessage aMessage) {
        try {
            itsSocketHandler.sendMessage(aMessage);
        } catch (Exception e) {
            theirLogger.log(Level.SEVERE,
                    "Error sending message",e);
        }
    }
   
    public void registerListener(ModelListener aListener) {
        // the transport layer will fireMessageReceived(SipMessage) to
        // whomever is intereseted. in this case it should be the ui.
       
        // BUT:
       
        // In case there's no GUI listening to model changes, controller could
        // decide to buffer sent and received messages in a database or so.
       
        // SO:
       
        // controller registers once with the sockethandler, and several
        // clients can register with the controller.
        long tid = Thread.currentThread().getId();
       
        theirLogger.fine(
            "registering listener: " + aListener + "(thread " + tid + ", object " + this);
       
        itsListeners.add(aListener);
       
    }
   
    public void close(){
        theirLogger.finest("----- close ----->");
        theirLogger.finest("Stopping socket handler...");
        itsSocketHandler.stop();
        theirLogger.finest("<----- close -----");
    }

    public void messageReceived(SipMessage sipmessage) {
        long tid = Thread.currentThread().getId();
        theirLogger.fine(
            "messageReceived (thread " + tid + ", object " + this);
       
       
        // TODO determine if this was a retransmission
        for (ModelListener m : itsListeners) {
            m.incomingMessage(sipmessage);
        }
    }

    public void messageSent(SipMessage sipmessage) {
        long tid = Thread.currentThread().getId();
        theirLogger.fine(
            "messageSent(thread " + tid + ", object " + this);
       
        // clients might care: GUI should be updated when message was actually
        // sent out.
        for (ModelListener m : itsListeners) {
            m.outgoingMessage(sipmessage);
        }
       
    }
   
}
TOP

Related Classes of org.jvnet.glassfish.comms.sipagent.backend.SocketController

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.