Commit 4e26b6a5 authored by Ming Rui Zhang's avatar Ming Rui Zhang Committed by Sébastien Blin

peerdiscovery: add functionality of discovering Jami Account

Change-Id: Iee3572c7f0fa9b35ed9eb8db19e642a28d4ef981
Reviewed-by: Sébastien Blin's avatarSébastien Blin <sebastien.blin@savoirfairelinux.com>
parent 680d27e6
......@@ -130,6 +130,33 @@
</arg>
</signal>
<signal name="nearbyPeerNotification" tp:name-for-bindings="nearbyPeerNotification">
<tp:added version="1.3.0"/>
<tp:docstring>
Notify when a new local peer is discovered
</tp:docstring>
<arg type="s" name="accountID">
<tp:docstring>
The associated account
</tp:docstring>
</arg>
<arg type="s" name="buddyUri">
<tp:docstring>
The registered URI
</tp:docstring>
</arg>
<arg type="i" name="status">
<tp:docstring>
Is delete or addition
</tp:docstring>
</arg>
<arg type="s" name="displayname">
<tp:docstring>
A string containing informations from the user (human readable)
</tp:docstring>
</arg>
</signal>
<signal name="subscriptionStateChanged" tp:name-for-bindings="subscriptionStateChanged">
<tp:added version="1.3.0"/>
<tp:docstring>
......
......@@ -196,6 +196,7 @@ DBusClient::initLibrary(int flags)
exportable_callback<PresenceSignal::NewServerSubscriptionRequest>(bind(&DBusPresenceManager::newServerSubscriptionRequest, presM, _1)),
exportable_callback<PresenceSignal::ServerError>(bind(&DBusPresenceManager::serverError, presM, _1, _2, _3)),
exportable_callback<PresenceSignal::NewBuddyNotification>(bind(&DBusPresenceManager::newBuddyNotification, presM, _1, _2, _3, _4)),
exportable_callback<PresenceSignal::NearbyPeerNotification>(bind(&DBusPresenceManager::nearbyPeerNotification, presM, _1, _2, _3, _4)),
exportable_callback<PresenceSignal::SubscriptionStateChanged>(bind(&DBusPresenceManager::subscriptionStateChanged, presM, _1, _2, _3)),
};
......
......@@ -89,6 +89,7 @@ getSignalHandlers()
/* Presence */
exported_callback<DRing::PresenceSignal::NewServerSubscriptionRequest>(),
exported_callback<DRing::PresenceSignal::NearbyPeerNotification>(),
exported_callback<DRing::PresenceSignal::ServerError>(),
exported_callback<DRing::PresenceSignal::NewBuddyNotification>(),
exported_callback<DRing::PresenceSignal::SubscriptionStateChanged>(),
......
......@@ -142,6 +142,7 @@ constexpr static const char PROXY_ENABLED [] = "Account.proxyEnabled";
constexpr static const char PROXY_SERVER [] = "Account.proxyServer";
constexpr static const char PROXY_PUSH_TOKEN [] = "Account.proxyPushToken";
constexpr static const char DHT_PEER_DISCOVERY [] = "Account.peerDiscovery";
constexpr static const char ACCOUNT_PEER_DISCOVERY [] = "Account.accountDiscovery";
namespace Audio {
......
......@@ -57,6 +57,10 @@ struct DRING_PUBLIC PresenceSignal {
constexpr static const char* name = "NewBuddyNotification";
using cb_type = void(const std::string& /*account_id*/, const std::string& /*buddy_uri*/, int /*status*/, const std::string& /*line_status*/);
};
struct DRING_PUBLIC NearbyPeerNotification {
constexpr static const char* name = "NearbyPeerNotification";
using cb_type = void(const std::string& /*account_id*/, const std::string& /*buddy_uri*/, int /*state*/, const std::string& /*displayname*/);
};
struct DRING_PUBLIC SubscriptionStateChanged {
constexpr static const char* name = "SubscriptionStateChanged";
using cb_type = void(const std::string& /*account_id*/, const std::string& /*buddy_uri*/, int /*state*/);
......
......@@ -5,6 +5,7 @@
* Author: Guillaume Roguez <guillaume.roguez@savoirfairelinux.com>
* Author: Simon Désaulniers <simon.desaulniers@savoirfairelinux.com>
* Author: Nicolas Jäger <nicolas.jager@savoirfairelinux.com>
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
......@@ -69,6 +70,7 @@
#include "base64.h"
#include <opendht/thread_pool.h>
#include <opendht/peer_discovery.h>
#include <yaml-cpp/yaml.h>
#include <json/json.h>
......@@ -202,6 +204,19 @@ struct JamiAccount::DeviceSync : public dht::EncryptedValue<DeviceSync>
MSGPACK_DEFINE_MAP(date, device_name, devices_known, peers, trust_requests)
};
struct AccountPeerInfo
{
dht::InfoHash accountId;
std::string displayName;
MSGPACK_DEFINE(accountId, displayName)
};
struct JamiAccount::DiscoveredPeer
{
std::string displayName;
std::shared_ptr<Task> cleanupTask;
};
static constexpr int ICE_COMPONENTS {1};
static constexpr int ICE_COMP_SIP_TRANSPORT {0};
static constexpr auto ICE_NEGOTIATION_TIMEOUT = std::chrono::seconds(60);
......@@ -214,6 +229,9 @@ static constexpr const char * DEFAULT_TURN_USERNAME = "ring";
static constexpr const char * DEFAULT_TURN_PWD = "ring";
static constexpr const char * DEFAULT_TURN_REALM = "ring";
static const auto PROXY_REGEX = std::regex("(https?://)?([\\w\\.]+)(:(\\d+)|:\\[(.+)-(.+)\\])?");
static const std::string PEER_DISCOVERY_JAMI_SERVICE = "jami";
const constexpr auto PEER_DISCOVERY_EXPIRATION = std::chrono::minutes(15);
constexpr const char* const JamiAccount::ACCOUNT_TYPE;
/* constexpr */ const std::pair<uint16_t, uint16_t> JamiAccount::DHT_PORT_RANGE {4000, 8888};
......@@ -302,6 +320,10 @@ JamiAccount::~JamiAccount()
eventHandler->cancel();
eventHandler.reset();
}
if(peerDiscovery_){
peerDiscovery_->stopPublish(PEER_DISCOVERY_JAMI_SERVICE);
peerDiscovery_->stopDiscovery(PEER_DISCOVERY_JAMI_SERVICE);
}
dht_.join();
}
......@@ -668,6 +690,7 @@ void JamiAccount::serialize(YAML::Emitter &out) const
out << YAML::Key << Conf::DHT_ALLOW_PEERS_FROM_CONTACT << YAML::Value << allowPeersFromContact_;
out << YAML::Key << Conf::DHT_ALLOW_PEERS_FROM_TRUSTED << YAML::Value << allowPeersFromTrusted_;
out << YAML::Key << DRing::Account::ConfProperties::DHT_PEER_DISCOVERY << YAML::Value << dhtPeerDiscovery_;
out << YAML::Key << DRing::Account::ConfProperties::ACCOUNT_PEER_DISCOVERY << YAML::Value << accountPeerDiscovery_;
out << YAML::Key << Conf::PROXY_ENABLED_KEY << YAML::Value << proxyEnabled_;
out << YAML::Key << Conf::PROXY_SERVER_KEY << YAML::Value << proxyServer_;
......@@ -741,6 +764,7 @@ void JamiAccount::unserialize(const YAML::Node &node)
dhtPortUsed_ = dhtPort_;
parseValueOptional(node, DRing::Account::ConfProperties::DHT_PEER_DISCOVERY, dhtPeerDiscovery_);
parseValueOptional(node, DRing::Account::ConfProperties::ACCOUNT_PEER_DISCOVERY, accountPeerDiscovery_);
#if HAVE_RINGNS
parseValueOptional(node, DRing::Account::ConfProperties::RingNS::URI, nameServer_);
......@@ -1537,6 +1561,7 @@ JamiAccount::setAccountDetails(const std::map<std::string, std::string>& details
parseInt(details, Conf::CONFIG_DHT_PORT, dhtPort_);
parseBool(details, Conf::CONFIG_DHT_PUBLIC_IN_CALLS, dhtPublicInCalls_);
parseBool(details, DRing::Account::ConfProperties::DHT_PEER_DISCOVERY, dhtPeerDiscovery_);
parseBool(details, DRing::Account::ConfProperties::ACCOUNT_PEER_DISCOVERY, accountPeerDiscovery_);
parseBool(details, DRing::Account::ConfProperties::ALLOW_CERT_FROM_HISTORY, allowPeersFromHistory_);
parseBool(details, DRing::Account::ConfProperties::ALLOW_CERT_FROM_CONTACT, allowPeersFromContact_);
parseBool(details, DRing::Account::ConfProperties::ALLOW_CERT_FROM_TRUSTED, allowPeersFromTrusted_);
......@@ -1596,6 +1621,7 @@ JamiAccount::getAccountDetails() const
a.emplace(Conf::CONFIG_DHT_PORT, std::to_string(dhtPort_));
a.emplace(Conf::CONFIG_DHT_PUBLIC_IN_CALLS, dhtPublicInCalls_ ? TRUE_STR : FALSE_STR);
a.emplace(DRing::Account::ConfProperties::DHT_PEER_DISCOVERY, dhtPeerDiscovery_ ? TRUE_STR : FALSE_STR);
a.emplace(DRing::Account::ConfProperties::ACCOUNT_PEER_DISCOVERY, accountPeerDiscovery_ ? TRUE_STR : FALSE_STR);
a.emplace(DRing::Account::ConfProperties::RING_DEVICE_ID, ringDeviceId_);
a.emplace(DRing::Account::ConfProperties::RING_DEVICE_NAME, ringDeviceName_);
a.emplace(DRing::Account::ConfProperties::Presence::SUPPORT_SUBSCRIBE, TRUE_STR);
......@@ -2145,7 +2171,16 @@ JamiAccount::doRegister_()
dht_.setPushNotificationToken(deviceKey_);
}
//check if dht peer service is enabled
if(accountPeerDiscovery_){
peerDiscovery_ = std::make_shared<dht::PeerDiscovery>();
JAMI_INFO("Start Jami account discovering.....");
startAccountDiscovery();
startAccountPublish();
}
dht::DhtRunner::Context context {};
context.peerDiscovery = peerDiscovery_;
auto dht_log_level = Manager::instance().dhtLogLevel.load();
if (dht_log_level > 0) {
static auto silent = [](char const* /*m*/, va_list /*args*/) {};
......@@ -3654,4 +3689,47 @@ JamiAccount::checkPendingCallsTask()
}
}
void
JamiAccount::startAccountPublish()
{
AccountPeerInfo info_pub;
info_pub.accountId = dht::InfoHash(ringAccountId_);
info_pub.displayName = displayName_;
peerDiscovery_->startPublish<AccountPeerInfo>(PEER_DISCOVERY_JAMI_SERVICE, info_pub);
}
void
JamiAccount::startAccountDiscovery()
{
peerDiscovery_->startDiscovery<AccountPeerInfo>(PEER_DISCOVERY_JAMI_SERVICE,[this](AccountPeerInfo&& v, dht::SockAddr&& add){
std::lock_guard<std::mutex> lc(discoveryMapMtx_);
//Make sure that account itself will not be recorded
if(v.accountId != dht::InfoHash(ringAccountId_)){
//Create or Find the old one
auto& dp = discoveredPeers_[v.accountId];
dp.displayName = v.displayName;
if (dp.cleanupTask) {
dp.cleanupTask->cancel();
} else {
//Avoid Repeat Reception of Same peer
JAMI_INFO("Account discovered: %s", v.displayName.c_str());
//Send Added Peer and corrsponding accoundID
emitSignal<DRing::PresenceSignal::NearbyPeerNotification>(getAccountID(), v.accountId.toString(), 0, v.displayName);
}
dp.cleanupTask = Manager::instance().scheduler().scheduleIn([w = weak(), p = v.accountId, a = v.displayName]{
if (auto this_ = w.lock()){
{
std::lock_guard<std::mutex> lc(this_->discoveryMapMtx_);
this_->discoveredPeers_.erase(p);
}
//Send Deleted Peer
emitSignal<DRing::PresenceSignal::NearbyPeerNotification>(this_->getAccountID(), p.toString(), 1, a);
}
JAMI_INFO("Account removed from discovery list: %s", a.c_str());
}, PEER_DISCOVERY_EXPIRATION);
}
});
}
} // namespace jami
......@@ -415,6 +415,7 @@ class JamiAccount : public SIPAccountBase {
struct DeviceAnnouncement;
struct DeviceSync;
struct BuddyInfo;
struct DiscoveredPeer;
void syncDevices();
void onReceiveDeviceSync(DeviceSync&& sync);
......@@ -490,6 +491,16 @@ class JamiAccount : public SIPAccountBase {
void onTrustRequest(const dht::InfoHash& peer_account, const dht::InfoHash& peer_device, time_t received , bool confirm, std::vector<uint8_t>&& payload);
/**
* Start Publish the Jami Account onto the Network
*/
void startAccountPublish();
/**
* Start Discovery the Jami Account from the Network
*/
void startAccountDiscovery();
/**
* Maps require port via UPnP
*/
......@@ -681,6 +692,11 @@ class JamiAccount : public SIPAccountBase {
std::unique_ptr<DhtPeerConnector> dhtPeerConnector_;
std::mutex discoveryMapMtx_;
std::shared_ptr<dht::PeerDiscovery> peerDiscovery_;
std::map<dht::InfoHash, DiscoveredPeer> discoveredPeers_;
bool accountPeerDiscovery_ {true};
std::shared_ptr<RepeatedTask> eventHandler {};
void checkPendingCallsTask();
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment