android: use WifiManager.MulticastLock to receive broadcast packets

In many cases, broadcast UDP packets can't be received on android unless
a MulticastLock is held.
This commit is contained in:
Flyinghead 2022-05-12 17:39:49 +02:00
parent cce8cb8528
commit cd22ba1a2b
7 changed files with 43 additions and 1 deletions

View File

@ -91,6 +91,7 @@ bool NaomiNetwork::startNetwork()
if (config::ActAsServer)
{
enableNetworkBroadcast(true);
const auto timeout = seconds(20);
NOTICE_LOG(NETWORK, "Waiting for slave connections");
steady_clock::time_point start_time = steady_clock::now();
@ -110,6 +111,7 @@ bool NaomiNetwork::startNetwork()
break;
std::this_thread::sleep_for(milliseconds(20));
}
enableNetworkBroadcast(false);
if (!slaves.empty())
{
NOTICE_LOG(NETWORK, "Master starting: %zd slaves", slaves.size());

View File

@ -50,6 +50,7 @@ public:
void shutdown()
{
enableNetworkBroadcast(false);
emu.setNetworkState(false);
closesocket(sock);
sock = INVALID_SOCKET;

View File

@ -125,3 +125,9 @@ static inline const char *inet_ntop(int af, const void* src, char* dst, int cnt)
return dst;
}
#endif
#ifdef __ANDROID__
void enableNetworkBroadcast(bool enable);
#else
static inline void enableNetworkBroadcast(bool enable) {}
#endif

View File

@ -90,7 +90,9 @@ struct MaxSpeedNetPipe : public SerialPipe
return true;
}
void shutdown() {
void shutdown()
{
enableNetworkBroadcast(false);
if (VALID(sock))
closesocket(sock);
sock = INVALID_SOCKET;
@ -174,6 +176,7 @@ private:
{
peerAddress.sin_addr.s_addr = addr.sin_addr.s_addr;
peerAddress.sin_port = addr.sin_port;
enableNetworkBroadcast(false);
}
}
}
@ -235,6 +238,8 @@ private:
freeaddrinfo(resultAddr);
}
}
else
enableNetworkBroadcast(true);
serial_setPipe(this);
}

View File

@ -15,6 +15,8 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-feature

View File

@ -3,6 +3,7 @@ package com.reicast.emulator;
import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.net.wifi.WifiManager;
import android.preference.PreferenceManager;
import android.util.Log;
@ -14,6 +15,8 @@ import com.reicast.emulator.emu.JNIdc;
public class Emulator extends Application {
private static Context context;
private static BaseGLActivity currentActivity;
private WifiManager wifiManager = null;
private WifiManager.MulticastLock multicastLock = null;
// see MapleDeviceType in hw/maple/maple_devs.h
public static final int MDT_Microphone = 2;
@ -92,4 +95,20 @@ public class Emulator extends Application {
static {
AppCompatDelegate.setCompatVectorFromResourcesEnabled(true);
}
public void enableNetworkBroadcast(boolean enable) {
if (enable) {
if (wifiManager == null)
wifiManager = (WifiManager)Emulator.context.getSystemService(Context.WIFI_SERVICE);
if (multicastLock == null)
multicastLock = wifiManager.createMulticastLock("Flycast");
if (multicastLock != null && !multicastLock.isHeld())
multicastLock.acquire();
}
else
{
if (multicastLock != null && multicastLock.isHeld())
multicastLock.release();
}
}
}

View File

@ -626,3 +626,10 @@ extern "C" JNIEXPORT void JNICALL Java_com_reicast_emulator_emu_JNIdc_setButtons
memcpy(DefaultOSDButtons.data(), b, len);
env->ReleaseByteArrayElements(data, b, JNI_ABORT);
}
void enableNetworkBroadcast(bool enable)
{
JNIEnv *env = jvm_attacher.getEnv();
jmethodID enableNetworkBroadcastMID = env->GetMethodID(env->GetObjectClass(g_emulator), "enableNetworkBroadcast", "(Z)V");
env->CallVoidMethod(g_emulator, enableNetworkBroadcastMID, enable);
}