|
@@ -30,6 +30,7 @@ using namespace std::placeholders;
|
|
|
|
|
|
using std::function;
|
|
|
using std::shared_ptr;
|
|
|
+using std::weak_ptr;
|
|
|
|
|
|
PeerConnection::PeerConnection() : PeerConnection(Configuration()) {}
|
|
|
|
|
@@ -97,7 +98,7 @@ shared_ptr<DataChannel> PeerConnection::createDataChannel(const string &label,
|
|
|
}
|
|
|
|
|
|
void PeerConnection::onDataChannel(
|
|
|
- std::function<void(std::shared_ptr<DataChannel> dataChannel)> callback) {
|
|
|
+ std::function<void(shared_ptr<DataChannel> dataChannel)> callback) {
|
|
|
mDataChannelCallback = callback;
|
|
|
}
|
|
|
|
|
@@ -120,8 +121,11 @@ void PeerConnection::onGatheringStateChange(std::function<void(GatheringState st
|
|
|
|
|
|
void PeerConnection::initIceTransport(Description::Role role) {
|
|
|
mIceTransport = std::make_shared<IceTransport>(
|
|
|
- mConfig, role, std::bind(&PeerConnection::processLocalCandidate, this, _1),
|
|
|
- [this](IceTransport::State state) {
|
|
|
+ mConfig, role, std::bind(&PeerConnection::processLocalCandidate, this, weak_ptr<PeerConnection>{shared_from_this()}, _1),
|
|
|
+ [this, weak_this = weak_ptr<PeerConnection>{shared_from_this()}](IceTransport::State state) {
|
|
|
+ auto strong_this = weak_this.lock();
|
|
|
+ if (!strong_this) return;
|
|
|
+
|
|
|
switch (state) {
|
|
|
case IceTransport::State::Connecting:
|
|
|
changeState(State::Connecting);
|
|
@@ -137,7 +141,10 @@ void PeerConnection::initIceTransport(Description::Role role) {
|
|
|
break;
|
|
|
}
|
|
|
},
|
|
|
- [this](IceTransport::GatheringState state) {
|
|
|
+ [this, weak_this = weak_ptr<PeerConnection>{shared_from_this()}](IceTransport::GatheringState state) {
|
|
|
+ auto strong_this = weak_this.lock();
|
|
|
+ if (!strong_this) return;
|
|
|
+
|
|
|
switch (state) {
|
|
|
case IceTransport::GatheringState::InProgress:
|
|
|
changeGatheringState(GatheringState::InProgress);
|
|
@@ -156,8 +163,11 @@ void PeerConnection::initIceTransport(Description::Role role) {
|
|
|
|
|
|
void PeerConnection::initDtlsTransport() {
|
|
|
mDtlsTransport = std::make_shared<DtlsTransport>(
|
|
|
- mIceTransport, mCertificate, std::bind(&PeerConnection::checkFingerprint, this, _1),
|
|
|
- [this](DtlsTransport::State state) {
|
|
|
+ mIceTransport, mCertificate, std::bind(&PeerConnection::checkFingerprint, this, weak_ptr<PeerConnection>{shared_from_this()}, _1),
|
|
|
+ [this, weak_this = weak_ptr<PeerConnection>{shared_from_this()}](DtlsTransport::State state) {
|
|
|
+ auto strong_this = weak_this.lock();
|
|
|
+ if (!strong_this) return;
|
|
|
+
|
|
|
switch (state) {
|
|
|
case DtlsTransport::State::Connected:
|
|
|
initSctpTransport();
|
|
@@ -175,8 +185,11 @@ void PeerConnection::initDtlsTransport() {
|
|
|
void PeerConnection::initSctpTransport() {
|
|
|
uint16_t sctpPort = mRemoteDescription->sctpPort().value_or(DEFAULT_SCTP_PORT);
|
|
|
mSctpTransport = std::make_shared<SctpTransport>(
|
|
|
- mDtlsTransport, sctpPort, std::bind(&PeerConnection::forwardMessage, this, _1),
|
|
|
- [this](SctpTransport::State state) {
|
|
|
+ mDtlsTransport, sctpPort, std::bind(&PeerConnection::forwardMessage, this, weak_ptr<PeerConnection>{shared_from_this()}, _1),
|
|
|
+ [this, weak_this = weak_ptr<PeerConnection>{shared_from_this()}](SctpTransport::State state) {
|
|
|
+ auto strong_this = weak_this.lock();
|
|
|
+ if (!strong_this) return;
|
|
|
+
|
|
|
switch (state) {
|
|
|
case SctpTransport::State::Connected:
|
|
|
changeState(State::Connected);
|
|
@@ -195,7 +208,10 @@ void PeerConnection::initSctpTransport() {
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-bool PeerConnection::checkFingerprint(const std::string &fingerprint) const {
|
|
|
+bool PeerConnection::checkFingerprint(weak_ptr<PeerConnection> weak_this, const std::string &fingerprint) const {
|
|
|
+ auto strong_this = weak_this.lock();
|
|
|
+ if (!strong_this) return false;
|
|
|
+
|
|
|
if (auto expectedFingerprint =
|
|
|
mRemoteDescription ? mRemoteDescription->fingerprint() : nullopt) {
|
|
|
return *expectedFingerprint == fingerprint;
|
|
@@ -203,7 +219,10 @@ bool PeerConnection::checkFingerprint(const std::string &fingerprint) const {
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
-void PeerConnection::forwardMessage(message_ptr message) {
|
|
|
+void PeerConnection::forwardMessage(weak_ptr<PeerConnection> weak_this, message_ptr message) {
|
|
|
+ auto strong_this = weak_this.lock();
|
|
|
+ if (!strong_this) return;
|
|
|
+
|
|
|
if (!mIceTransport || !mSctpTransport)
|
|
|
throw std::logic_error("Got a DataChannel message without transport");
|
|
|
|
|
@@ -227,7 +246,7 @@ void PeerConnection::forwardMessage(message_ptr message) {
|
|
|
if (message->type == Message::Control && *message->data() == dataChannelOpenMessage &&
|
|
|
message->stream % 2 == remoteParity) {
|
|
|
channel = std::make_shared<DataChannel>(message->stream, mSctpTransport);
|
|
|
- channel->onOpen(std::bind(&PeerConnection::triggerDataChannel, this, channel));
|
|
|
+ channel->onOpen(std::bind(&PeerConnection::triggerDataChannel, this, weak_this, weak_ptr<DataChannel>{channel}));
|
|
|
mDataChannels.insert(std::make_pair(message->stream, channel));
|
|
|
} else {
|
|
|
// Invalid, close the DataChannel by resetting the stream
|
|
@@ -272,7 +291,10 @@ void PeerConnection::processLocalDescription(Description description) {
|
|
|
mLocalDescriptionCallback(*mLocalDescription);
|
|
|
}
|
|
|
|
|
|
-void PeerConnection::processLocalCandidate(Candidate candidate) {
|
|
|
+void PeerConnection::processLocalCandidate(weak_ptr<PeerConnection> weak_this, Candidate candidate) {
|
|
|
+ auto strong_this = weak_this.lock();
|
|
|
+ if (!strong_this) return;
|
|
|
+
|
|
|
if (!mLocalDescription)
|
|
|
throw std::logic_error("Got a local candidate without local description");
|
|
|
|
|
@@ -282,7 +304,13 @@ void PeerConnection::processLocalCandidate(Candidate candidate) {
|
|
|
mLocalCandidateCallback(candidate);
|
|
|
}
|
|
|
|
|
|
-void PeerConnection::triggerDataChannel(std::shared_ptr<DataChannel> dataChannel) {
|
|
|
+void PeerConnection::triggerDataChannel(weak_ptr<PeerConnection> weak_this, weak_ptr<DataChannel> weakDataChannel) {
|
|
|
+ auto strong_this = weak_this.lock();
|
|
|
+ if (!strong_this) return;
|
|
|
+
|
|
|
+ auto dataChannel = weakDataChannel.lock();
|
|
|
+ if (!dataChannel) return;
|
|
|
+
|
|
|
if (mDataChannelCallback)
|
|
|
mDataChannelCallback(dataChannel);
|
|
|
}
|