create package sipproxy and move code tunneling sip to jxta from core to this new package

git-svn-id: svn+ssh://svn.savannah.nongnu.org/linphone/trunk@20 3f6dc0c8-ddfe-455d-9043-3cd528dc4637
This commit is contained in:
jehan 2008-09-16 13:54:05 +00:00
parent 61af348392
commit 74c12a5761
5 changed files with 301 additions and 60 deletions

View file

@ -25,12 +25,12 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
import org.linphone.p2pproxy.core.media.jxtaudpproxy.RtpSession;
import org.linphone.p2pproxy.core.media.jxtaudpproxy.RtpSessionImpl;
import net.jxta.discovery.DiscoveryService;
import net.jxta.pipe.InputPipe;
import net.jxta.pipe.OutputPipe;
import net.jxta.pipe.PipeMsgListener;
/**

View file

@ -0,0 +1,215 @@
/*
p2pproxy Copyright (C) 2007 Jehan Monnier ()
JxtaSipProxy.java - .
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.p2pproxy.core.sipproxy;
import java.io.IOException;
import java.util.Map;
import net.jxta.document.Advertisement;
import net.jxta.endpoint.MessageElement;
import net.jxta.endpoint.StringMessageElement;
import net.jxta.pipe.OutputPipe;
import net.jxta.pipe.PipeMsgEvent;
import net.jxta.pipe.PipeMsgListener;
import net.jxta.protocol.PipeAdvertisement;
import org.apache.log4j.Logger;
import org.linphone.p2pproxy.api.P2pProxyException;
import org.linphone.p2pproxy.api.P2pProxyRtpRelayManagement;
import org.linphone.p2pproxy.api.P2pProxyUserNotFoundException;
import org.linphone.p2pproxy.core.JxtaNetworkManager;
import org.linphone.p2pproxy.core.P2pProxyAdvertisementNotFoundException;
import org.linphone.p2pproxy.core.media.rtprelay.SdpProcessorImpl;
import org.zoolu.sip.address.NameAddress;
import org.zoolu.sip.address.SipURL;
import org.zoolu.sip.header.MultipleHeader;
import org.zoolu.sip.header.RouteHeader;
import org.zoolu.sip.message.Message;
import org.zoolu.sip.message.MessageFactory;
import org.zoolu.sip.provider.SipProvider;
import org.zoolu.sip.transaction.TransactionServer;
public class JxtaSipProxy implements SipProxy, PipeMsgListener {
private final JxtaNetworkManager mJxtaNetworkManager;
private final Map<String,SipProxyRegistrar.Registration> mRegistrationTab;
private final SdpProcessor mSdpProcessor;
private final SipProvider mProvider;
private final static Logger mLog = Logger.getLogger(JxtaSipProxy.class);
public JxtaSipProxy(SipProvider aProvider,JxtaNetworkManager aJxtaNetworkManager, Map<String,SipProxyRegistrar.Registration> aRegistrationTab,P2pProxyRtpRelayManagement aP2pProxyRtpRelayManagement) {
mJxtaNetworkManager = aJxtaNetworkManager;
mSdpProcessor = new SdpProcessorImpl(aP2pProxyRtpRelayManagement);
mRegistrationTab = aRegistrationTab;
mProvider = aProvider;
}
public void proxyRequest(SipProvider aProvider, Message aMessage) throws P2pProxyException {
if (aMessage.isAck() && aMessage.getToHeader().getTag() == null) {
// just terminate the Invite transaction
return;
}
if (aMessage.isInvite() == true) {
// 100 trying
TransactionServer lTransactionServer = new TransactionServer(aProvider,aMessage,null);
Message l100Trying = MessageFactory.createResponse(aMessage,100,"trying",null);
lTransactionServer.respondWith(l100Trying);
}
String lTo = aMessage.getToHeader().getNameAddress().getAddress().toString();
//remove route
MultipleHeader lMultipleRoute = aMessage.getRoutes();
if (lMultipleRoute != null) {
lMultipleRoute.removeTop();
aMessage.setRoutes(lMultipleRoute);
}
// add Via only udp
SipUtils.addVia(aProvider,aMessage);
// add recordRoute
SipUtils.addRecordRoute(aProvider,aMessage);
try {
mSdpProcessor.processSdpBeforeSendingToPipe(aMessage);
// proxy message to pipe
OutputPipe lOutputPipe = sendMessageToPipe(lTo,aMessage.toString());
mSdpProcessor.processSdpAfterSentToPipe( aMessage,lOutputPipe);
} catch (P2pProxyUserNotFoundException e) {
//remove via
SipUtils.removeVia(aProvider, aMessage);
if (aMessage.isInvite()) {
Message lresp = MessageFactory.createResponse(aMessage,404,e.getMessage(),null);
TransactionServer lTransactionServer = new TransactionServer(aProvider,aMessage,null);
lTransactionServer.respondWith(lresp);
} else {
throw e;
}
} catch (Exception e2) {
//remove via
SipUtils.removeVia(aProvider, aMessage);
throw new P2pProxyException(e2);
}
}
public void proxyResponse(SipProvider aProvider, Message aMessage) throws P2pProxyException {
try {
String lFrom = aMessage.getFromHeader().getNameAddress().getAddress().toString();
mSdpProcessor.processSdpBeforeSendingToPipe(aMessage);
OutputPipe lOutputPipe = sendMessageToPipe(lFrom,aMessage.toString());
mSdpProcessor.processSdpAfterSentToPipe( aMessage,lOutputPipe);
} catch(Exception e) {
throw new P2pProxyException(e);
}
}
private Advertisement getPipeAdv(String aUser,long aDiscoveryTimout,boolean isTryFromLocal) throws InterruptedException, P2pProxyUserNotFoundException, IOException {
// search on all peers
try {
return mJxtaNetworkManager.getAdvertisement(null,aUser, isTryFromLocal);
} catch (P2pProxyAdvertisementNotFoundException e) {
throw new P2pProxyUserNotFoundException(e);
}
}
private OutputPipe sendMessageToPipe(String aDestination,String lContent) throws NumberFormatException, InterruptedException, P2pProxyException, IOException {
//1 search for pipe
long lTimeout = JxtaNetworkManager.ADV_DISCOVERY_TIMEOUT_INT;
PipeAdvertisement lPipeAdvertisement = (PipeAdvertisement)getPipeAdv(aDestination,lTimeout,true);
OutputPipe lOutputPipe=null;
try {
// create output pipe
lOutputPipe = mJxtaNetworkManager.getPeerGroup().getPipeService().createOutputPipe(lPipeAdvertisement, lTimeout);
//create the message
} catch (IOException e) {
//second try from remote only to avoid wrong cached value
mJxtaNetworkManager.getPeerGroup().getDiscoveryService().flushAdvertisement(lPipeAdvertisement);
mLog.warn("cannot create output pipe, trying to ask from rdv ",e);
lPipeAdvertisement = (PipeAdvertisement)getPipeAdv(aDestination,lTimeout,false);
lOutputPipe = mJxtaNetworkManager.getPeerGroup().getPipeService().createOutputPipe(lPipeAdvertisement, lTimeout);
}
net.jxta.endpoint.Message lMessage = new net.jxta.endpoint.Message();
StringMessageElement lStringMessageElement = new StringMessageElement("SIP", lContent, null);
lMessage.addMessageElement("SIP", lStringMessageElement);
//send the message
lOutputPipe.send(lMessage);
mLog.debug("message sent to ["+aDestination+"]");
return lOutputPipe;
}
//////////////////////////////////////////////////////////////////////
////jxta service methods
/////////////////////////////////////////////////////////////////////
public void pipeMsgEvent(PipeMsgEvent anEvent) {
MessageElement lMessageElement = anEvent.getMessage().getMessageElement("SIP");
if (lMessageElement == null) {
//nop, this is not for me
return;
}
String lMesssage = lMessageElement.toString();
mLog.info("pipe event sip message["+lMesssage+"]");
Message lSipMessage = new Message(lMesssage);
// process request
if (lSipMessage.isRequest()) {
SipURL lNextHope ;
// get next hope from registrar
String lToName = lSipMessage.getToHeader().getNameAddress().getAddress().toString();
if (mRegistrationTab.containsKey(lToName)) {
lNextHope = new SipURL(mRegistrationTab.get(lToName).Contact);
} else {
mLog.error("user ["+lToName+"] not found");
return;
}
//RequestLine lRequestLine = new RequestLine(lSipMessage.getRequestLine().getMethod(),lNextHope);
//lSipMessage.setRequestLine(lRequestLine);
MultipleHeader lMultipleRoute = lSipMessage.getRoutes();
RouteHeader lRouteHeader = new RouteHeader(new NameAddress(lNextHope+";lr"));
//lRouteHeader.setParameter("lr", null);
if (lMultipleRoute != null) {
lMultipleRoute.addTop(lRouteHeader);
lSipMessage.setRoutes(lMultipleRoute);
} else {
lSipMessage.addRouteHeader(lRouteHeader);
}
// add Via only udp
SipUtils.addVia(mProvider,lSipMessage);
// add recordRoute
SipUtils.addRecordRoute(mProvider,lSipMessage);
} else {
//response
//1 remove via header
SipUtils.removeVia(mProvider,lSipMessage);
}
try {
mSdpProcessor.processSdpBeforeSendingToSipUA( lSipMessage);
} catch (P2pProxyException e) {
mLog.error("enable to re-write sdp",e);
}
mProvider.sendMessage(lSipMessage);
//
}
}

View file

@ -0,0 +1,29 @@
/*
p2pproxy Copyright (C) 2007 Jehan Monnier ()
SipProxy.java - .
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.p2pproxy.core.sipproxy;
import org.linphone.p2pproxy.api.P2pProxyException;
import org.zoolu.sip.message.Message;
import org.zoolu.sip.provider.SipProvider;
public interface SipProxy {
public void proxyRequest(SipProvider aProvider, Message aMessage) throws P2pProxyException;
public void proxyResponse(SipProvider aProvider, Message aMessage) throws P2pProxyException;
}

View file

@ -65,7 +65,7 @@ import org.zoolu.sip.provider.SipProvider;
import org.zoolu.sip.provider.SipProviderListener;
import org.zoolu.sip.provider.SipStack;
import org.zoolu.sip.transaction.TransactionServer;
public class SipProxyRegistrar implements SipProviderListener,PipeMsgListener,SipProxyRegistrarMBean {
public class SipProxyRegistrar implements SipProviderListener,SipProxyRegistrarMBean {
private final static Logger mLog = Logger.getLogger(SipProxyRegistrar.class);
public final static String REGISTRAR_PORT="org.linphone.p2pproxy.SipListener.registrar.port";
public final static String UDP_PORT_BEGING="org.linphone.p2pproxy.udp.port.begin";
@ -81,7 +81,7 @@ public class SipProxyRegistrar implements SipProviderListener,PipeMsgListener,Si
private final P2pProxyAccountManagementMBean mP2pProxyAccountManagement;
private final Configurator mProperties;
private final SdpProcessor mSdpProcessor;
//private long mNumberOfEstablishedCall;
private long mNumberOfRefusedRegistration;
private long mNumberOfSuccessfullRegistration;
@ -183,7 +183,7 @@ public class SipProxyRegistrar implements SipProviderListener,PipeMsgListener,Si
mProvider=new SipProvider(null,lPort,lProto,SipProvider.ALL_INTERFACES);
mProvider.addSipProviderListener(SipProvider.PROMISQUE,this);
mPool = Executors.newCachedThreadPool();
mSdpProcessor = new SdpProcessorImpl(aP2pProxyRtpRelayManagement);
}
public synchronized void onReceivedMessage(SipProvider aProvider, Message aMessage) {
@ -289,61 +289,6 @@ public class SipProxyRegistrar implements SipProviderListener,PipeMsgListener,Si
aRegistration.NetResources.publish(aRegistration.Expiration);
}
//////////////////////////////////////////////////////////////////////
////jxta service methods
/////////////////////////////////////////////////////////////////////
public void pipeMsgEvent(PipeMsgEvent anEvent) {
MessageElement lMessageElement = anEvent.getMessage().getMessageElement("SIP");
if (lMessageElement == null) {
//nop, this is not for me
return;
}
String lMesssage = lMessageElement.toString();
mLog.info("pipe event sip message["+lMesssage+"]");
Message lSipMessage = new Message(lMesssage);
// process request
if (lSipMessage.isRequest()) {
SipURL lNextHope ;
// get next hope from registrar
String lToName = lSipMessage.getToHeader().getNameAddress().getAddress().toString();
if (mRegistrationTab.containsKey(lToName)) {
lNextHope = new SipURL(mRegistrationTab.get(lToName).Contact);
} else {
mLog.error("user ["+lToName+"] not found");
return;
}
//RequestLine lRequestLine = new RequestLine(lSipMessage.getRequestLine().getMethod(),lNextHope);
//lSipMessage.setRequestLine(lRequestLine);
MultipleHeader lMultipleRoute = lSipMessage.getRoutes();
RouteHeader lRouteHeader = new RouteHeader(new NameAddress(lNextHope+";lr"));
//lRouteHeader.setParameter("lr", null);
if (lMultipleRoute != null) {
lMultipleRoute.addTop(lRouteHeader);
lSipMessage.setRoutes(lMultipleRoute);
} else {
lSipMessage.addRouteHeader(lRouteHeader);
}
// add Via only udp
SipUtils.addVia(mProvider,lSipMessage);
// add recordRoute
SipUtils.addRecordRoute(mProvider,lSipMessage);
} else {
//response
//1 remove via header
SipUtils.removeVia(mProvider,lSipMessage);
}
try {
mSdpProcessor.processSdpBeforeSendingToSipUA( lSipMessage);
} catch (P2pProxyException e) {
mLog.error("enable to re-write sdp",e);
}
mProvider.sendMessage(lSipMessage);
//
}

View file

@ -0,0 +1,52 @@
/*
p2pproxy Copyright (C) 2007 Jehan Monnier ()
SipUtils.java - .
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/
package org.linphone.p2pproxy.core.sipproxy;
import org.zoolu.sip.address.NameAddress;
import org.zoolu.sip.address.SipURL;
import org.zoolu.sip.header.Header;
import org.zoolu.sip.header.RecordRouteHeader;
import org.zoolu.sip.header.ViaHeader;
import org.zoolu.sip.message.Message;
import org.zoolu.sip.provider.SipProvider;
public class SipUtils {
public static void addVia(SipProvider aProvider, Message aMessage) {
ViaHeader via=new ViaHeader("udp",aProvider.getViaAddress(),aProvider.getPort());
String branch=aProvider.pickBranch(aMessage);
via.setBranch(branch);
aMessage.addViaHeader(via);
}
public static void addRecordRoute(SipProvider aProvider, Message aMessage) {
SipURL lRecordRoute;
lRecordRoute=new SipURL(aProvider.getViaAddress(),aProvider.getPort());
lRecordRoute.addLr();
RecordRouteHeader lRecordRouteHeader=new RecordRouteHeader(new NameAddress(lRecordRoute));
aMessage.addRecordRouteHeader(lRecordRouteHeader);
}
public static void removeVia(SipProvider aProvider, Message aMessage) {
synchronized (aMessage) {
ViaHeader lViaHeader =new ViaHeader((Header)aMessage.getVias().getHeaders().elementAt(0));
if (lViaHeader.getHost().equals(aProvider.getViaAddress()) && lViaHeader.getPort() == aProvider.getPort() ) {
aMessage.removeViaHeader();
}
}
}
}