mirror of
https://github.com/mii443/libdatachannel.git
synced 2025-12-07 13:08:26 +00:00
Merge pull request #351 from paullouisageneau/config-autonegotiation
Introduce configuration flag to disable auto negotiation
This commit is contained in:
@@ -161,12 +161,13 @@ int main(int argc, char **argv) try {
|
|||||||
string stunServer = "stun:stun.l.google.com:19302";
|
string stunServer = "stun:stun.l.google.com:19302";
|
||||||
cout << "Stun server is " << stunServer << endl;
|
cout << "Stun server is " << stunServer << endl;
|
||||||
config.iceServers.emplace_back(stunServer);
|
config.iceServers.emplace_back(stunServer);
|
||||||
|
config.disableAutoNegotiation = true;
|
||||||
|
|
||||||
string localId = "server";
|
string localId = "server";
|
||||||
cout << "The local ID is: " << localId << endl;
|
cout << "The local ID is: " << localId << endl;
|
||||||
|
|
||||||
auto ws = make_shared<WebSocket>();
|
auto ws = make_shared<WebSocket>();
|
||||||
|
|
||||||
ws->onOpen([]() { cout << "WebSocket connected, signaling ready" << endl; });
|
ws->onOpen([]() { cout << "WebSocket connected, signaling ready" << endl; });
|
||||||
|
|
||||||
ws->onClosed([]() { cout << "WebSocket closed" << endl; });
|
ws->onClosed([]() { cout << "WebSocket closed" << endl; });
|
||||||
@@ -219,15 +220,15 @@ shared_ptr<ClientTrackData> addVideo(const shared_ptr<PeerConnection> pc, const
|
|||||||
// create RTP configuration
|
// create RTP configuration
|
||||||
auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, H264RtpPacketizer::defaultClockRate));
|
auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, H264RtpPacketizer::defaultClockRate));
|
||||||
// create packetizer
|
// create packetizer
|
||||||
auto packetizer = shared_ptr<H264RtpPacketizer>(new H264RtpPacketizer(H264RtpPacketizer::Separator::Length, rtpConfig));
|
auto packetizer = shared_ptr<H264RtpPacketizer>(new H264RtpPacketizer(H264RtpPacketizer::Separator::Length, rtpConfig));
|
||||||
// create H264 handler
|
// create H264 handler
|
||||||
shared_ptr<H264PacketizationHandler> h264Handler(new H264PacketizationHandler(packetizer));
|
shared_ptr<H264PacketizationHandler> h264Handler(new H264PacketizationHandler(packetizer));
|
||||||
// add RTCP SR handler
|
// add RTCP SR handler
|
||||||
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
|
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
|
||||||
h264Handler->addToChain(srReporter);
|
h264Handler->addToChain(srReporter);
|
||||||
// add RTCP NACK handler
|
// add RTCP NACK handler
|
||||||
auto nackResponder = make_shared<RtcpNackResponder>();
|
auto nackResponder = make_shared<RtcpNackResponder>();
|
||||||
h264Handler->addToChain(nackResponder);
|
h264Handler->addToChain(nackResponder);
|
||||||
// set handler
|
// set handler
|
||||||
track->setRtcpHandler(h264Handler);
|
track->setRtcpHandler(h264Handler);
|
||||||
track->onOpen(onOpen);
|
track->onOpen(onOpen);
|
||||||
@@ -244,14 +245,14 @@ shared_ptr<ClientTrackData> addAudio(const shared_ptr<PeerConnection> pc, const
|
|||||||
auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, OpusRtpPacketizer::defaultClockRate));
|
auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, OpusRtpPacketizer::defaultClockRate));
|
||||||
// create packetizer
|
// create packetizer
|
||||||
auto packetizer = make_shared<OpusRtpPacketizer>(rtpConfig);
|
auto packetizer = make_shared<OpusRtpPacketizer>(rtpConfig);
|
||||||
// create opus handler
|
// create opus handler
|
||||||
auto opusHandler = make_shared<OpusPacketizationHandler>(packetizer);
|
auto opusHandler = make_shared<OpusPacketizationHandler>(packetizer);
|
||||||
// add RTCP SR handler
|
// add RTCP SR handler
|
||||||
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
|
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
|
||||||
opusHandler->addToChain(srReporter);
|
opusHandler->addToChain(srReporter);
|
||||||
// add RTCP NACK handler
|
// add RTCP NACK handler
|
||||||
auto nackResponder = make_shared<RtcpNackResponder>();
|
auto nackResponder = make_shared<RtcpNackResponder>();
|
||||||
opusHandler->addToChain(nackResponder);
|
opusHandler->addToChain(nackResponder);
|
||||||
// set handler
|
// set handler
|
||||||
track->setRtcpHandler(opusHandler);
|
track->setRtcpHandler(opusHandler);
|
||||||
track->onOpen(onOpen);
|
track->onOpen(onOpen);
|
||||||
@@ -263,7 +264,6 @@ shared_ptr<ClientTrackData> addAudio(const shared_ptr<PeerConnection> pc, const
|
|||||||
shared_ptr<Client> createPeerConnection(const Configuration &config,
|
shared_ptr<Client> createPeerConnection(const Configuration &config,
|
||||||
weak_ptr<WebSocket> wws,
|
weak_ptr<WebSocket> wws,
|
||||||
string id) {
|
string id) {
|
||||||
|
|
||||||
auto pc = make_shared<PeerConnection>(config);
|
auto pc = make_shared<PeerConnection>(config);
|
||||||
shared_ptr<Client> client(new Client(pc));
|
shared_ptr<Client> client(new Client(pc));
|
||||||
|
|
||||||
@@ -316,7 +316,7 @@ shared_ptr<Client> createPeerConnection(const Configuration &config,
|
|||||||
cout << "Audio from " << id << " opened" << endl;
|
cout << "Audio from " << id << " opened" << endl;
|
||||||
});
|
});
|
||||||
|
|
||||||
auto dc = pc->addDataChannel("ping-pong");
|
auto dc = pc->createDataChannel("ping-pong");
|
||||||
dc->onOpen([id, wdc = make_weak_ptr(dc)]() {
|
dc->onOpen([id, wdc = make_weak_ptr(dc)]() {
|
||||||
if (auto dc = wdc.lock()) {
|
if (auto dc = wdc.lock()) {
|
||||||
dc->send("Ping");
|
dc->send("Ping");
|
||||||
|
|||||||
@@ -68,6 +68,7 @@ struct RTC_CPP_EXPORT Configuration {
|
|||||||
std::vector<IceServer> iceServers;
|
std::vector<IceServer> iceServers;
|
||||||
std::optional<ProxyServer> proxyServer;
|
std::optional<ProxyServer> proxyServer;
|
||||||
bool enableIceTcp = false;
|
bool enableIceTcp = false;
|
||||||
|
bool disableAutoNegotiation = false;
|
||||||
uint16_t portRangeBegin = 1024;
|
uint16_t portRangeBegin = 1024;
|
||||||
uint16_t portRangeEnd = 65535;
|
uint16_t portRangeEnd = 65535;
|
||||||
std::optional<size_t> mtu;
|
std::optional<size_t> mtu;
|
||||||
|
|||||||
@@ -96,12 +96,13 @@ public:
|
|||||||
void setRemoteDescription(Description description);
|
void setRemoteDescription(Description description);
|
||||||
void addRemoteCandidate(Candidate candidate);
|
void addRemoteCandidate(Candidate candidate);
|
||||||
|
|
||||||
std::shared_ptr<DataChannel> addDataChannel(string label, DataChannelInit init = {});
|
|
||||||
|
|
||||||
// Equivalent to calling addDataChannel() and setLocalDescription()
|
|
||||||
std::shared_ptr<DataChannel> createDataChannel(string label, DataChannelInit init = {});
|
std::shared_ptr<DataChannel> createDataChannel(string label, DataChannelInit init = {});
|
||||||
|
|
||||||
void onDataChannel(std::function<void(std::shared_ptr<DataChannel> dataChannel)> callback);
|
void onDataChannel(std::function<void(std::shared_ptr<DataChannel> dataChannel)> callback);
|
||||||
|
|
||||||
|
std::shared_ptr<Track> addTrack(Description::Media description);
|
||||||
|
void onTrack(std::function<void(std::shared_ptr<Track> track)> callback);
|
||||||
|
|
||||||
void onLocalDescription(std::function<void(Description description)> callback);
|
void onLocalDescription(std::function<void(Description description)> callback);
|
||||||
void onLocalCandidate(std::function<void(Candidate candidate)> callback);
|
void onLocalCandidate(std::function<void(Candidate candidate)> callback);
|
||||||
void onStateChange(std::function<void(State state)> callback);
|
void onStateChange(std::function<void(State state)> callback);
|
||||||
@@ -113,10 +114,6 @@ public:
|
|||||||
size_t bytesSent();
|
size_t bytesSent();
|
||||||
size_t bytesReceived();
|
size_t bytesReceived();
|
||||||
std::optional<std::chrono::milliseconds> rtt();
|
std::optional<std::chrono::milliseconds> rtt();
|
||||||
|
|
||||||
// Track media support requires compiling with libSRTP
|
|
||||||
std::shared_ptr<Track> addTrack(Description::Media description);
|
|
||||||
void onTrack(std::function<void(std::shared_ptr<Track> track)> callback);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace rtc
|
} // namespace rtc
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ typedef struct {
|
|||||||
const char **iceServers;
|
const char **iceServers;
|
||||||
int iceServersCount;
|
int iceServersCount;
|
||||||
bool enableIceTcp;
|
bool enableIceTcp;
|
||||||
|
bool disableAutoNegotiation;
|
||||||
uint16_t portRangeBegin;
|
uint16_t portRangeBegin;
|
||||||
uint16_t portRangeEnd;
|
uint16_t portRangeEnd;
|
||||||
int mtu; // <= 0 means automatic
|
int mtu; // <= 0 means automatic
|
||||||
@@ -193,10 +194,6 @@ RTC_EXPORT int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, c
|
|||||||
|
|
||||||
// DataChannel
|
// DataChannel
|
||||||
RTC_EXPORT int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb);
|
RTC_EXPORT int rtcSetDataChannelCallback(int pc, rtcDataChannelCallbackFunc cb);
|
||||||
RTC_EXPORT int rtcAddDataChannel(int pc, const char *label); // returns dc id
|
|
||||||
RTC_EXPORT int rtcAddDataChannelEx(int pc, const char *label,
|
|
||||||
const rtcDataChannelInit *init); // returns dc id
|
|
||||||
// Equivalent to calling rtcAddDataChannel() and rtcSetLocalDescription()
|
|
||||||
RTC_EXPORT int rtcCreateDataChannel(int pc, const char *label); // returns dc id
|
RTC_EXPORT int rtcCreateDataChannel(int pc, const char *label); // returns dc id
|
||||||
RTC_EXPORT int rtcCreateDataChannelEx(int pc, const char *label,
|
RTC_EXPORT int rtcCreateDataChannelEx(int pc, const char *label,
|
||||||
const rtcDataChannelInit *init); // returns dc id
|
const rtcDataChannelInit *init); // returns dc id
|
||||||
|
|||||||
19
src/capi.cpp
19
src/capi.cpp
@@ -353,6 +353,7 @@ int rtcCreatePeerConnection(const rtcConfiguration *config) {
|
|||||||
c.iceServers.emplace_back(string(config->iceServers[i]));
|
c.iceServers.emplace_back(string(config->iceServers[i]));
|
||||||
|
|
||||||
c.enableIceTcp = config->enableIceTcp;
|
c.enableIceTcp = config->enableIceTcp;
|
||||||
|
c.disableAutoNegotiation = config->disableAutoNegotiation;
|
||||||
|
|
||||||
if (config->portRangeBegin > 0 || config->portRangeEnd > 0) {
|
if (config->portRangeBegin > 0 || config->portRangeEnd > 0) {
|
||||||
c.portRangeBegin = config->portRangeBegin;
|
c.portRangeBegin = config->portRangeBegin;
|
||||||
@@ -381,9 +382,11 @@ int rtcDeletePeerConnection(int pc) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtcAddDataChannel(int pc, const char *label) { return rtcAddDataChannelEx(pc, label, nullptr); }
|
int rtcCreateDataChannel(int pc, const char *label) {
|
||||||
|
return rtcCreateDataChannelEx(pc, label, nullptr);
|
||||||
|
}
|
||||||
|
|
||||||
int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *init) {
|
int rtcCreateDataChannelEx(int pc, const char *label, const rtcDataChannelInit *init) {
|
||||||
return wrap([&] {
|
return wrap([&] {
|
||||||
DataChannelInit dci = {};
|
DataChannelInit dci = {};
|
||||||
if (init) {
|
if (init) {
|
||||||
@@ -408,7 +411,7 @@ int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *ini
|
|||||||
|
|
||||||
auto peerConnection = getPeerConnection(pc);
|
auto peerConnection = getPeerConnection(pc);
|
||||||
int dc = emplaceDataChannel(
|
int dc = emplaceDataChannel(
|
||||||
peerConnection->addDataChannel(string(label ? label : ""), std::move(dci)));
|
peerConnection->createDataChannel(string(label ? label : ""), std::move(dci)));
|
||||||
|
|
||||||
if (auto ptr = getUserPointer(pc))
|
if (auto ptr = getUserPointer(pc))
|
||||||
rtcSetUserPointer(dc, *ptr);
|
rtcSetUserPointer(dc, *ptr);
|
||||||
@@ -417,16 +420,6 @@ int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *ini
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
int rtcCreateDataChannel(int pc, const char *label) {
|
|
||||||
return rtcCreateDataChannelEx(pc, label, nullptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
int rtcCreateDataChannelEx(int pc, const char *label, const rtcDataChannelInit *init) {
|
|
||||||
int dc = rtcAddDataChannelEx(pc, label, init);
|
|
||||||
rtcSetLocalDescription(pc, NULL);
|
|
||||||
return dc;
|
|
||||||
}
|
|
||||||
|
|
||||||
int rtcDeleteDataChannel(int dc) {
|
int rtcDeleteDataChannel(int dc) {
|
||||||
return wrap([dc] {
|
return wrap([dc] {
|
||||||
auto dataChannel = getDataChannel(dc);
|
auto dataChannel = getDataChannel(dc);
|
||||||
|
|||||||
@@ -232,7 +232,8 @@ void PeerConnection::setRemoteDescription(Description description) {
|
|||||||
|
|
||||||
if (type == Description::Type::Offer) {
|
if (type == Description::Type::Offer) {
|
||||||
// This is an offer, we need to answer
|
// This is an offer, we need to answer
|
||||||
setLocalDescription(Description::Type::Answer);
|
if (!impl()->config.disableAutoNegotiation)
|
||||||
|
setLocalDescription(Description::Type::Answer);
|
||||||
} else {
|
} else {
|
||||||
// This is an answer
|
// This is an answer
|
||||||
// Since we assumed passive role during DataChannel creation, we need to shift the
|
// Since we assumed passive role during DataChannel creation, we need to shift the
|
||||||
@@ -259,7 +260,7 @@ std::optional<string> PeerConnection::remoteAddress() const {
|
|||||||
return iceTransport ? iceTransport->getRemoteAddress() : nullopt;
|
return iceTransport ? iceTransport->getRemoteAddress() : nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
shared_ptr<DataChannel> PeerConnection::addDataChannel(string label, DataChannelInit init) {
|
shared_ptr<DataChannel> PeerConnection::createDataChannel(string label, DataChannelInit init) {
|
||||||
// RFC 5763: The answerer MUST use either a setup attribute value of setup:active or
|
// RFC 5763: The answerer MUST use either a setup attribute value of setup:active or
|
||||||
// setup:passive. [...] Thus, setup:active is RECOMMENDED.
|
// setup:passive. [...] Thus, setup:active is RECOMMENDED.
|
||||||
// See https://tools.ietf.org/html/rfc5763#section-5
|
// See https://tools.ietf.org/html/rfc5763#section-5
|
||||||
@@ -268,6 +269,7 @@ shared_ptr<DataChannel> PeerConnection::addDataChannel(string label, DataChannel
|
|||||||
auto role = iceTransport ? iceTransport->role() : Description::Role::Passive;
|
auto role = iceTransport ? iceTransport->role() : Description::Role::Passive;
|
||||||
|
|
||||||
auto channelImpl = impl()->emplaceDataChannel(role, std::move(label), std::move(init));
|
auto channelImpl = impl()->emplaceDataChannel(role, std::move(label), std::move(init));
|
||||||
|
auto channel = std::make_shared<DataChannel>(channelImpl);
|
||||||
|
|
||||||
if (auto transport = impl()->getSctpTransport())
|
if (auto transport = impl()->getSctpTransport())
|
||||||
if (transport->state() == impl::SctpTransport::State::Connected)
|
if (transport->state() == impl::SctpTransport::State::Connected)
|
||||||
@@ -278,12 +280,9 @@ shared_ptr<DataChannel> PeerConnection::addDataChannel(string label, DataChannel
|
|||||||
if (!local || !local->hasApplication())
|
if (!local || !local->hasApplication())
|
||||||
impl()->negotiationNeeded = true;
|
impl()->negotiationNeeded = true;
|
||||||
|
|
||||||
return std::make_shared<DataChannel>(channelImpl);
|
if (!impl()->config.disableAutoNegotiation)
|
||||||
}
|
setLocalDescription();
|
||||||
|
|
||||||
shared_ptr<DataChannel> PeerConnection::createDataChannel(string label, DataChannelInit init) {
|
|
||||||
auto channel = addDataChannel(std::move(label), std::move(init));
|
|
||||||
setLocalDescription();
|
|
||||||
return channel;
|
return channel;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -292,6 +291,20 @@ void PeerConnection::onDataChannel(
|
|||||||
impl()->dataChannelCallback = callback;
|
impl()->dataChannelCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<Track> PeerConnection::addTrack(Description::Media description) {
|
||||||
|
auto trackImpl = impl()->emplaceTrack(std::move(description));
|
||||||
|
auto track = std::make_shared<Track>(trackImpl);
|
||||||
|
|
||||||
|
// Renegotiation is needed for the new or updated track
|
||||||
|
impl()->negotiationNeeded = true;
|
||||||
|
|
||||||
|
return track;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PeerConnection::onTrack(std::function<void(std::shared_ptr<Track>)> callback) {
|
||||||
|
impl()->trackCallback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
void PeerConnection::onLocalDescription(std::function<void(Description description)> callback) {
|
void PeerConnection::onLocalDescription(std::function<void(Description description)> callback) {
|
||||||
impl()->localDescriptionCallback = callback;
|
impl()->localDescriptionCallback = callback;
|
||||||
}
|
}
|
||||||
@@ -312,19 +325,6 @@ void PeerConnection::onSignalingStateChange(std::function<void(SignalingState st
|
|||||||
impl()->signalingStateChangeCallback = callback;
|
impl()->signalingStateChangeCallback = callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<Track> PeerConnection::addTrack(Description::Media description) {
|
|
||||||
auto trackImpl = impl()->emplaceTrack(std::move(description));
|
|
||||||
|
|
||||||
// Renegotiation is needed for the new or updated track
|
|
||||||
impl()->negotiationNeeded = true;
|
|
||||||
|
|
||||||
return std::make_shared<Track>(trackImpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PeerConnection::onTrack(std::function<void(std::shared_ptr<Track>)> callback) {
|
|
||||||
impl()->trackCallback = callback;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PeerConnection::getSelectedCandidatePair(Candidate *local, Candidate *remote) {
|
bool PeerConnection::getSelectedCandidatePair(Candidate *local, Candidate *remote) {
|
||||||
auto iceTransport = impl()->getIceTransport();
|
auto iceTransport = impl()->getIceTransport();
|
||||||
return iceTransport ? iceTransport->getSelectedCandidatePair(local, remote) : false;
|
return iceTransport ? iceTransport->getSelectedCandidatePair(local, remote) : false;
|
||||||
|
|||||||
Reference in New Issue
Block a user