Optional tunnel plugin.

Requires a tunnel implementation with Android.mk in
submodules/linphone/tunnel
This commit is contained in:
Guillaume Beraudo 2011-12-16 10:59:32 +01:00
parent 6933cbe329
commit 420698d3b4
15 changed files with 199 additions and 18 deletions

1
README
View file

@ -19,6 +19,7 @@ BUILD_X264 0 (don't build x264) or 1 (build x264)
BUILD_AMR 0 (don't build amr codec), light (try to use amr codec from android), full (build your own amr codec) BUILD_AMR 0 (don't build amr codec), light (try to use amr codec from android), full (build your own amr codec)
BUILD_GPLV3_ZRTP 0 (don't support ZRTP), 1 (support ZRTP and make the whole program GPLv3) BUILD_GPLV3_ZRTP 0 (don't support ZRTP), 1 (support ZRTP and make the whole program GPLv3)
BUILD_SILK 0 (don't build silk plugin), 1 (build silk) [silk is Skype nonfree patented audio codec] BUILD_SILK 0 (don't build silk plugin), 1 (build silk) [silk is Skype nonfree patented audio codec]
BUILD_TUNNEL 0 (don't build tunnel), 1 (build tunnel) [requires a tunnel implementation in submodules/linphone/tunnel]
In order to use ZRTP you also need to define the media_encryption property to In order to use ZRTP you also need to define the media_encryption property to
"zrtp" in the sip section of linphonerc file. "zrtp" in the sip section of linphonerc file.

View file

@ -63,6 +63,10 @@ include $(linphone-root-dir)/submodules/linphone/mediastreamer2/build/android/An
include $(linphone-root-dir)/submodules/linphone/mediastreamer2/tests/Android.mk include $(linphone-root-dir)/submodules/linphone/mediastreamer2/tests/Android.mk
ifeq ($(BUILD_TUNNEL), 1)
include $(linphone-root-dir)/submodules/linphone/tunnel/Android.mk
endif
ifeq ($(BUILD_SILK), 1) ifeq ($(BUILD_SILK), 1)
$(info Build proprietary SILK plugin for mediastreamer2) $(info Build proprietary SILK plugin for mediastreamer2)
include $(linphone-root-dir)/submodules/mssilk/Android.mk include $(linphone-root-dir)/submodules/mssilk/Android.mk

View file

@ -2,10 +2,6 @@ APP_PROJECT_PATH := $(call my-dir)/../
APP_MODULES :=libspeex libgsm libortp libosip2 libeXosip2 libmediastreamer2 liblinphone APP_MODULES :=libspeex libgsm libortp libosip2 libeXosip2 libmediastreamer2 liblinphone
APP_STL := stlport_static APP_STL := stlport_static
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
APP_MODULES +=libmsilbc
endif
ifeq ($(LINPHONE_VIDEO),1) ifeq ($(LINPHONE_VIDEO),1)
APP_MODULES += libavutil libavcore libavcodec libswscale libvpx APP_MODULES += libavutil libavcore libavcodec libswscale libvpx
endif endif
@ -14,10 +10,6 @@ ifeq ($(BUILD_AMR),1)
APP_MODULES += libopencoreamr libmsamr APP_MODULES += libopencoreamr libmsamr
endif endif
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
APP_MODULES += liblincrypto liblinssl
endif
ifeq ($(BUILD_X264),1) ifeq ($(BUILD_X264),1)
APP_MODULES +=libx264 libmsx264 APP_MODULES +=libx264 libmsx264
endif endif
@ -30,7 +22,14 @@ ifeq ($(RING),yes)
APP_MODULES += libring APP_MODULES += libring
endif endif
ifeq ($(BUILD_TUNNEL), 1)
APP_MODULES += libtunnelclient
endif
ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
APP_MODULES += liblincrypto liblinssl
APP_MODULES +=libmsilbc
ifeq ($(BUILD_GPLV3_ZRTP), 1) ifeq ($(BUILD_GPLV3_ZRTP), 1)
APP_MODULES += libzrtpcpp APP_MODULES += libzrtpcpp
endif endif
@ -38,12 +37,13 @@ endif
ifeq ($(BUILD_SRTP), 1) ifeq ($(BUILD_SRTP), 1)
APP_MODULES += libsrtp APP_MODULES += libsrtp
endif endif
endif endif #armeabi-v7a
linphone-root-dir:=$(APP_PROJECT_PATH) linphone-root-dir:=$(APP_PROJECT_PATH)
APP_BUILD_SCRIPT:=$(call my-dir)/Android.mk APP_BUILD_SCRIPT:=$(call my-dir)/Android.mk
APP_PLATFORM := android-8 APP_PLATFORM := android-8
#APP_ABI := armeabi-v7a #APP_ABI := armeabi
APP_ABI := armeabi-v7a armeabi APP_ABI := armeabi-v7a armeabi
APP_CFLAGS:=-DDISABLE_NEON APP_CFLAGS:=-DDISABLE_NEON

View file

@ -8,5 +8,8 @@
<string name="notification_registered">Registered to %s </string> <string name="notification_registered">Registered to %s </string>
<string name="notification_register_failure">Fails to register to %s</string> <string name="notification_register_failure">Fails to register to %s</string>
<string name="about_text">Linphone %s SIP (rfc 3261) compatible phone under GNU Public License V2\n http://www.linphone.org\n\nInstructions\nhttp://www.linphone.org/m/help\n\n© 2011 Belledonne Communications</string> <string name="about_text">Linphone %s SIP (rfc 3261) compatible phone under GNU Public License V2\n http://www.linphone.org\n\nInstructions\nhttp://www.linphone.org/m/help\n\n© 2011 Belledonne Communications</string>
<string name="tunnel_host"></string>
<string name="default_tunnel_mode_entry_value">@string/tunnel_mode_entry_value_disabled</string>
</resources> </resources>

View file

@ -1,5 +1,21 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<!-- Do not translate any of the strings below -->
<string name="pref_tunnel_key">pref_tunnel_key</string>
<string name="pref_tunnel_mode_key">pref_tunnel_mode_key</string>
<string name="tunnel_mode_entry_value_disabled">disabled</string>
<string name="tunnel_mode_entry_value_3G_only">3G_only</string>
<string name="tunnel_mode_entry_value_always">always</string>
<string-array name="tunnel_mode_entry_values">
<item>@string/tunnel_mode_entry_value_disabled</item>
<item >@string/tunnel_mode_entry_value_3G_only</item>
<item>@string/tunnel_mode_entry_value_always</item>
<item>@string/tunnel_mode_entry_value_auto</item>
</string-array>
<string name="pref_tunnel_host_key">pref_tunnel_host_key</string>
<string name="pref_tunnel_port_key">pref_tunnel_port_key</string>
<string name="tunnel_mode_entry_value_auto">auto</string>
<string name="pref_audio_use_specific_mode_key">pref_audio_use_specific_mode_key</string> <string name="pref_audio_use_specific_mode_key">pref_audio_use_specific_mode_key</string>
<string name="pref_audio_hacks_use_galaxys_hack_key">pref_audio_hacks_use_galaxys_hack_key</string> <string name="pref_audio_hacks_use_galaxys_hack_key">pref_audio_hacks_use_galaxys_hack_key</string>

View file

@ -1,6 +1,19 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<resources> <resources>
<string name="pref_tunnel">Tunnel</string>
<string name="pref_tunnel_host">Hostname</string>
<string name="pref_tunnel_port">Port</string>
<string name="pref_tunnel_mode">Mode</string>
<!-- do not change order without changing corresponding entry_values in non_localizable_strings.xml -->
<string-array name="tunnel_mode_entries">
<item>disabled</item>
<item>3G only</item>
<item>always</item>
<item>auto</item>
</string-array>
<string name="incall_notif_active">Audio call ongoing</string> <string name="incall_notif_active">Audio call ongoing</string>
<string name="incall_notif_paused">Paused call ongoing</string> <string name="incall_notif_paused">Paused call ongoing</string>
<string name="incall_notif_video">Video capturing call ongoing</string> <string name="incall_notif_video">Video capturing call ongoing</string>

View file

@ -21,6 +21,19 @@
</PreferenceCategory> </PreferenceCategory>
<PreferenceCategory android:key="@string/pref_tunnel_key" android:title="@string/pref_tunnel">
<EditTextPreference android:title="@string/pref_tunnel_host"
android:key="@string/pref_tunnel_host_key"/>
<EditTextPreference android:title="@string/pref_tunnel_port"
android:key="@string/pref_tunnel_port_key" android:defaultValue="443"/>
<ListPreference android:title="@string/pref_tunnel_mode"
android:entries="@array/tunnel_mode_entries"
android:entryValues="@array/tunnel_mode_entry_values"
android:defaultValue="@string/default_tunnel_mode_entry_value"
android:key="@string/pref_tunnel_mode_key" />
</PreferenceCategory>

View file

@ -403,6 +403,47 @@ public final class LinphoneManager implements LinphoneCoreListener {
} }
} }
private boolean isTunnelNeeded(NetworkInfo info) {
if (info == null) {
Log.i("No connectivity: tunnel should be disabled");
return false;
}
String pref = getPrefString(R.string.pref_tunnel_mode_key, R.string.default_tunnel_mode_entry_value);
if (getString(R.string.tunnel_mode_entry_value_always).equals(pref)) {
return true;
}
if (info.getType() != ConnectivityManager.TYPE_WIFI
&& getString(R.string.tunnel_mode_entry_value_3G_only).equals(pref)) {
Log.i("need tunnel: 'no wifi' connection");
return true;
}
return false;
}
public void manageTunnelServer(NetworkInfo info) {
if (mLc == null) return;
if (!mLc.isTunnelAvailable()) return;
Log.i("Managing tunnel");
if (isTunnelNeeded(info)) {
Log.i("Tunnel need to be activated");
mLc.tunnelEnable(true);
} else {
Log.i("Tunnel should not be used");
String pref = getPrefString(R.string.pref_tunnel_mode_key, R.string.default_tunnel_mode_entry_value);
mLc.tunnelEnable(false);
if (getString(R.string.tunnel_mode_entry_value_auto).equals(pref)) {
mLc.tunnelAutoDetect();
}
}
}
private synchronized void startLibLinphone() { private synchronized void startLibLinphone() {
try { try {
copyAssetsFromPackage(); copyAssetsFromPackage();
@ -484,7 +525,7 @@ public final class LinphoneManager implements LinphoneCoreListener {
void initMediaEncryption(){ void initMediaEncryption(){
String pref = getPrefString(R.string.pref_media_encryption_key, String pref = getPrefString(R.string.pref_media_encryption_key,
getString(R.string.pref_media_encryption_key_none)); R.string.pref_media_encryption_key_none);
MediaEncryption me=MediaEncryption.None; MediaEncryption me=MediaEncryption.None;
if (pref.equals(getString(R.string.pref_media_encryption_key_srtp))) if (pref.equals(getString(R.string.pref_media_encryption_key_srtp)))
me=MediaEncryption.SRTP; me=MediaEncryption.SRTP;
@ -494,11 +535,26 @@ public final class LinphoneManager implements LinphoneCoreListener {
mLc.setMediaEncryption(me); mLc.setMediaEncryption(me);
} }
private void initFromConfTunnel(){
if (!mLc.isTunnelAvailable()) return;
NetworkInfo info = mConnectivityManager.getActiveNetworkInfo();
mLc.tunnelEnableLogs(getPrefBoolean(R.string.pref_debug_key, false));
mLc.tunnelCleanServers();
String host = getString(R.string.tunnel_host);
if (host == null || host.length() == 0)
host = mPref.getString(getString(R.string.pref_tunnel_host_key), "");
int port = Integer.parseInt(getPrefString(R.string.pref_tunnel_port_key, "443"));
mLc.tunnelAddServerAndMirror(host, port, 12345,500);
manageTunnelServer(info);
}
public void initFromConf() throws LinphoneConfigException { public void initFromConf() throws LinphoneConfigException {
//traces //traces
boolean lIsDebug = true;//mPref.getBoolean(getString(R.string.pref_debug_key), false); boolean lIsDebug = true;//mPref.getBoolean(getString(R.string.pref_debug_key), false);
LinphoneCoreFactory.instance().setDebugMode(lIsDebug); LinphoneCoreFactory.instance().setDebugMode(lIsDebug);
initFromConfTunnel();
if (initialTransports == null) if (initialTransports == null)
initialTransports = mLc.getSignalingTransportPorts(); initialTransports = mLc.getSignalingTransportPorts();
@ -713,9 +769,32 @@ public final class LinphoneManager implements LinphoneCoreListener {
private String getPrefString(int key, String value) { private String getPrefString(int key, String value) {
return mPref.getString(mR.getString(key), value); return mPref.getString(mR.getString(key), value);
} }
private String getPrefString(int key, int value) {
return mPref.getString(mR.getString(key), mR.getString(value));
}
/* Simple implementation as Android way seems very complicate:
For example: with wifi and mobile actives; when pulling mobile down:
I/Linphone( 8397): WIFI connected: setting network reachable
I/Linphone( 8397): new state [RegistrationProgress]
I/Linphone( 8397): mobile disconnected: setting network unreachable
I/Linphone( 8397): Managing tunnel
I/Linphone( 8397): WIFI connected: setting network reachable
*/
public void connectivityChanged(NetworkInfo eventInfo, ConnectivityManager cm) {
NetworkInfo activeInfo = cm.getActiveNetworkInfo();
if (eventInfo.getState() == NetworkInfo.State.DISCONNECTED) {
Log.i(eventInfo.getTypeName()," disconnected: setting network unreachable");
mLc.setNetworkReachable(false);
} else if (eventInfo.getState() == NetworkInfo.State.CONNECTED){
manageTunnelServer(activeInfo);
Log.i(eventInfo.getTypeName()," connected: setting network reachable");
mLc.setNetworkReachable(true);
}
}

View file

@ -52,6 +52,7 @@ import android.preference.CheckBoxPreference;
import android.preference.ListPreference; import android.preference.ListPreference;
import android.preference.Preference; import android.preference.Preference;
import android.preference.PreferenceActivity; import android.preference.PreferenceActivity;
import android.preference.PreferenceCategory;
import android.preference.Preference.OnPreferenceChangeListener; import android.preference.Preference.OnPreferenceChangeListener;
import android.preference.Preference.OnPreferenceClickListener; import android.preference.Preference.OnPreferenceClickListener;
@ -144,6 +145,15 @@ public class LinphonePreferencesActivity extends PreferenceActivity implements E
if (Hacks.needSoftvolume()) checkAndDisableCheckbox(R.string.pref_audio_soft_volume_key); if (Hacks.needSoftvolume()) checkAndDisableCheckbox(R.string.pref_audio_soft_volume_key);
if (!LinphoneManager.getLc().isTunnelAvailable()){
hidePreferenceCategory(R.string.pref_tunnel_key);
}
}
private void hidePreferenceCategory(int key) {
PreferenceCategory p = (PreferenceCategory) findPreference(key);
p.removeAll();
p.setLayoutResource(R.layout.hidden);
} }
private void doOnFirstLaunch() { private void doOnFirstLaunch() {

View file

@ -414,7 +414,7 @@ public final class LinphoneService extends Service implements LinphoneServiceLis
sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered); sendNotification(IC_LEVEL_ORANGE, R.string.notification_registered);
} }
if (state == RegistrationState.RegistrationFailed) { if (state == RegistrationState.RegistrationFailed || state == RegistrationState.RegistrationCleared) {
sendNotification(IC_LEVEL_OFFLINE, R.string.notification_register_failure); sendNotification(IC_LEVEL_OFFLINE, R.string.notification_register_failure);
} }

View file

@ -56,6 +56,10 @@ public class NetworkManager extends BroadcastReceiver {
} else { } else {
// Other unhandled events // Other unhandled events
} }
NetworkInfo eventInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
LinphoneManager.getInstance().connectivityChanged(eventInfo, cm);
} }
} }

View file

@ -49,6 +49,9 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory {
loadOptionalLibrary("srtp"); loadOptionalLibrary("srtp");
loadOptionalLibrary("zrtpcpp"); // GPLv3+ loadOptionalLibrary("zrtpcpp"); // GPLv3+
// Tunnel
loadOptionalLibrary("tunnelclient");
//Main library //Main library
System.loadLibrary("linphone"); System.loadLibrary("linphone");

View file

@ -617,8 +617,43 @@ class LinphoneCoreImpl implements LinphoneCore {
} }
private native void setPlayFile(long nativePtr, String path); private native void setPlayFile(long nativePtr, String path);
@Override @Override
public void setPlayFile(String path) { public void setPlayFile(String path) {
setPlayFile(nativePtr, path); setPlayFile(nativePtr, path);
} }
private native void tunnelAddServerAndMirror(long nativePtr, String host, int port, int mirror, int ms);
@Override
public void tunnelAddServerAndMirror(String host, int port, int mirror, int ms) {
tunnelAddServerAndMirror(nativePtr, host, port, mirror, ms);
}
private native void tunnelAutoDetect(long nativePtr);
@Override
public void tunnelAutoDetect() {
tunnelAutoDetect(nativePtr);
}
private native void tunnelCleanServers(long nativePtr);
@Override
public void tunnelCleanServers() {
tunnelCleanServers(nativePtr);
}
private native void tunnelEnable(long nativePtr, boolean enable);
@Override
public void tunnelEnable(boolean enable) {
tunnelEnable(nativePtr, enable);
}
private native void tunnelEnableLogs(long nativePtr, boolean enable);
@Override
public void tunnelEnableLogs(boolean enable) {
tunnelEnableLogs(nativePtr, enable);
}
@Override
public native boolean isTunnelAvailable();
} }

@ -1 +1 @@
Subproject commit 4eabd05b149d18629098f3254f15c8d14ff6664c Subproject commit c3da0303519ad3120355cb85baee9cf6d0e4d1c2

@ -1 +1 @@
Subproject commit 75e7426eb68e6fdbaae229e05fe11398172fec7e Subproject commit 886d80bb6d8ac916d6cc0cf635ce25e82ff1f051