Package org.cafesip.reference.jiplet

Source Code of org.cafesip.reference.jiplet.SipProxy

/*
* Created on May 31, 2005
*
* Copyright 2005 CafeSip.org
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.cafesip.reference.jiplet;

import java.text.ParseException;
import java.util.ListIterator;

import javax.sip.InvalidArgumentException;
import javax.sip.ListeningPoint;
import javax.sip.RequestEvent;
import javax.sip.ResponseEvent;
import javax.sip.SipException;
import javax.sip.SipProvider;
import javax.sip.address.Address;
import javax.sip.header.ContactHeader;
import javax.sip.header.MaxForwardsHeader;
import javax.sip.header.ToHeader;
import javax.sip.header.ViaHeader;
import javax.sip.message.Request;
import javax.sip.message.Response;

import org.cafesip.jiplet.Jiplet;
import org.cafesip.jiplet.JipletException;
import org.cafesip.jiplet.JipletLogger;
import org.cafesip.jiplet.JipletRequest;
import org.cafesip.jiplet.JipletResponse;
import org.cafesip.jiplet.JipletSession;
import org.cafesip.jiplet.config.jip.JipletConfig;
import org.cafesip.jiplet.sip.ProxyUtilities;

/**
* @author Amit Chatterjee
*/
public class SipProxy extends Jiplet
{
    private Object callIdLock = new Object();
   
    private int callId = 0;
   
    /**
     * A constructor for this class.
     *
     * 
     */
    public SipProxy()
    {
        super();
    }

    /*
     * @see org.cafesip.jiplet.Jiplet#init(org.cafesip.jiplet.config.jip.JipletConfig)
     */
    public void init(JipletConfig config) throws JipletException
    {
        super.init(config);

        ListeningPoint lp = getListeningPointDefault();
        info("Started SIP stateless proxy on IP=" + lp.getIPAddress() + " port=" + lp.getPort()
                + " protocol=" + lp.getTransport());
    }

    /*
     * @see org.cafesip.jiplet.Jiplet#processRequest(org.cafesip.jiplet.JipletRequest)
     */
    public void processRequest(JipletRequest requestEvent)
    {
        //   print the trace provided by the base-class.
        super.processRequest(requestEvent);
       
        try
        {
            RequestEvent req_event = requestEvent.getRequestEvent();
            Request req_msg = req_event.getRequest();
            SipProvider provider = (SipProvider) req_event.getSource();

            JipletSession session = null;
            if (req_msg.getMethod().equals(Request.INVITE) == true)
            {
                session = requestEvent.getSession(true);
                synchronized (callIdLock)
                {
                    callId++;
                    info ("SIP session " + callId + " created.");
                    session.setAttribute("callId", new Integer(callId));
                    ListeningPoint lp = provider.getListeningPoints()[0];
                    session.setAttribute("requestSourceIp", new String(lp.getIPAddress()));
                    session.setAttribute("requestSourcePort", new Integer(lp.getPort()));
                }
            }
            else
            {
                session = requestEvent.getSession(false);
                if (session != null)
                {
                    Integer c = (Integer) session.getAttribute("callId");
                    if (c != null)
                    {
                        info("SIP request message  received for  session " + c);
                    }
                }
               
                if (req_msg.getMethod().equals(Request.BYE) == true)
                {
                    if (session != null)
                    {
                        session.invalidate();
                    }
                }
            }
           
            // Act as a stateless proxy. Forward the message to the phone.

            ToHeader to = (ToHeader) req_msg.getHeader(ToHeader.NAME);
            String addr = to.getAddress().getURI().toString();

            // check if user has registered
            ContactInfo contact = (ContactInfo) LocationDatabase
                    .getInstance().get(addr);
            if (contact == null)
            {
                debug("Request message received for an unknown user. Tossing the request");
                 return;
            }

            // the message is for a location that has registered. Forward the message.
            forwardRequestMessage(req_msg, contact.getContact(), getListeningPointDefault());
           
        }
        catch (Exception e)
        {
            fatal(e.getClass().getName() + ": " + e.getMessage() + "\n"
                    + JipletLogger.getStackTrace(e));
        }
        finally
        {
            // forward to the SipRecorder so that it can record the request message.
            forward(requestEvent, "ExampleSIPRecorderJiplet"); // this should be the last thing we do
        }
    }

    private void forwardRequestMessage(Request request, ContactHeader contact,
            ListeningPoint listeningPoint) throws ParseException,
            InvalidArgumentException, SipException
    {
        Request req = (Request) request.clone();

        // replace the URI with the contact URI
        Address address = contact.getAddress();

        req.setRequestURI(address.getURI());

        // add the VIA header
        ViaHeader via = getHeaderFactory().createViaHeader(
                listeningPoint.getIPAddress(), listeningPoint.getPort(),
                listeningPoint.getTransport(),
                ProxyUtilities.generateBranchId());

        req.addHeader(via);

        // decrement the hop count
        int num_forwards = 70;
        MaxForwardsHeader forwards = (MaxForwardsHeader) request
                .getHeader(MaxForwardsHeader.NAME);
        if (forwards != null)
        {
            num_forwards = forwards.getMaxForwards() - 1;
            if (num_forwards <= 0)
            {
                // oops, we are not supposed to forward further, but since we
                // are not a real proxy server,
                // we will do it anyways. Hopefully, the next guy will catch it.
                num_forwards = 1;
            }
        }
        forwards = getHeaderFactory().createMaxForwardsHeader(num_forwards);
        req.setHeader(forwards);

        debug("Forwarding the request message to " + contact.getAddress());
        getSipProvider(listeningPoint).sendRequest(req);

        // register for response for requests for which responses are expected.
        String method = req.getMethod();
       
        // TODO add other methods
        if (method.equals(Request.ACK) == false)
        {
            registerForResponse(req, 30000L);
        }
    }
   
    /*
     * @see org.cafesip.jiplet.Jiplet#processResponse(org.cafesip.jiplet.JipletResponse)
     */
    public void processResponse(JipletResponse responseEvent)
    {
        //   print the trace provided by the base-class.
        super.processResponse(responseEvent);

        SipProvider provider = getSipProvider(getListeningPointDefault());
        JipletSession session = responseEvent.getSession(false);
        if (session != null)
        {
            Integer c = (Integer) session.getAttribute("callId");
            if (c != null)
            {
                info("SIP request message  received for  session " + c);
            }
           
            String sourceIp = (String) session.getAttribute("requestSourceIp");
            if (sourceIp != null)
            {
                int sourcePort = ((Integer) session.getAttribute("requestSourcePort")).intValue();
                provider = getSipProvider(sourceIp, sourcePort);
            }
        }

        try
        {
            ResponseEvent rsp_event = responseEvent.getResponseEvent();
            Response rsp_msg = rsp_event.getResponse();

            forwardResponseMessage(rsp_msg, provider);           
        }
        catch (Exception e)
        {
            fatal(e.getClass().getName() + ": " + e.getMessage() + "\n"
                    + JipletLogger.getStackTrace(e));
        }
        finally
        {
            // forward to the SipRecorder so that it can record the response message.
            forward(responseEvent, "ExampleSIPRecorderJiplet"); // this should be the last thing we do
        }
    }

    private void forwardResponseMessage(Response response,
            SipProvider provider)
            throws InvalidArgumentException, SipException
    {
        Response resp = (Response) response.clone();

        ListIterator iter = resp.getHeaders(ViaHeader.NAME);
        if (iter != null)
        {
            iter.next();
            iter.remove();
        }

        if (isDebugEnabled() == true)
        {
            debug("Forwarding the response");
        }
        provider.sendResponse(resp);
    }
}
TOP

Related Classes of org.cafesip.reference.jiplet.SipProxy

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.