From bd2294204e3edaede3fe81eb9b11c05c4fafe627 Mon Sep 17 00:00:00 2001 From: Chung-yih Wang Date: Thu, 23 Sep 2010 23:23:11 +0800 Subject: [PATCH] Fix the unhold issue especially if one is behind NAT. +call startAudio() when call is established. Change-Id: Ib6a1e34017fb83007ce275da1991058e8b803833 --- .../internal/telephony/sip/SipPhone.java | 13 ++++++++- voip/jni/rtp/AudioGroup.cpp | 29 +++++++++++++++++-- 2 files changed, 39 insertions(+), 3 deletions(-) diff --git a/telephony/java/com/android/internal/telephony/sip/SipPhone.java b/telephony/java/com/android/internal/telephony/sip/SipPhone.java index 45e6ccdf17d3f..c0f29937b80c3 100755 --- a/telephony/java/com/android/internal/telephony/sip/SipPhone.java +++ b/telephony/java/com/android/internal/telephony/sip/SipPhone.java @@ -632,6 +632,18 @@ public class SipPhone extends SipPhoneBase { } } + @Override + public void onCallEstablished(SipAudioCall call) { + call.startAudio(); + onChanged(call); + } + + @Override + public void onCallHeld(SipAudioCall call) { + call.startAudio(); + onChanged(call); + } + @Override public void onChanged(SipAudioCall call) { synchronized (SipPhone.class) { @@ -652,7 +664,6 @@ public class SipPhone extends SipPhoneBase { } foregroundCall.switchWith(ringingCall); } - if (newState == Call.State.ACTIVE) call.startAudio(); setState(newState); } mOwner.onConnectionStateChanged(SipConnection.this); diff --git a/voip/jni/rtp/AudioGroup.cpp b/voip/jni/rtp/AudioGroup.cpp index 7cf06137dc757..81d4dfc2c1b91 100644 --- a/voip/jni/rtp/AudioGroup.cpp +++ b/voip/jni/rtp/AudioGroup.cpp @@ -86,6 +86,8 @@ public: void decode(int tick); private: + bool isNatAddress(struct sockaddr_storage *addr); + enum { NORMAL = 0, SEND_ONLY = 1, @@ -316,6 +318,16 @@ void AudioStream::encode(int tick, AudioStream *chain) sizeof(mRemote)); } +bool AudioStream::isNatAddress(struct sockaddr_storage *addr) { + if (addr->ss_family != AF_INET) return false; + struct sockaddr_in *s4 = (struct sockaddr_in *)addr; + unsigned char *d = (unsigned char *) &s4->sin_addr; + if ((d[0] == 10) + || ((d[0] == 172) && (d[1] & 0x10)) + || ((d[0] == 192) && (d[1] == 168))) return true; + return false; +} + void AudioStream::decode(int tick) { char c; @@ -363,8 +375,21 @@ void AudioStream::decode(int tick) MSG_TRUNC | MSG_DONTWAIT) >> 1; } else { __attribute__((aligned(4))) uint8_t buffer[2048]; - length = recv(mSocket, buffer, sizeof(buffer), - MSG_TRUNC | MSG_DONTWAIT); + struct sockaddr_storage src_addr; + socklen_t addrlen; + length = recvfrom(mSocket, buffer, sizeof(buffer), + MSG_TRUNC|MSG_DONTWAIT, (sockaddr*)&src_addr, &addrlen); + + // The following if clause is for fixing the target address if + // proxy server did not replace the NAT address with its media + // port in SDP. Although it is proxy server's responsibility for + // replacing the connection address with correct one, we will change + // the target address as we detect the difference for now until we + // know the best way to get rid of this issue. + if ((memcmp((void*)&src_addr, (void*)&mRemote, addrlen) != 0) && + isNatAddress(&mRemote)) { + memcpy((void*)&mRemote, (void*)&src_addr, addrlen); + } // Do we need to check SSRC, sequence, and timestamp? They are not // reliable but at least they can be used to identify duplicates?