From 99705b52ec952012bedc4aa8e1f62caff80a6a2f Mon Sep 17 00:00:00 2001 From: Hung-ying Tyan Date: Tue, 28 Jun 2011 19:56:19 +0800 Subject: Record external IP and port from SIP responses and use them to create the contact header when sending OK response for INVITE. Bug: 3461707 Change-Id: I5b254618f4920cf10a1460631bcd336778f344ec --- voip/java/com/android/server/sip/SipHelper.java | 30 +++++++++++++----- .../com/android/server/sip/SipSessionGroup.java | 37 ++++++++++++++++++++-- 2 files changed, 57 insertions(+), 10 deletions(-) (limited to 'voip') diff --git a/voip/java/com/android/server/sip/SipHelper.java b/voip/java/com/android/server/sip/SipHelper.java index 47950e3..c031bc1 100644 --- a/voip/java/com/android/server/sip/SipHelper.java +++ b/voip/java/com/android/server/sip/SipHelper.java @@ -150,9 +150,17 @@ class SipHelper { private ContactHeader createContactHeader(SipProfile profile) throws ParseException, SipException { - ListeningPoint lp = getListeningPoint(); - SipURI contactURI = - createSipUri(profile.getUserName(), profile.getProtocol(), lp); + return createContactHeader(profile, null, 0); + } + + private ContactHeader createContactHeader(SipProfile profile, + String ip, int port) throws ParseException, + SipException { + SipURI contactURI = (ip == null) + ? createSipUri(profile.getUserName(), profile.getProtocol(), + getListeningPoint()) + : createSipUri(profile.getUserName(), profile.getProtocol(), + ip, port); Address contactAddress = mAddressFactory.createAddress(contactURI); contactAddress.setDisplayName(profile.getDisplayName()); @@ -168,9 +176,14 @@ class SipHelper { private SipURI createSipUri(String username, String transport, ListeningPoint lp) throws ParseException { - SipURI uri = mAddressFactory.createSipURI(username, lp.getIPAddress()); + return createSipUri(username, transport, lp.getIPAddress(), lp.getPort()); + } + + private SipURI createSipUri(String username, String transport, + String ip, int port) throws ParseException { + SipURI uri = mAddressFactory.createSipURI(username, ip); try { - uri.setPort(lp.getPort()); + uri.setPort(port); uri.setTransportParam(transport); } catch (InvalidArgumentException e) { throw new RuntimeException(e); @@ -353,13 +366,14 @@ class SipHelper { */ public ServerTransaction sendInviteOk(RequestEvent event, SipProfile localProfile, String sessionDescription, - ServerTransaction inviteTransaction) - throws SipException { + ServerTransaction inviteTransaction, String externalIp, + int externalPort) throws SipException { try { Request request = event.getRequest(); Response response = mMessageFactory.createResponse(Response.OK, request); - response.addHeader(createContactHeader(localProfile)); + response.addHeader(createContactHeader(localProfile, externalIp, + externalPort)); response.setContent(sessionDescription, mHeaderFactory.createContentTypeHeader( "application", "sdp")); diff --git a/voip/java/com/android/server/sip/SipSessionGroup.java b/voip/java/com/android/server/sip/SipSessionGroup.java index c0c1b28..047eb8d 100644 --- a/voip/java/com/android/server/sip/SipSessionGroup.java +++ b/voip/java/com/android/server/sip/SipSessionGroup.java @@ -119,6 +119,10 @@ class SipSessionGroup implements SipListener { private Map mSessionMap = new HashMap(); + // external address observed from any response + private String mExternalIp; + private int mExternalPort; + /** * @param myself the local profile with password crossed out * @param password the password of the profile @@ -175,6 +179,8 @@ class SipSessionGroup implements SipListener { mCallReceiverSession = null; mSessionMap.clear(); + + resetExternalAddress(); } synchronized void onConnectivityChanged() { @@ -190,6 +196,12 @@ class SipSessionGroup implements SipListener { } } + synchronized void resetExternalAddress() { + Log.d(TAG, " reset external addr on " + mSipStack); + mExternalIp = null; + mExternalPort = 0; + } + public SipProfile getLocalProfile() { return mLocalProfile; } @@ -363,6 +375,21 @@ class SipSessionGroup implements SipListener { return null; } + private void extractExternalAddress(ResponseEvent evt) { + Response response = evt.getResponse(); + ViaHeader viaHeader = (ViaHeader)(response.getHeader( + SIPHeaderNames.VIA)); + if (viaHeader == null) return; + int rport = viaHeader.getRPort(); + String externalIp = viaHeader.getReceived(); + if ((rport > 0) && (externalIp != null)) { + mExternalIp = externalIp; + mExternalPort = rport; + Log.d(TAG, " got external addr " + externalIp + ":" + rport + + " on " + mSipStack); + } + } + private class SipSessionCallReceiverImpl extends SipSessionImpl { public SipSessionCallReceiverImpl(ISipSessionListener listener) { super(listener); @@ -682,6 +709,7 @@ class SipSessionGroup implements SipListener { dialog = ((RequestEvent) evt).getDialog(); } else if (evt instanceof ResponseEvent) { dialog = ((ResponseEvent) evt).getDialog(); + extractExternalAddress((ResponseEvent) evt); } if (dialog != null) mDialog = dialog; @@ -984,7 +1012,8 @@ class SipSessionGroup implements SipListener { mServerTransaction = mSipHelper.sendInviteOk(mInviteReceived, mLocalProfile, ((MakeCallCommand) evt).getSessionDescription(), - mServerTransaction); + mServerTransaction, + mExternalIp, mExternalPort); startSessionTimer(((MakeCallCommand) evt).getTimeout()); return true; } else if (END_CALL == evt) { @@ -1376,6 +1405,7 @@ class SipSessionGroup implements SipListener { if (evt instanceof ResponseEvent) { if (parseOptionsResult(evt)) { if (mPortChanged) { + resetExternalAddress(); stop(); } else { cancelSessionTimer(); @@ -1405,8 +1435,11 @@ class SipSessionGroup implements SipListener { if (!mRunning) return; if (DEBUG_PING) { + String peerUri = (mPeerProfile == null) + ? "null" + : mPeerProfile.getUriString(); Log.d(TAG, "keepalive: " + mLocalProfile.getUriString() - + " --> " + mPeerProfile + ", interval=" + mInterval); + + " --> " + peerUri + ", interval=" + mInterval); } try { sendKeepAlive(); -- cgit v1.1