mirror of
https://github.com/RetroShare/RetroShare.git
synced 2024-10-01 02:35:48 -04:00
Merge pull request #1691 from G10h4ck/fixup_brodcastdiscovery
Fix some bugs in broadcast discovery
This commit is contained in:
commit
584918388c
@ -107,5 +107,45 @@ public:
|
||||
*/
|
||||
virtual std::vector<RsBroadcastDiscoveryResult> getDiscoveredPeers() = 0;
|
||||
|
||||
/**
|
||||
* @brief Check if multicast listening is enabled
|
||||
* @jsonapi{development}
|
||||
* On some platforms such as Android multicast listening, which is needed
|
||||
* for broadcast discovery, is not enabled by default at WiFi driver level
|
||||
* @see enableMulticastListening, so this method check if it is enabled.
|
||||
* On platforms that are not expected to have such a limitation this method
|
||||
* always return true.
|
||||
* @return true if enabled, false otherwise.
|
||||
*/
|
||||
virtual bool isMulticastListeningEnabled() = 0;
|
||||
|
||||
/**
|
||||
* @brief On platforms that need it enable low level multicast listening
|
||||
* @jsonapi{development}
|
||||
* On Android and potencially other mobile platforms, WiFi drivers are
|
||||
* configured by default to discard any packet that is not directed to the
|
||||
* unicast mac address of the interface, this way they could save some
|
||||
* battery but breaks anything that is not unicast, such as broadcast
|
||||
* discovery. On such platforms this method enable low level multicast
|
||||
* listening so we can receive advertisement from same broadcast domain
|
||||
* nodes.
|
||||
* On platforms without such limitation does nothing and always return
|
||||
* false.
|
||||
* It is exposed as a public API so the UI can decide the right equilibrium
|
||||
* between discoverability and battery saving.
|
||||
* @return true if multicast listening has been enabled due to this call,
|
||||
* false otherwise.
|
||||
*/
|
||||
virtual bool enableMulticastListening() = 0;
|
||||
|
||||
/**
|
||||
* @brief Disable multicast listening
|
||||
* @jsonapi{development}
|
||||
* The opposite of @see enableMulticastListening.
|
||||
* @return true if multicast listening has been disabled due to this call,
|
||||
* false otherwise.
|
||||
*/
|
||||
virtual bool disableMulticastListening() = 0;
|
||||
|
||||
virtual ~RsBroadcastDiscovery();
|
||||
};
|
||||
|
@ -25,6 +25,10 @@
|
||||
#include <vector>
|
||||
#include <iostream>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
# include <QtAndroid>
|
||||
#endif // def __ANDROID__
|
||||
|
||||
#include "services/broadcastdiscoveryservice.h"
|
||||
#include "retroshare/rspeers.h"
|
||||
#include "serialiser/rsserializable.h"
|
||||
@ -94,6 +98,12 @@ BroadcastDiscoveryService::BroadcastDiscoveryService(
|
||||
{
|
||||
if(mRsPeers.isHiddenNode(mRsPeers.getOwnId())) return;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
createMulticastLock();
|
||||
#endif // def __ANDROID__
|
||||
|
||||
enableMulticastListening();
|
||||
|
||||
mUdcParameters.set_can_discover(true);
|
||||
mUdcParameters.set_can_be_discovered(true);
|
||||
mUdcParameters.set_port(port);
|
||||
@ -104,7 +114,10 @@ BroadcastDiscoveryService::BroadcastDiscoveryService(
|
||||
}
|
||||
|
||||
BroadcastDiscoveryService::~BroadcastDiscoveryService()
|
||||
{ mUdcPeer.Stop(true); }
|
||||
{
|
||||
mUdcPeer.Stop(true);
|
||||
disableMulticastListening();
|
||||
}
|
||||
|
||||
std::vector<RsBroadcastDiscoveryResult>
|
||||
BroadcastDiscoveryService::getDiscoveredPeers()
|
||||
@ -192,6 +205,7 @@ RsBroadcastDiscoveryResult BroadcastDiscoveryService::createResult(
|
||||
BroadcastDiscoveryPack::fromSerializedString(uData);
|
||||
|
||||
RsBroadcastDiscoveryResult rbdr;
|
||||
rbdr.mPgpFingerprint = bdp.mPgpFingerprint;
|
||||
rbdr.mSslId = bdp.mSslId;
|
||||
rbdr.mProfileName = bdp.mProfileName;
|
||||
rbdr.mLocator.
|
||||
@ -202,6 +216,95 @@ RsBroadcastDiscoveryResult BroadcastDiscoveryService::createResult(
|
||||
return rbdr;
|
||||
}
|
||||
|
||||
bool BroadcastDiscoveryService::isMulticastListeningEnabled()
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
return assertMulticastLockIsvalid() &&
|
||||
mWifiMulticastLock.callMethod<jboolean>("isHeld");
|
||||
#endif // def __ANDROID__
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BroadcastDiscoveryService::enableMulticastListening()
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
if(assertMulticastLockIsvalid() && !isMulticastListeningEnabled())
|
||||
{
|
||||
mWifiMulticastLock.callMethod<void>("acquire");
|
||||
return true;
|
||||
}
|
||||
#endif // def __ANDROID__
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool BroadcastDiscoveryService::disableMulticastListening()
|
||||
{
|
||||
#ifdef __ANDROID__
|
||||
if(assertMulticastLockIsvalid() && isMulticastListeningEnabled())
|
||||
{
|
||||
mWifiMulticastLock.callMethod<void>("release");
|
||||
return true;
|
||||
}
|
||||
#endif // def __ANDROID__
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool BroadcastDiscoveryService::createMulticastLock()
|
||||
{
|
||||
Dbg2() << __PRETTY_FUNCTION__ << std::endl;
|
||||
|
||||
constexpr auto fname = __PRETTY_FUNCTION__;
|
||||
const auto failure = [&](const std::string& err)
|
||||
{
|
||||
RsErr() << fname << " " << err << std::endl;
|
||||
return false;
|
||||
};
|
||||
|
||||
if(mWifiMulticastLock.isValid())
|
||||
return failure("mWifiMulticastLock is already initialized");
|
||||
|
||||
QAndroidJniObject context = QtAndroid::androidContext();
|
||||
if(!context.isValid())
|
||||
return failure("Cannot retrieve Android context");
|
||||
|
||||
QAndroidJniObject WIFI_SERVICE = QAndroidJniObject::getStaticObjectField(
|
||||
"android.content.Context", "WIFI_SERVICE", "Ljava/lang/String;");
|
||||
if(!WIFI_SERVICE.isValid())
|
||||
return failure("Cannot retrieve Context.WIFI_SERVICE value");
|
||||
|
||||
QAndroidJniObject wifiManager = context.callObjectMethod(
|
||||
"getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;",
|
||||
WIFI_SERVICE.object<jstring>() );
|
||||
if(!wifiManager.isValid())
|
||||
return failure("Cannot retrieve Android Wifi Manager");
|
||||
|
||||
mWifiMulticastLock = wifiManager.callObjectMethod(
|
||||
"createMulticastLock",
|
||||
"(Ljava/lang/String;)Landroid/net/wifi/WifiManager$MulticastLock;",
|
||||
QAndroidJniObject::fromString(fname).object<jstring>() );
|
||||
if(!mWifiMulticastLock.isValid())
|
||||
return failure("Cannot create WifiManager.MulticastLock");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool BroadcastDiscoveryService::assertMulticastLockIsvalid()
|
||||
{
|
||||
if(!mWifiMulticastLock.isValid())
|
||||
{
|
||||
RsErr() << __PRETTY_FUNCTION__ << " mWifiMulticastLock is invalid!"
|
||||
<< std::endl;
|
||||
print_stacktrace();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
#endif // def __ANDROID__
|
||||
|
||||
RsBroadcastDiscovery::~RsBroadcastDiscovery() = default;
|
||||
RsBroadcastDiscoveryResult::~RsBroadcastDiscoveryResult() = default;
|
||||
RsBroadcastDiscoveryPeerFoundEvent::~RsBroadcastDiscoveryPeerFoundEvent() = default;
|
||||
|
@ -27,8 +27,13 @@
|
||||
|
||||
#include <udp_discovery_peer.hpp>
|
||||
|
||||
#ifdef __ANDROID__
|
||||
# include <QtAndroidExtras/QAndroidJniObject>
|
||||
#endif // def __ANDROID__
|
||||
|
||||
#include "retroshare/rsbroadcastdiscovery.h"
|
||||
#include "util/rsthreads.h"
|
||||
#include "util/rsdebug.h"
|
||||
|
||||
namespace UDC = udpdiscovery;
|
||||
class RsPeers;
|
||||
@ -37,13 +42,21 @@ class BroadcastDiscoveryService :
|
||||
public RsBroadcastDiscovery, public RsTickingThread
|
||||
{
|
||||
public:
|
||||
// TODO: std::shared_ptr<RsPeers> mRsPeers;
|
||||
BroadcastDiscoveryService(RsPeers& pRsPeers);
|
||||
virtual ~BroadcastDiscoveryService() override;
|
||||
~BroadcastDiscoveryService() override;
|
||||
|
||||
/// @see RsBroadcastDiscovery
|
||||
std::vector<RsBroadcastDiscoveryResult> getDiscoveredPeers() override;
|
||||
|
||||
/// @see RsBroadcastDiscovery
|
||||
bool isMulticastListeningEnabled() override;
|
||||
|
||||
/// @see RsBroadcastDiscovery
|
||||
bool enableMulticastListening() override;
|
||||
|
||||
/// @see RsBroadcastDiscovery
|
||||
bool disableMulticastListening() override;
|
||||
|
||||
/// @see RsTickingThread
|
||||
void data_tick() override;
|
||||
|
||||
@ -63,4 +76,22 @@ protected:
|
||||
|
||||
RsBroadcastDiscoveryResult createResult(
|
||||
const UDC::IpPort& ipp, const std::string& uData );
|
||||
|
||||
#ifdef __ANDROID__
|
||||
/** Android WifiManager.MulticastLock */
|
||||
QAndroidJniObject mWifiMulticastLock;
|
||||
|
||||
/** Initialize the wifi multicast lock without acquiring it
|
||||
* Needed to enable multicast listening in Android, for RetroShare broadcast
|
||||
* discovery inspired by:
|
||||
* https://github.com/flutter/flutter/issues/16335#issuecomment-420547860
|
||||
*/
|
||||
bool createMulticastLock();
|
||||
|
||||
/** Return false if mWifiMulticastLock is invalid and print error messages */
|
||||
bool assertMulticastLockIsvalid();
|
||||
|
||||
#endif // def __ANDROID__
|
||||
|
||||
RS_SET_CONTEXT_DEBUG_LEVEL(3)
|
||||
};
|
||||
|
@ -85,4 +85,8 @@
|
||||
<!-- Added by G10h4ck: Needed permission for network usage -->
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<!-- Added by G10h4ck: Needed to listen for multicast packets, needed for
|
||||
! broadcast discovery -->
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
|
||||
</manifest>
|
||||
|
Loading…
Reference in New Issue
Block a user