Loading services/java/com/android/server/sip/SipHelper.java +20 −7 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import javax.sip.message.Response; */ class SipHelper { private static final String TAG = SipHelper.class.getSimpleName(); private static final boolean DEBUG = true; private SipStack mSipStack; private SipProvider mSipProvider; Loading Loading @@ -264,6 +265,7 @@ class SipHelper { ClientTransaction clientTransaction = mSipProvider.getNewClientTransaction(request); if (DEBUG) Log.d(TAG, "send INVITE: " + request); clientTransaction.sendRequest(); return clientTransaction; } catch (ParseException e) { Loading @@ -281,6 +283,7 @@ class SipHelper { ClientTransaction clientTransaction = mSipProvider.getNewClientTransaction(request); if (DEBUG) Log.d(TAG, "send RE-INVITE: " + request); dialog.sendRequest(clientTransaction); return clientTransaction; } catch (ParseException e) { Loading Loading @@ -314,6 +317,7 @@ class SipHelper { ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); toHeader.setTag(tag); response.addHeader(toHeader); if (DEBUG) Log.d(TAG, "send RINGING: " + response); transaction.sendResponse(response); return transaction; } catch (ParseException e) { Loading @@ -340,7 +344,9 @@ class SipHelper { if (inviteTransaction == null) { inviteTransaction = getServerTransaction(event); } if (inviteTransaction.getState() != TransactionState.COMPLETED) { if (DEBUG) Log.d(TAG, "send OK: " + response); inviteTransaction.sendResponse(response); } Loading @@ -358,6 +364,7 @@ class SipHelper { Response.BUSY_HERE, request); if (inviteTransaction.getState() != TransactionState.COMPLETED) { if (DEBUG) Log.d(TAG, "send BUSY HERE: " + response); inviteTransaction.sendResponse(response); } } catch (ParseException e) { Loading @@ -373,27 +380,31 @@ class SipHelper { Response response = event.getResponse(); long cseq = ((CSeqHeader) response.getHeader(CSeqHeader.NAME)) .getSeqNumber(); dialog.sendAck(dialog.createAck(cseq)); Request ack = dialog.createAck(cseq); if (DEBUG) Log.d(TAG, "send ACK: " + ack); dialog.sendAck(ack); } public void sendBye(Dialog dialog) throws SipException { Request byeRequest = dialog.createRequest(Request.BYE); Log.d(TAG, "send BYE: " + byeRequest); if (DEBUG) Log.d(TAG, "send BYE: " + byeRequest); dialog.sendRequest(mSipProvider.getNewClientTransaction(byeRequest)); } public void sendCancel(ClientTransaction inviteTransaction) throws SipException { Request cancelRequest = inviteTransaction.createCancel(); if (DEBUG) Log.d(TAG, "send CANCEL: " + cancelRequest); mSipProvider.getNewClientTransaction(cancelRequest).sendRequest(); } public void sendResponse(RequestEvent event, int responseCode) throws SipException { try { getServerTransaction(event).sendResponse( mMessageFactory.createResponse( responseCode, event.getRequest())); Response response = mMessageFactory.createResponse( responseCode, event.getRequest()); if (DEBUG) Log.d(TAG, "send response: " + response); getServerTransaction(event).sendResponse(response); } catch (ParseException e) { throw new SipException("sendResponse()", e); } Loading @@ -402,8 +413,10 @@ class SipHelper { public void sendInviteRequestTerminated(Request inviteRequest, ServerTransaction inviteTransaction) throws SipException { try { inviteTransaction.sendResponse(mMessageFactory.createResponse( Response.REQUEST_TERMINATED, inviteRequest)); Response response = mMessageFactory.createResponse( Response.REQUEST_TERMINATED, inviteRequest); if (DEBUG) Log.d(TAG, "send response: " + response); inviteTransaction.sendResponse(response); } catch (ParseException e) { throw new SipException("sendInviteRequestTerminated()", e); } Loading services/java/com/android/server/sip/SipService.java +67 −54 Original line number Diff line number Diff line Loading @@ -59,6 +59,8 @@ import javax.sip.SipException; */ public final class SipService extends ISipService.Stub { private static final String TAG = "SipService"; private static final boolean DEBUG = true; private static final boolean DEBUG_TIMER = DEBUG && false; private static final int EXPIRY_TIME = 3600; private static final int SHORT_EXPIRY_TIME = 10; private static final int MIN_EXPIRY_TIME = 60; Loading Loading @@ -90,7 +92,7 @@ public final class SipService extends ISipService.Stub { } private SipService(Context context) { Log.v(TAG, " service started!"); if (DEBUG) Log.d(TAG, " service started!"); mContext = context; mConnectivityReceiver = new ConnectivityReceiver(); context.registerReceiver(mConnectivityReceiver, Loading Loading @@ -137,7 +139,7 @@ public final class SipService extends ISipService.Stub { throw new RuntimeException( "empty broadcast action for incoming call"); } Log.v(TAG, "open3: " + localProfile.getUriString() + ": " if (DEBUG) Log.d(TAG, "open3: " + localProfile.getUriString() + ": " + incomingCallBroadcastAction + ": " + listener); try { SipSessionGroupExt group = createGroup(localProfile, Loading Loading @@ -238,14 +240,14 @@ public final class SipService extends ISipService.Stub { } private void notifyProfileAdded(SipProfile localProfile) { Log.d(TAG, "notify: profile added: " + localProfile); if (DEBUG) Log.d(TAG, "notify: profile added: " + localProfile); Intent intent = new Intent(SipManager.SIP_ADD_PHONE_ACTION); intent.putExtra(SipManager.LOCAL_URI_KEY, localProfile.getUriString()); mContext.sendBroadcast(intent); } private void notifyProfileRemoved(SipProfile localProfile) { Log.d(TAG, "notify: profile removed: " + localProfile); if (DEBUG) Log.d(TAG, "notify: profile removed: " + localProfile); Intent intent = new Intent(SipManager.SIP_REMOVE_PHONE_ACTION); intent.putExtra(SipManager.LOCAL_URI_KEY, localProfile.getUriString()); mContext.sendBroadcast(intent); Loading @@ -260,7 +262,7 @@ public final class SipService extends ISipService.Stub { private void grabWifiLock() { if (mWifiLock == null) { Log.v(TAG, "acquire wifi lock"); if (DEBUG) Log.d(TAG, "acquire wifi lock"); mWifiLock = ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE)) .createWifiLock(WifiManager.WIFI_MODE_FULL, TAG); Loading @@ -270,7 +272,7 @@ public final class SipService extends ISipService.Stub { private void releaseWifiLock() { if (mWifiLock != null) { Log.v(TAG, "release wifi lock"); if (DEBUG) Log.d(TAG, "release wifi lock"); mWifiLock.release(); mWifiLock = null; } Loading @@ -283,7 +285,7 @@ public final class SipService extends ISipService.Stub { private synchronized void onConnectivityChanged( String type, boolean connected) { Log.v(TAG, "onConnectivityChanged(): " if (DEBUG) Log.d(TAG, "onConnectivityChanged(): " + mNetworkType + (mConnected? " CONNECTED" : " DISCONNECTED") + " --> " + type + (connected? " CONNECTED" : " DISCONNECTED")); Loading Loading @@ -398,7 +400,7 @@ public final class SipService extends ISipService.Stub { mSipGroup.openToReceiveCalls(this); mAutoRegistration.start(mSipGroup); } Log.v(TAG, " openToReceiveCalls: " + getUri() + ": " if (DEBUG) Log.d(TAG, " openToReceiveCalls: " + getUri() + ": " + mIncomingCallBroadcastAction); } Loading @@ -410,8 +412,8 @@ public final class SipService extends ISipService.Stub { if (mOpened) openToReceiveCalls(); } else { // close mSipGroup but remember mOpened Log.v(TAG, " close auto reg temporarily: " + getUri() + ": " + mIncomingCallBroadcastAction); if (DEBUG) Log.d(TAG, " close auto reg temporarily: " + getUri() + ": " + mIncomingCallBroadcastAction); mSipGroup.close(); mAutoRegistration.stop(); } Loading @@ -437,7 +439,7 @@ public final class SipService extends ISipService.Stub { mOpened = false; mSipGroup.closeToNotReceiveCalls(); mAutoRegistration.stop(); Log.v(TAG, " close: " + getUri() + ": " if (DEBUG) Log.d(TAG, " close: " + getUri() + ": " + mIncomingCallBroadcastAction); } Loading @@ -456,13 +458,13 @@ public final class SipService extends ISipService.Stub { } // send out incoming call broadcast Log.d(TAG, " ringing~~ " + getUri() + ": " + caller.getUri() + ": " + session.getCallId()); addPendingSession(session); Intent intent = SipManager.createIncomingCallBroadcast( mIncomingCallBroadcastAction, session.getCallId(), sessionDescription); Log.d(TAG, " send out intent: " + intent); if (DEBUG) Log.d(TAG, " ringing~~ " + getUri() + ": " + caller.getUri() + ": " + session.getCallId() + " " + mIncomingCallBroadcastAction); mContext.sendBroadcast(intent); } catch (RemoteException e) { // should never happen with a local call Loading @@ -474,7 +476,8 @@ public final class SipService extends ISipService.Stub { @Override public void onError(ISipSession session, String errorClass, String message) { Log.v(TAG, "sip session error: " + errorClass + ": " + message); if (DEBUG) Log.d(TAG, "sip session error: " + errorClass + ": " + message); } public boolean isOpened() { Loading Loading @@ -506,7 +509,7 @@ public final class SipService extends ISipService.Stub { public void run() { synchronized (SipService.this) { SipSessionGroup.SipSessionImpl session = mSession.duplicate(); Log.d(TAG, " ~~~ keepalive"); if (DEBUG) Log.d(TAG, "~~~ keepalive"); mTimer.cancel(this); session.sendKeepAlive(); if (session.isReRegisterRequired()) { Loading Loading @@ -549,7 +552,7 @@ public final class SipService extends ISipService.Stub { // TODO: when rfc5626 is deployed, use reg-id and sip.instance // in registration to avoid adding duplicate entries to server mSession.unregister(); Log.v(TAG, "start AutoRegistrationProcess for " if (DEBUG) Log.d(TAG, "start AutoRegistrationProcess for " + mSession.getLocalProfile().getUriString()); } } Loading Loading @@ -581,7 +584,6 @@ public final class SipService extends ISipService.Stub { } public void setListener(ISipSessionListener listener) { Log.v(TAG, "setListener(): " + listener); synchronized (SipService.this) { mProxy.setListener(listener); if (mSession == null) return; Loading Loading @@ -619,7 +621,7 @@ public final class SipService extends ISipService.Stub { public void run() { mErrorCode = null; mErrorMessage = null; Log.v(TAG, " ~~~ registering"); if (DEBUG) Log.d(TAG, "~~~ registering"); synchronized (SipService.this) { if (mConnected && !isStopped()) mSession.register(EXPIRY_TIME); } Loading @@ -642,7 +644,7 @@ public final class SipService extends ISipService.Stub { } private void restart(int duration) { Log.v(TAG, "Refresh registration " + duration + "s later."); if (DEBUG) Log.d(TAG, "Refresh registration " + duration + "s later."); mTimer.cancel(this); mTimer.set(duration * 1000, this); } Loading @@ -659,7 +661,7 @@ public final class SipService extends ISipService.Stub { @Override public void onRegistering(ISipSession session) { Log.v(TAG, "onRegistering(): " + session + ": " + mSession); if (DEBUG) Log.d(TAG, "onRegistering(): " + session); synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; mRegistered = false; Loading @@ -669,7 +671,7 @@ public final class SipService extends ISipService.Stub { @Override public void onRegistrationDone(ISipSession session, int duration) { Log.v(TAG, "onRegistrationDone(): " + session + ": " + mSession); if (DEBUG) Log.d(TAG, "onRegistrationDone(): " + session); synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; Loading Loading @@ -703,7 +705,7 @@ public final class SipService extends ISipService.Stub { } else { mRegistered = false; mExpiryTime = -1L; Log.v(TAG, "Refresh registration immediately"); if (DEBUG) Log.d(TAG, "Refresh registration immediately"); run(); } } Loading @@ -714,8 +716,8 @@ public final class SipService extends ISipService.Stub { String errorCodeString, String message) { SipErrorCode errorCode = Enum.valueOf(SipErrorCode.class, errorCodeString); Log.v(TAG, "onRegistrationFailed(): " + session + ": " + mSession + ": " + errorCode + ": " + message); if (DEBUG) Log.d(TAG, "onRegistrationFailed(): " + session + ": " + errorCode + ": " + message); synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; mErrorCode = errorCode; Loading @@ -724,7 +726,7 @@ public final class SipService extends ISipService.Stub { message); if (errorCode == SipErrorCode.INVALID_CREDENTIALS) { Log.d(TAG, " pause auto-registration"); if (DEBUG) Log.d(TAG, " pause auto-registration"); stopButKeepStates(); } else if (!isStopped()) { onError(); Loading @@ -734,7 +736,7 @@ public final class SipService extends ISipService.Stub { @Override public void onRegistrationTimeout(ISipSession session) { Log.v(TAG, "onRegistrationTimeout(): " + session + ": " + mSession); if (DEBUG) Log.d(TAG, "onRegistrationTimeout(): " + session); synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; mErrorCode = SipErrorCode.TIME_OUT; Loading Loading @@ -773,30 +775,33 @@ public final class SipService extends ISipService.Stub { NetworkInfo.State state = netInfo.getState(); NetworkInfo activeNetInfo = getActiveNetworkInfo(); if (DEBUG) { if (activeNetInfo != null) { Log.v(TAG, "active network: " + activeNetInfo.getTypeName() Log.d(TAG, "active network: " + activeNetInfo.getTypeName() + ((activeNetInfo.getState() == NetworkInfo.State.CONNECTED) ? " CONNECTED" : " DISCONNECTED")); } else { Log.v(TAG, "active network: null"); Log.d(TAG, "active network: null"); } } if ((state == NetworkInfo.State.CONNECTED) && (activeNetInfo != null) && (activeNetInfo.getType() != netInfo.getType())) { Log.d(TAG, "ignore connect event: " + type if (DEBUG) Log.d(TAG, "ignore connect event: " + type + ", active: " + activeNetInfo.getTypeName()); return; } if (state == NetworkInfo.State.CONNECTED) { Log.v(TAG, "Connectivity alert: CONNECTED " + type); if (DEBUG) Log.d(TAG, "Connectivity alert: CONNECTED " + type); onChanged(type, true); } else if (state == NetworkInfo.State.DISCONNECTED) { Log.v(TAG, "Connectivity alert: DISCONNECTED " + type); if (DEBUG) Log.d(TAG, "Connectivity alert: DISCONNECTED " + type); onChanged(type, false); } else { Log.d(TAG, "Connectivity alert not processed: " + state + " " + type); if (DEBUG) Log.d(TAG, "Connectivity alert not processed: " + state + " " + type); } } } Loading Loading @@ -847,7 +852,7 @@ public final class SipService extends ISipService.Stub { return; } mTask = null; Log.v(TAG, " deliver change for " + mNetworkType if (DEBUG) Log.d(TAG, " deliver change for " + mNetworkType + (mConnected ? " CONNECTED" : "DISCONNECTED")); onConnectivityChanged(mNetworkType, mConnected); } Loading Loading @@ -929,9 +934,11 @@ public final class SipService extends ISipService.Stub { newQueue.addAll((Collection<MyEvent>) mEventQueue); mEventQueue.clear(); mEventQueue = newQueue; Log.v(TAG, "queue re-calculated"); if (DEBUG_TIMER) { Log.d(TAG, "queue re-calculated"); printQueue(); } } // Determines the period and the trigger time of the new event and insert it // to the queue. Loading Loading @@ -984,11 +991,13 @@ public final class SipService extends ISipService.Stub { } long triggerTime = event.mTriggerTime; Log.v(TAG, " add event " + event + " scheduled at " if (DEBUG_TIMER) { Log.d(TAG, " add event " + event + " scheduled at " + showTime(triggerTime) + " at " + showTime(now) + ", #events=" + mEventQueue.size()); printQueue(); } } /** * Cancels all the timer events with the specified callback. Loading @@ -997,7 +1006,7 @@ public final class SipService extends ISipService.Stub { */ public synchronized void cancel(Runnable callback) { if (stopped() || mEventQueue.isEmpty()) return; Log.d(TAG, "cancel:" + callback); if (DEBUG_TIMER) Log.d(TAG, "cancel:" + callback); MyEvent firstEvent = mEventQueue.first(); for (Iterator<MyEvent> iter = mEventQueue.iterator(); Loading @@ -1005,7 +1014,7 @@ public final class SipService extends ISipService.Stub { MyEvent event = iter.next(); if (event.mCallback == callback) { iter.remove(); Log.d(TAG, " cancel found:" + event); if (DEBUG_TIMER) Log.d(TAG, " cancel found:" + event); } } if (mEventQueue.isEmpty()) { Loading @@ -1019,9 +1028,11 @@ public final class SipService extends ISipService.Stub { recalculatePeriods(); scheduleNext(); } if (DEBUG_TIMER) { Log.d(TAG, "after cancel:"); printQueue(); } } private void scheduleNext() { if (stopped() || mEventQueue.isEmpty()) return; Loading Loading @@ -1069,13 +1080,13 @@ public final class SipService extends ISipService.Stub { } private void execute(long triggerTime) { Log.d(TAG, "time's up, triggerTime = " + showTime(triggerTime) + ": " + mEventQueue.size()); if (DEBUG_TIMER) Log.d(TAG, "time's up, triggerTime = " + showTime(triggerTime) + ": " + mEventQueue.size()); if (stopped() || mEventQueue.isEmpty()) return; for (MyEvent event : mEventQueue) { if (event.mTriggerTime != triggerTime) break; Log.d(TAG, "execute " + event); if (DEBUG_TIMER) Log.d(TAG, "execute " + event); event.mLastTriggerTime = event.mTriggerTime; event.mTriggerTime += event.mPeriod; Loading @@ -1083,8 +1094,10 @@ public final class SipService extends ISipService.Stub { // run the callback in a new thread to prevent deadlock new Thread(event.mCallback).start(); } if (DEBUG_TIMER) { Log.d(TAG, "after timeout execution"); printQueue(); } scheduleNext(); } Loading services/java/com/android/server/sip/SipSessionGroup.java +59 −23 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ import javax.sip.message.Response; */ class SipSessionGroup implements SipListener { private static final String TAG = "SipSession"; private static final boolean DEBUG = true; private static final boolean DEBUG_PING = DEBUG && false; private static final String ANONYMOUS = "anonymous"; private static final String SERVER_ERROR_PREFIX = "Response: "; private static final int EXPIRY_TIME = 3600; Loading Loading @@ -218,22 +220,26 @@ class SipSessionGroup implements SipListener { private synchronized SipSessionImpl getSipSession(EventObject event) { String key = SipHelper.getCallId(event); Log.d(TAG, "sesssion key from event: " + key); SipSessionImpl session = mSessionMap.get(key); if ((session != null) && isLoggable(session)) { Log.d(TAG, "session key from event: " + key); Log.d(TAG, "active sessions:"); for (String k : mSessionMap.keySet()) { Log.d(TAG, " ..." + k + ": " + mSessionMap.get(k)); } SipSessionImpl session = mSessionMap.get(key); } return ((session != null) ? session : mCallReceiverSession); } private synchronized void addSipSession(SipSessionImpl newSession) { removeSipSession(newSession); String key = newSession.getCallId(); Log.d(TAG, "+++ add a session with key: '" + key + "'"); mSessionMap.put(key, newSession); if (isLoggable(newSession)) { Log.d(TAG, "+++ add a session with key: '" + key + "'"); for (String k : mSessionMap.keySet()) { Log.d(TAG, " ..... " + k + ": " + mSessionMap.get(k)); Log.d(TAG, " " + k + ": " + mSessionMap.get(k)); } } } Loading @@ -254,10 +260,12 @@ class SipSessionGroup implements SipListener { } } } Log.d(TAG, " remove session " + session + " with key '" + key + "'"); if ((s != null) && isLoggable(s)) { Log.d(TAG, "remove session " + session + " @key '" + key + "'"); for (String k : mSessionMap.keySet()) { Log.d(TAG, " ..... " + k + ": " + mSessionMap.get(k)); Log.d(TAG, " " + k + ": " + mSessionMap.get(k)); } } } Loading Loading @@ -288,10 +296,10 @@ class SipSessionGroup implements SipListener { private synchronized void process(EventObject event) { SipSessionImpl session = getSipSession(event); try { if ((session != null) && session.process(event)) { Log.d(TAG, " ~~~~~ new state: " + session.mState); } else { Log.d(TAG, "event not processed: " + event); boolean isLoggable = isLoggable(session, event); boolean processed = (session != null) && session.process(event); if (isLoggable && processed) { Log.d(TAG, "new state after: " + session.mState); } } catch (Throwable e) { Log.w(TAG, "event process error: " + event, e); Loading Loading @@ -321,8 +329,8 @@ class SipSessionGroup implements SipListener { } public boolean process(EventObject evt) throws SipException { Log.d(TAG, " ~~~~~ " + this + ": " + mState + ": processing " + log(evt)); if (isLoggable(this, evt)) Log.d(TAG, " ~~~~~ " + this + ": " + mState + ": processing " + log(evt)); if (isRequestEvent(Request.INVITE, evt)) { RequestEvent event = (RequestEvent) evt; SipSessionImpl newSession = new SipSessionImpl(mProxy); Loading Loading @@ -503,8 +511,8 @@ class SipSessionGroup implements SipListener { } public boolean process(EventObject evt) throws SipException { Log.d(TAG, " ~~~~~ " + this + ": " + mState + ": processing " + log(evt)); if (isLoggable(this, evt)) Log.d(TAG, " ~~~~~ " + this + ": " + mState + ": processing " + log(evt)); synchronized (SipSessionGroup.this) { if (isClosed()) return false; Loading Loading @@ -672,14 +680,14 @@ class SipSessionGroup implements SipListener { if (mRPort == 0) mRPort = rPort; if (mRPort != rPort) { mReRegisterFlag = true; Log.w(TAG, String.format("rport is changed: %d <> %d", mRPort, rPort)); if (DEBUG) Log.w(TAG, String.format( "rport is changed: %d <> %d", mRPort, rPort)); mRPort = rPort; } else { Log.w(TAG, "rport is the same: " + rPort); if (DEBUG_PING) Log.w(TAG, "rport is the same: " + rPort); } } else { Log.w(TAG, "peer did not respect our rport request"); if (DEBUG) Log.w(TAG, "peer did not respond rport"); } reset(); return true; Loading Loading @@ -1188,6 +1196,34 @@ class SipSessionGroup implements SipListener { } } private static boolean isLoggable(SipSessionImpl s) { if (s != null) { switch (s.mState) { case PINGING: return DEBUG_PING; } } return DEBUG; } private static boolean isLoggable(SipSessionImpl s, EventObject evt) { if (!isLoggable(s)) return false; if (evt == null) return false; if (evt instanceof OptionsCommand) { return DEBUG_PING; } else if (evt instanceof ResponseEvent) { Response response = ((ResponseEvent) evt).getResponse(); if (Request.OPTIONS.equals(response.getHeader(CSeqHeader.NAME))) { return DEBUG_PING; } return DEBUG; } else if (evt instanceof RequestEvent) { return DEBUG; } return false; } private static String log(EventObject evt) { if (evt instanceof RequestEvent) { return ((RequestEvent) evt).getRequest().toString(); Loading Loading
services/java/com/android/server/sip/SipHelper.java +20 −7 Original line number Diff line number Diff line Loading @@ -68,6 +68,7 @@ import javax.sip.message.Response; */ class SipHelper { private static final String TAG = SipHelper.class.getSimpleName(); private static final boolean DEBUG = true; private SipStack mSipStack; private SipProvider mSipProvider; Loading Loading @@ -264,6 +265,7 @@ class SipHelper { ClientTransaction clientTransaction = mSipProvider.getNewClientTransaction(request); if (DEBUG) Log.d(TAG, "send INVITE: " + request); clientTransaction.sendRequest(); return clientTransaction; } catch (ParseException e) { Loading @@ -281,6 +283,7 @@ class SipHelper { ClientTransaction clientTransaction = mSipProvider.getNewClientTransaction(request); if (DEBUG) Log.d(TAG, "send RE-INVITE: " + request); dialog.sendRequest(clientTransaction); return clientTransaction; } catch (ParseException e) { Loading Loading @@ -314,6 +317,7 @@ class SipHelper { ToHeader toHeader = (ToHeader) response.getHeader(ToHeader.NAME); toHeader.setTag(tag); response.addHeader(toHeader); if (DEBUG) Log.d(TAG, "send RINGING: " + response); transaction.sendResponse(response); return transaction; } catch (ParseException e) { Loading @@ -340,7 +344,9 @@ class SipHelper { if (inviteTransaction == null) { inviteTransaction = getServerTransaction(event); } if (inviteTransaction.getState() != TransactionState.COMPLETED) { if (DEBUG) Log.d(TAG, "send OK: " + response); inviteTransaction.sendResponse(response); } Loading @@ -358,6 +364,7 @@ class SipHelper { Response.BUSY_HERE, request); if (inviteTransaction.getState() != TransactionState.COMPLETED) { if (DEBUG) Log.d(TAG, "send BUSY HERE: " + response); inviteTransaction.sendResponse(response); } } catch (ParseException e) { Loading @@ -373,27 +380,31 @@ class SipHelper { Response response = event.getResponse(); long cseq = ((CSeqHeader) response.getHeader(CSeqHeader.NAME)) .getSeqNumber(); dialog.sendAck(dialog.createAck(cseq)); Request ack = dialog.createAck(cseq); if (DEBUG) Log.d(TAG, "send ACK: " + ack); dialog.sendAck(ack); } public void sendBye(Dialog dialog) throws SipException { Request byeRequest = dialog.createRequest(Request.BYE); Log.d(TAG, "send BYE: " + byeRequest); if (DEBUG) Log.d(TAG, "send BYE: " + byeRequest); dialog.sendRequest(mSipProvider.getNewClientTransaction(byeRequest)); } public void sendCancel(ClientTransaction inviteTransaction) throws SipException { Request cancelRequest = inviteTransaction.createCancel(); if (DEBUG) Log.d(TAG, "send CANCEL: " + cancelRequest); mSipProvider.getNewClientTransaction(cancelRequest).sendRequest(); } public void sendResponse(RequestEvent event, int responseCode) throws SipException { try { getServerTransaction(event).sendResponse( mMessageFactory.createResponse( responseCode, event.getRequest())); Response response = mMessageFactory.createResponse( responseCode, event.getRequest()); if (DEBUG) Log.d(TAG, "send response: " + response); getServerTransaction(event).sendResponse(response); } catch (ParseException e) { throw new SipException("sendResponse()", e); } Loading @@ -402,8 +413,10 @@ class SipHelper { public void sendInviteRequestTerminated(Request inviteRequest, ServerTransaction inviteTransaction) throws SipException { try { inviteTransaction.sendResponse(mMessageFactory.createResponse( Response.REQUEST_TERMINATED, inviteRequest)); Response response = mMessageFactory.createResponse( Response.REQUEST_TERMINATED, inviteRequest); if (DEBUG) Log.d(TAG, "send response: " + response); inviteTransaction.sendResponse(response); } catch (ParseException e) { throw new SipException("sendInviteRequestTerminated()", e); } Loading
services/java/com/android/server/sip/SipService.java +67 −54 Original line number Diff line number Diff line Loading @@ -59,6 +59,8 @@ import javax.sip.SipException; */ public final class SipService extends ISipService.Stub { private static final String TAG = "SipService"; private static final boolean DEBUG = true; private static final boolean DEBUG_TIMER = DEBUG && false; private static final int EXPIRY_TIME = 3600; private static final int SHORT_EXPIRY_TIME = 10; private static final int MIN_EXPIRY_TIME = 60; Loading Loading @@ -90,7 +92,7 @@ public final class SipService extends ISipService.Stub { } private SipService(Context context) { Log.v(TAG, " service started!"); if (DEBUG) Log.d(TAG, " service started!"); mContext = context; mConnectivityReceiver = new ConnectivityReceiver(); context.registerReceiver(mConnectivityReceiver, Loading Loading @@ -137,7 +139,7 @@ public final class SipService extends ISipService.Stub { throw new RuntimeException( "empty broadcast action for incoming call"); } Log.v(TAG, "open3: " + localProfile.getUriString() + ": " if (DEBUG) Log.d(TAG, "open3: " + localProfile.getUriString() + ": " + incomingCallBroadcastAction + ": " + listener); try { SipSessionGroupExt group = createGroup(localProfile, Loading Loading @@ -238,14 +240,14 @@ public final class SipService extends ISipService.Stub { } private void notifyProfileAdded(SipProfile localProfile) { Log.d(TAG, "notify: profile added: " + localProfile); if (DEBUG) Log.d(TAG, "notify: profile added: " + localProfile); Intent intent = new Intent(SipManager.SIP_ADD_PHONE_ACTION); intent.putExtra(SipManager.LOCAL_URI_KEY, localProfile.getUriString()); mContext.sendBroadcast(intent); } private void notifyProfileRemoved(SipProfile localProfile) { Log.d(TAG, "notify: profile removed: " + localProfile); if (DEBUG) Log.d(TAG, "notify: profile removed: " + localProfile); Intent intent = new Intent(SipManager.SIP_REMOVE_PHONE_ACTION); intent.putExtra(SipManager.LOCAL_URI_KEY, localProfile.getUriString()); mContext.sendBroadcast(intent); Loading @@ -260,7 +262,7 @@ public final class SipService extends ISipService.Stub { private void grabWifiLock() { if (mWifiLock == null) { Log.v(TAG, "acquire wifi lock"); if (DEBUG) Log.d(TAG, "acquire wifi lock"); mWifiLock = ((WifiManager) mContext.getSystemService(Context.WIFI_SERVICE)) .createWifiLock(WifiManager.WIFI_MODE_FULL, TAG); Loading @@ -270,7 +272,7 @@ public final class SipService extends ISipService.Stub { private void releaseWifiLock() { if (mWifiLock != null) { Log.v(TAG, "release wifi lock"); if (DEBUG) Log.d(TAG, "release wifi lock"); mWifiLock.release(); mWifiLock = null; } Loading @@ -283,7 +285,7 @@ public final class SipService extends ISipService.Stub { private synchronized void onConnectivityChanged( String type, boolean connected) { Log.v(TAG, "onConnectivityChanged(): " if (DEBUG) Log.d(TAG, "onConnectivityChanged(): " + mNetworkType + (mConnected? " CONNECTED" : " DISCONNECTED") + " --> " + type + (connected? " CONNECTED" : " DISCONNECTED")); Loading Loading @@ -398,7 +400,7 @@ public final class SipService extends ISipService.Stub { mSipGroup.openToReceiveCalls(this); mAutoRegistration.start(mSipGroup); } Log.v(TAG, " openToReceiveCalls: " + getUri() + ": " if (DEBUG) Log.d(TAG, " openToReceiveCalls: " + getUri() + ": " + mIncomingCallBroadcastAction); } Loading @@ -410,8 +412,8 @@ public final class SipService extends ISipService.Stub { if (mOpened) openToReceiveCalls(); } else { // close mSipGroup but remember mOpened Log.v(TAG, " close auto reg temporarily: " + getUri() + ": " + mIncomingCallBroadcastAction); if (DEBUG) Log.d(TAG, " close auto reg temporarily: " + getUri() + ": " + mIncomingCallBroadcastAction); mSipGroup.close(); mAutoRegistration.stop(); } Loading @@ -437,7 +439,7 @@ public final class SipService extends ISipService.Stub { mOpened = false; mSipGroup.closeToNotReceiveCalls(); mAutoRegistration.stop(); Log.v(TAG, " close: " + getUri() + ": " if (DEBUG) Log.d(TAG, " close: " + getUri() + ": " + mIncomingCallBroadcastAction); } Loading @@ -456,13 +458,13 @@ public final class SipService extends ISipService.Stub { } // send out incoming call broadcast Log.d(TAG, " ringing~~ " + getUri() + ": " + caller.getUri() + ": " + session.getCallId()); addPendingSession(session); Intent intent = SipManager.createIncomingCallBroadcast( mIncomingCallBroadcastAction, session.getCallId(), sessionDescription); Log.d(TAG, " send out intent: " + intent); if (DEBUG) Log.d(TAG, " ringing~~ " + getUri() + ": " + caller.getUri() + ": " + session.getCallId() + " " + mIncomingCallBroadcastAction); mContext.sendBroadcast(intent); } catch (RemoteException e) { // should never happen with a local call Loading @@ -474,7 +476,8 @@ public final class SipService extends ISipService.Stub { @Override public void onError(ISipSession session, String errorClass, String message) { Log.v(TAG, "sip session error: " + errorClass + ": " + message); if (DEBUG) Log.d(TAG, "sip session error: " + errorClass + ": " + message); } public boolean isOpened() { Loading Loading @@ -506,7 +509,7 @@ public final class SipService extends ISipService.Stub { public void run() { synchronized (SipService.this) { SipSessionGroup.SipSessionImpl session = mSession.duplicate(); Log.d(TAG, " ~~~ keepalive"); if (DEBUG) Log.d(TAG, "~~~ keepalive"); mTimer.cancel(this); session.sendKeepAlive(); if (session.isReRegisterRequired()) { Loading Loading @@ -549,7 +552,7 @@ public final class SipService extends ISipService.Stub { // TODO: when rfc5626 is deployed, use reg-id and sip.instance // in registration to avoid adding duplicate entries to server mSession.unregister(); Log.v(TAG, "start AutoRegistrationProcess for " if (DEBUG) Log.d(TAG, "start AutoRegistrationProcess for " + mSession.getLocalProfile().getUriString()); } } Loading Loading @@ -581,7 +584,6 @@ public final class SipService extends ISipService.Stub { } public void setListener(ISipSessionListener listener) { Log.v(TAG, "setListener(): " + listener); synchronized (SipService.this) { mProxy.setListener(listener); if (mSession == null) return; Loading Loading @@ -619,7 +621,7 @@ public final class SipService extends ISipService.Stub { public void run() { mErrorCode = null; mErrorMessage = null; Log.v(TAG, " ~~~ registering"); if (DEBUG) Log.d(TAG, "~~~ registering"); synchronized (SipService.this) { if (mConnected && !isStopped()) mSession.register(EXPIRY_TIME); } Loading @@ -642,7 +644,7 @@ public final class SipService extends ISipService.Stub { } private void restart(int duration) { Log.v(TAG, "Refresh registration " + duration + "s later."); if (DEBUG) Log.d(TAG, "Refresh registration " + duration + "s later."); mTimer.cancel(this); mTimer.set(duration * 1000, this); } Loading @@ -659,7 +661,7 @@ public final class SipService extends ISipService.Stub { @Override public void onRegistering(ISipSession session) { Log.v(TAG, "onRegistering(): " + session + ": " + mSession); if (DEBUG) Log.d(TAG, "onRegistering(): " + session); synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; mRegistered = false; Loading @@ -669,7 +671,7 @@ public final class SipService extends ISipService.Stub { @Override public void onRegistrationDone(ISipSession session, int duration) { Log.v(TAG, "onRegistrationDone(): " + session + ": " + mSession); if (DEBUG) Log.d(TAG, "onRegistrationDone(): " + session); synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; Loading Loading @@ -703,7 +705,7 @@ public final class SipService extends ISipService.Stub { } else { mRegistered = false; mExpiryTime = -1L; Log.v(TAG, "Refresh registration immediately"); if (DEBUG) Log.d(TAG, "Refresh registration immediately"); run(); } } Loading @@ -714,8 +716,8 @@ public final class SipService extends ISipService.Stub { String errorCodeString, String message) { SipErrorCode errorCode = Enum.valueOf(SipErrorCode.class, errorCodeString); Log.v(TAG, "onRegistrationFailed(): " + session + ": " + mSession + ": " + errorCode + ": " + message); if (DEBUG) Log.d(TAG, "onRegistrationFailed(): " + session + ": " + errorCode + ": " + message); synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; mErrorCode = errorCode; Loading @@ -724,7 +726,7 @@ public final class SipService extends ISipService.Stub { message); if (errorCode == SipErrorCode.INVALID_CREDENTIALS) { Log.d(TAG, " pause auto-registration"); if (DEBUG) Log.d(TAG, " pause auto-registration"); stopButKeepStates(); } else if (!isStopped()) { onError(); Loading @@ -734,7 +736,7 @@ public final class SipService extends ISipService.Stub { @Override public void onRegistrationTimeout(ISipSession session) { Log.v(TAG, "onRegistrationTimeout(): " + session + ": " + mSession); if (DEBUG) Log.d(TAG, "onRegistrationTimeout(): " + session); synchronized (SipService.this) { if (!isStopped() && (session != mSession)) return; mErrorCode = SipErrorCode.TIME_OUT; Loading Loading @@ -773,30 +775,33 @@ public final class SipService extends ISipService.Stub { NetworkInfo.State state = netInfo.getState(); NetworkInfo activeNetInfo = getActiveNetworkInfo(); if (DEBUG) { if (activeNetInfo != null) { Log.v(TAG, "active network: " + activeNetInfo.getTypeName() Log.d(TAG, "active network: " + activeNetInfo.getTypeName() + ((activeNetInfo.getState() == NetworkInfo.State.CONNECTED) ? " CONNECTED" : " DISCONNECTED")); } else { Log.v(TAG, "active network: null"); Log.d(TAG, "active network: null"); } } if ((state == NetworkInfo.State.CONNECTED) && (activeNetInfo != null) && (activeNetInfo.getType() != netInfo.getType())) { Log.d(TAG, "ignore connect event: " + type if (DEBUG) Log.d(TAG, "ignore connect event: " + type + ", active: " + activeNetInfo.getTypeName()); return; } if (state == NetworkInfo.State.CONNECTED) { Log.v(TAG, "Connectivity alert: CONNECTED " + type); if (DEBUG) Log.d(TAG, "Connectivity alert: CONNECTED " + type); onChanged(type, true); } else if (state == NetworkInfo.State.DISCONNECTED) { Log.v(TAG, "Connectivity alert: DISCONNECTED " + type); if (DEBUG) Log.d(TAG, "Connectivity alert: DISCONNECTED " + type); onChanged(type, false); } else { Log.d(TAG, "Connectivity alert not processed: " + state + " " + type); if (DEBUG) Log.d(TAG, "Connectivity alert not processed: " + state + " " + type); } } } Loading Loading @@ -847,7 +852,7 @@ public final class SipService extends ISipService.Stub { return; } mTask = null; Log.v(TAG, " deliver change for " + mNetworkType if (DEBUG) Log.d(TAG, " deliver change for " + mNetworkType + (mConnected ? " CONNECTED" : "DISCONNECTED")); onConnectivityChanged(mNetworkType, mConnected); } Loading Loading @@ -929,9 +934,11 @@ public final class SipService extends ISipService.Stub { newQueue.addAll((Collection<MyEvent>) mEventQueue); mEventQueue.clear(); mEventQueue = newQueue; Log.v(TAG, "queue re-calculated"); if (DEBUG_TIMER) { Log.d(TAG, "queue re-calculated"); printQueue(); } } // Determines the period and the trigger time of the new event and insert it // to the queue. Loading Loading @@ -984,11 +991,13 @@ public final class SipService extends ISipService.Stub { } long triggerTime = event.mTriggerTime; Log.v(TAG, " add event " + event + " scheduled at " if (DEBUG_TIMER) { Log.d(TAG, " add event " + event + " scheduled at " + showTime(triggerTime) + " at " + showTime(now) + ", #events=" + mEventQueue.size()); printQueue(); } } /** * Cancels all the timer events with the specified callback. Loading @@ -997,7 +1006,7 @@ public final class SipService extends ISipService.Stub { */ public synchronized void cancel(Runnable callback) { if (stopped() || mEventQueue.isEmpty()) return; Log.d(TAG, "cancel:" + callback); if (DEBUG_TIMER) Log.d(TAG, "cancel:" + callback); MyEvent firstEvent = mEventQueue.first(); for (Iterator<MyEvent> iter = mEventQueue.iterator(); Loading @@ -1005,7 +1014,7 @@ public final class SipService extends ISipService.Stub { MyEvent event = iter.next(); if (event.mCallback == callback) { iter.remove(); Log.d(TAG, " cancel found:" + event); if (DEBUG_TIMER) Log.d(TAG, " cancel found:" + event); } } if (mEventQueue.isEmpty()) { Loading @@ -1019,9 +1028,11 @@ public final class SipService extends ISipService.Stub { recalculatePeriods(); scheduleNext(); } if (DEBUG_TIMER) { Log.d(TAG, "after cancel:"); printQueue(); } } private void scheduleNext() { if (stopped() || mEventQueue.isEmpty()) return; Loading Loading @@ -1069,13 +1080,13 @@ public final class SipService extends ISipService.Stub { } private void execute(long triggerTime) { Log.d(TAG, "time's up, triggerTime = " + showTime(triggerTime) + ": " + mEventQueue.size()); if (DEBUG_TIMER) Log.d(TAG, "time's up, triggerTime = " + showTime(triggerTime) + ": " + mEventQueue.size()); if (stopped() || mEventQueue.isEmpty()) return; for (MyEvent event : mEventQueue) { if (event.mTriggerTime != triggerTime) break; Log.d(TAG, "execute " + event); if (DEBUG_TIMER) Log.d(TAG, "execute " + event); event.mLastTriggerTime = event.mTriggerTime; event.mTriggerTime += event.mPeriod; Loading @@ -1083,8 +1094,10 @@ public final class SipService extends ISipService.Stub { // run the callback in a new thread to prevent deadlock new Thread(event.mCallback).start(); } if (DEBUG_TIMER) { Log.d(TAG, "after timeout execution"); printQueue(); } scheduleNext(); } Loading
services/java/com/android/server/sip/SipSessionGroup.java +59 −23 Original line number Diff line number Diff line Loading @@ -80,6 +80,8 @@ import javax.sip.message.Response; */ class SipSessionGroup implements SipListener { private static final String TAG = "SipSession"; private static final boolean DEBUG = true; private static final boolean DEBUG_PING = DEBUG && false; private static final String ANONYMOUS = "anonymous"; private static final String SERVER_ERROR_PREFIX = "Response: "; private static final int EXPIRY_TIME = 3600; Loading Loading @@ -218,22 +220,26 @@ class SipSessionGroup implements SipListener { private synchronized SipSessionImpl getSipSession(EventObject event) { String key = SipHelper.getCallId(event); Log.d(TAG, "sesssion key from event: " + key); SipSessionImpl session = mSessionMap.get(key); if ((session != null) && isLoggable(session)) { Log.d(TAG, "session key from event: " + key); Log.d(TAG, "active sessions:"); for (String k : mSessionMap.keySet()) { Log.d(TAG, " ..." + k + ": " + mSessionMap.get(k)); } SipSessionImpl session = mSessionMap.get(key); } return ((session != null) ? session : mCallReceiverSession); } private synchronized void addSipSession(SipSessionImpl newSession) { removeSipSession(newSession); String key = newSession.getCallId(); Log.d(TAG, "+++ add a session with key: '" + key + "'"); mSessionMap.put(key, newSession); if (isLoggable(newSession)) { Log.d(TAG, "+++ add a session with key: '" + key + "'"); for (String k : mSessionMap.keySet()) { Log.d(TAG, " ..... " + k + ": " + mSessionMap.get(k)); Log.d(TAG, " " + k + ": " + mSessionMap.get(k)); } } } Loading @@ -254,10 +260,12 @@ class SipSessionGroup implements SipListener { } } } Log.d(TAG, " remove session " + session + " with key '" + key + "'"); if ((s != null) && isLoggable(s)) { Log.d(TAG, "remove session " + session + " @key '" + key + "'"); for (String k : mSessionMap.keySet()) { Log.d(TAG, " ..... " + k + ": " + mSessionMap.get(k)); Log.d(TAG, " " + k + ": " + mSessionMap.get(k)); } } } Loading Loading @@ -288,10 +296,10 @@ class SipSessionGroup implements SipListener { private synchronized void process(EventObject event) { SipSessionImpl session = getSipSession(event); try { if ((session != null) && session.process(event)) { Log.d(TAG, " ~~~~~ new state: " + session.mState); } else { Log.d(TAG, "event not processed: " + event); boolean isLoggable = isLoggable(session, event); boolean processed = (session != null) && session.process(event); if (isLoggable && processed) { Log.d(TAG, "new state after: " + session.mState); } } catch (Throwable e) { Log.w(TAG, "event process error: " + event, e); Loading Loading @@ -321,8 +329,8 @@ class SipSessionGroup implements SipListener { } public boolean process(EventObject evt) throws SipException { Log.d(TAG, " ~~~~~ " + this + ": " + mState + ": processing " + log(evt)); if (isLoggable(this, evt)) Log.d(TAG, " ~~~~~ " + this + ": " + mState + ": processing " + log(evt)); if (isRequestEvent(Request.INVITE, evt)) { RequestEvent event = (RequestEvent) evt; SipSessionImpl newSession = new SipSessionImpl(mProxy); Loading Loading @@ -503,8 +511,8 @@ class SipSessionGroup implements SipListener { } public boolean process(EventObject evt) throws SipException { Log.d(TAG, " ~~~~~ " + this + ": " + mState + ": processing " + log(evt)); if (isLoggable(this, evt)) Log.d(TAG, " ~~~~~ " + this + ": " + mState + ": processing " + log(evt)); synchronized (SipSessionGroup.this) { if (isClosed()) return false; Loading Loading @@ -672,14 +680,14 @@ class SipSessionGroup implements SipListener { if (mRPort == 0) mRPort = rPort; if (mRPort != rPort) { mReRegisterFlag = true; Log.w(TAG, String.format("rport is changed: %d <> %d", mRPort, rPort)); if (DEBUG) Log.w(TAG, String.format( "rport is changed: %d <> %d", mRPort, rPort)); mRPort = rPort; } else { Log.w(TAG, "rport is the same: " + rPort); if (DEBUG_PING) Log.w(TAG, "rport is the same: " + rPort); } } else { Log.w(TAG, "peer did not respect our rport request"); if (DEBUG) Log.w(TAG, "peer did not respond rport"); } reset(); return true; Loading Loading @@ -1188,6 +1196,34 @@ class SipSessionGroup implements SipListener { } } private static boolean isLoggable(SipSessionImpl s) { if (s != null) { switch (s.mState) { case PINGING: return DEBUG_PING; } } return DEBUG; } private static boolean isLoggable(SipSessionImpl s, EventObject evt) { if (!isLoggable(s)) return false; if (evt == null) return false; if (evt instanceof OptionsCommand) { return DEBUG_PING; } else if (evt instanceof ResponseEvent) { Response response = ((ResponseEvent) evt).getResponse(); if (Request.OPTIONS.equals(response.getHeader(CSeqHeader.NAME))) { return DEBUG_PING; } return DEBUG; } else if (evt instanceof RequestEvent) { return DEBUG; } return false; } private static String log(EventObject evt) { if (evt instanceof RequestEvent) { return ((RequestEvent) evt).getRequest().toString(); Loading