Skip to content

Commit 870085c

Browse files
Chia-chi YehAndroid (Google) Code Review
authored andcommitted
Merge "SIP: push the logic of finding local address down to SipSessionGroup."
2 parents 689b741 + 2dd9134 commit 870085c

File tree

2 files changed

+60
-89
lines changed

2 files changed

+60
-89
lines changed

voip/java/com/android/server/sip/SipService.java

Lines changed: 3 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -453,9 +453,8 @@ private class SipSessionGroupExt extends SipSessionAdapter {
453453
public SipSessionGroupExt(SipProfile localProfile,
454454
PendingIntent incomingCallPendingIntent,
455455
ISipSessionListener listener) throws SipException {
456-
String password = localProfile.getPassword();
457-
SipProfile p = duplicate(localProfile);
458-
mSipGroup = createSipSessionGroup(mLocalIp, p, password);
456+
mSipGroup = new SipSessionGroup(duplicate(localProfile),
457+
localProfile.getPassword(), mTimer, mMyWakeLock);
459458
mIncomingCallPendingIntent = incomingCallPendingIntent;
460459
mAutoRegistration.setListener(listener);
461460
}
@@ -478,27 +477,6 @@ void setWakeupTimer(SipWakeupTimer timer) {
478477
mSipGroup.setWakeupTimer(timer);
479478
}
480479

481-
// network connectivity is tricky because network can be disconnected
482-
// at any instant so need to deal with exceptions carefully even when
483-
// you think you are connected
484-
private SipSessionGroup createSipSessionGroup(String localIp,
485-
SipProfile localProfile, String password) throws SipException {
486-
try {
487-
return new SipSessionGroup(localIp, localProfile, password,
488-
mTimer, mMyWakeLock);
489-
} catch (IOException e) {
490-
// network disconnected
491-
Log.w(TAG, "createSipSessionGroup(): network disconnected?");
492-
if (localIp != null) {
493-
return createSipSessionGroup(null, localProfile, password);
494-
} else {
495-
// recursive
496-
Log.wtf(TAG, "impossible! recursive!");
497-
throw new RuntimeException("createSipSessionGroup");
498-
}
499-
}
500-
}
501-
502480
private SipProfile duplicate(SipProfile p) {
503481
try {
504482
return new SipProfile.Builder(p).setPassword("*").build();
@@ -530,7 +508,7 @@ public void onConnectivityChanged(boolean connected)
530508
throws SipException {
531509
mSipGroup.onConnectivityChanged();
532510
if (connected) {
533-
resetGroup(mLocalIp);
511+
mSipGroup.reset();
534512
if (mOpenedToReceiveCalls) openToReceiveCalls();
535513
} else {
536514
// close mSipGroup but remember mOpenedToReceiveCalls
@@ -541,22 +519,6 @@ public void onConnectivityChanged(boolean connected)
541519
}
542520
}
543521

544-
private void resetGroup(String localIp) throws SipException {
545-
try {
546-
mSipGroup.reset(localIp);
547-
} catch (IOException e) {
548-
// network disconnected
549-
Log.w(TAG, "resetGroup(): network disconnected?");
550-
if (localIp != null) {
551-
resetGroup(null); // reset w/o local IP
552-
} else {
553-
// recursive
554-
Log.wtf(TAG, "impossible!");
555-
throw new RuntimeException("resetGroup");
556-
}
557-
}
558-
}
559-
560522
public void close() {
561523
mOpenedToReceiveCalls = false;
562524
mSipGroup.close();

voip/java/com/android/server/sip/SipSessionGroup.java

Lines changed: 57 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -40,20 +40,19 @@
4040
import java.io.IOException;
4141
import java.io.UnsupportedEncodingException;
4242
import java.net.DatagramSocket;
43+
import java.net.InetAddress;
4344
import java.net.UnknownHostException;
4445
import java.text.ParseException;
4546
import java.util.Collection;
4647
import java.util.EventObject;
4748
import java.util.HashMap;
4849
import java.util.Map;
4950
import java.util.Properties;
50-
import java.util.TooManyListenersException;
5151

5252
import javax.sip.ClientTransaction;
5353
import javax.sip.Dialog;
5454
import javax.sip.DialogTerminatedEvent;
5555
import javax.sip.IOExceptionEvent;
56-
import javax.sip.InvalidArgumentException;
5756
import javax.sip.ListeningPoint;
5857
import javax.sip.ObjectInUseException;
5958
import javax.sip.RequestEvent;
@@ -132,18 +131,17 @@ class SipSessionGroup implements SipListener {
132131
private int mExternalPort;
133132

134133
/**
135-
* @param myself the local profile with password crossed out
134+
* @param profile the local profile with password crossed out
136135
* @param password the password of the profile
137136
* @throws IOException if cannot assign requested address
138137
*/
139-
public SipSessionGroup(String localIp, SipProfile myself, String password,
140-
SipWakeupTimer timer, SipWakeLock wakeLock) throws SipException,
141-
IOException {
142-
mLocalProfile = myself;
138+
public SipSessionGroup(SipProfile profile, String password,
139+
SipWakeupTimer timer, SipWakeLock wakeLock) throws SipException {
140+
mLocalProfile = profile;
143141
mPassword = password;
144142
mWakeupTimer = timer;
145143
mWakeLock = wakeLock;
146-
reset(localIp);
144+
reset();
147145
}
148146

149147
// TODO: remove this method once SipWakeupTimer can better handle variety
@@ -152,43 +150,64 @@ void setWakeupTimer(SipWakeupTimer timer) {
152150
mWakeupTimer = timer;
153151
}
154152

155-
synchronized void reset(String localIp) throws SipException, IOException {
156-
mLocalIp = localIp;
157-
if (localIp == null) return;
158-
159-
SipProfile myself = mLocalProfile;
160-
SipFactory sipFactory = SipFactory.getInstance();
153+
synchronized void reset() throws SipException {
161154
Properties properties = new Properties();
155+
156+
String protocol = mLocalProfile.getProtocol();
157+
int port = mLocalProfile.getPort();
158+
String server = mLocalProfile.getProxyAddress();
159+
160+
if (!TextUtils.isEmpty(server)) {
161+
properties.setProperty("javax.sip.OUTBOUND_PROXY",
162+
server + ':' + port + '/' + protocol);
163+
} else {
164+
server = mLocalProfile.getSipDomain();
165+
}
166+
if (server.startsWith("[") && server.endsWith("]")) {
167+
server = server.substring(1, server.length() - 1);
168+
}
169+
170+
String local = null;
171+
try {
172+
for (InetAddress remote : InetAddress.getAllByName(server)) {
173+
DatagramSocket socket = new DatagramSocket();
174+
socket.connect(remote, port);
175+
if (socket.isConnected()) {
176+
local = socket.getLocalAddress().getHostAddress();
177+
port = socket.getLocalPort();
178+
socket.close();
179+
break;
180+
}
181+
socket.close();
182+
}
183+
} catch (Exception e) {
184+
// ignore.
185+
}
186+
if (local == null) {
187+
// We are unable to reach the server. Just bail out.
188+
return;
189+
}
190+
191+
close();
192+
mLocalIp = local;
193+
162194
properties.setProperty("javax.sip.STACK_NAME", getStackName());
163195
properties.setProperty(
164196
"gov.nist.javax.sip.THREAD_POOL_SIZE", THREAD_POOL_SIZE);
165-
String outboundProxy = myself.getProxyAddress();
166-
if (!TextUtils.isEmpty(outboundProxy)) {
167-
Log.v(TAG, "outboundProxy is " + outboundProxy);
168-
properties.setProperty("javax.sip.OUTBOUND_PROXY", outboundProxy
169-
+ ":" + myself.getPort() + "/" + myself.getProtocol());
170-
}
171-
SipStack stack = mSipStack = sipFactory.createSipStack(properties);
172-
197+
mSipStack = SipFactory.getInstance().createSipStack(properties);
173198
try {
174-
SipProvider provider = stack.createSipProvider(
175-
stack.createListeningPoint(localIp, allocateLocalPort(),
176-
myself.getProtocol()));
199+
SipProvider provider = mSipStack.createSipProvider(
200+
mSipStack.createListeningPoint(local, port, protocol));
177201
provider.addSipListener(this);
178-
mSipHelper = new SipHelper(stack, provider);
179-
} catch (InvalidArgumentException e) {
180-
throw new IOException(e.getMessage());
181-
} catch (TooManyListenersException e) {
182-
// must never happen
183-
throw new SipException("SipSessionGroup constructor", e);
202+
mSipHelper = new SipHelper(mSipStack, provider);
203+
} catch (SipException e) {
204+
throw e;
205+
} catch (Exception e) {
206+
throw new SipException("failed to initialize SIP stack", e);
184207
}
185-
Log.d(TAG, " start stack for " + myself.getUriString());
186-
stack.start();
187-
188-
mCallReceiverSession = null;
189-
mSessionMap.clear();
190208

191-
resetExternalAddress();
209+
Log.d(TAG, " start stack for " + mLocalProfile.getUriString());
210+
mSipStack.start();
192211
}
193212

194213
synchronized void onConnectivityChanged() {
@@ -234,6 +253,7 @@ public synchronized void close() {
234253
mSipStack = null;
235254
mSipHelper = null;
236255
}
256+
resetExternalAddress();
237257
}
238258

239259
public synchronized boolean isClosed() {
@@ -257,17 +277,6 @@ public ISipSession createSession(ISipSessionListener listener) {
257277
return (isClosed() ? null : new SipSessionImpl(listener));
258278
}
259279

260-
private static int allocateLocalPort() throws SipException {
261-
try {
262-
DatagramSocket s = new DatagramSocket();
263-
int localPort = s.getLocalPort();
264-
s.close();
265-
return localPort;
266-
} catch (IOException e) {
267-
throw new SipException("allocateLocalPort()", e);
268-
}
269-
}
270-
271280
synchronized boolean containsSession(String callId) {
272281
return mSessionMap.containsKey(callId);
273282
}

0 commit comments

Comments
 (0)