mirror of
https://github.com/mii443/libdatachannel.git
synced 2025-12-03 02:58:22 +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";
|
||||
cout << "Stun server is " << stunServer << endl;
|
||||
config.iceServers.emplace_back(stunServer);
|
||||
|
||||
config.disableAutoNegotiation = true;
|
||||
|
||||
string localId = "server";
|
||||
cout << "The local ID is: " << localId << endl;
|
||||
|
||||
auto ws = make_shared<WebSocket>();
|
||||
|
||||
ws->onOpen([]() { cout << "WebSocket connected, signaling ready" << endl; });
|
||||
|
||||
ws->onClosed([]() { cout << "WebSocket closed" << endl; });
|
||||
@@ -219,15 +220,15 @@ shared_ptr<ClientTrackData> addVideo(const shared_ptr<PeerConnection> pc, const
|
||||
// create RTP configuration
|
||||
auto rtpConfig = shared_ptr<RtpPacketizationConfig>(new RtpPacketizationConfig(ssrc, cname, payloadType, H264RtpPacketizer::defaultClockRate));
|
||||
// create packetizer
|
||||
auto packetizer = shared_ptr<H264RtpPacketizer>(new H264RtpPacketizer(H264RtpPacketizer::Separator::Length, rtpConfig));
|
||||
// create H264 handler
|
||||
shared_ptr<H264PacketizationHandler> h264Handler(new H264PacketizationHandler(packetizer));
|
||||
// add RTCP SR handler
|
||||
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
|
||||
h264Handler->addToChain(srReporter);
|
||||
// add RTCP NACK handler
|
||||
auto nackResponder = make_shared<RtcpNackResponder>();
|
||||
h264Handler->addToChain(nackResponder);
|
||||
auto packetizer = shared_ptr<H264RtpPacketizer>(new H264RtpPacketizer(H264RtpPacketizer::Separator::Length, rtpConfig));
|
||||
// create H264 handler
|
||||
shared_ptr<H264PacketizationHandler> h264Handler(new H264PacketizationHandler(packetizer));
|
||||
// add RTCP SR handler
|
||||
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
|
||||
h264Handler->addToChain(srReporter);
|
||||
// add RTCP NACK handler
|
||||
auto nackResponder = make_shared<RtcpNackResponder>();
|
||||
h264Handler->addToChain(nackResponder);
|
||||
// set handler
|
||||
track->setRtcpHandler(h264Handler);
|
||||
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));
|
||||
// create packetizer
|
||||
auto packetizer = make_shared<OpusRtpPacketizer>(rtpConfig);
|
||||
// create opus handler
|
||||
// create opus handler
|
||||
auto opusHandler = make_shared<OpusPacketizationHandler>(packetizer);
|
||||
// add RTCP SR handler
|
||||
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
|
||||
opusHandler->addToChain(srReporter);
|
||||
// add RTCP NACK handler
|
||||
auto nackResponder = make_shared<RtcpNackResponder>();
|
||||
opusHandler->addToChain(nackResponder);
|
||||
// add RTCP SR handler
|
||||
auto srReporter = make_shared<RtcpSrReporter>(rtpConfig);
|
||||
opusHandler->addToChain(srReporter);
|
||||
// add RTCP NACK handler
|
||||
auto nackResponder = make_shared<RtcpNackResponder>();
|
||||
opusHandler->addToChain(nackResponder);
|
||||
// set handler
|
||||
track->setRtcpHandler(opusHandler);
|
||||
track->onOpen(onOpen);
|
||||
@@ -263,7 +264,6 @@ shared_ptr<ClientTrackData> addAudio(const shared_ptr<PeerConnection> pc, const
|
||||
shared_ptr<Client> createPeerConnection(const Configuration &config,
|
||||
weak_ptr<WebSocket> wws,
|
||||
string id) {
|
||||
|
||||
auto pc = make_shared<PeerConnection>(config);
|
||||
shared_ptr<Client> client(new Client(pc));
|
||||
|
||||
@@ -316,7 +316,7 @@ shared_ptr<Client> createPeerConnection(const Configuration &config,
|
||||
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)]() {
|
||||
if (auto dc = wdc.lock()) {
|
||||
dc->send("Ping");
|
||||
|
||||
@@ -68,6 +68,7 @@ struct RTC_CPP_EXPORT Configuration {
|
||||
std::vector<IceServer> iceServers;
|
||||
std::optional<ProxyServer> proxyServer;
|
||||
bool enableIceTcp = false;
|
||||
bool disableAutoNegotiation = false;
|
||||
uint16_t portRangeBegin = 1024;
|
||||
uint16_t portRangeEnd = 65535;
|
||||
std::optional<size_t> mtu;
|
||||
|
||||
@@ -96,12 +96,13 @@ public:
|
||||
void setRemoteDescription(Description description);
|
||||
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 = {});
|
||||
|
||||
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 onLocalCandidate(std::function<void(Candidate candidate)> callback);
|
||||
void onStateChange(std::function<void(State state)> callback);
|
||||
@@ -113,10 +114,6 @@ public:
|
||||
size_t bytesSent();
|
||||
size_t bytesReceived();
|
||||
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
|
||||
|
||||
@@ -120,6 +120,7 @@ typedef struct {
|
||||
const char **iceServers;
|
||||
int iceServersCount;
|
||||
bool enableIceTcp;
|
||||
bool disableAutoNegotiation;
|
||||
uint16_t portRangeBegin;
|
||||
uint16_t portRangeEnd;
|
||||
int mtu; // <= 0 means automatic
|
||||
@@ -193,10 +194,6 @@ RTC_EXPORT int rtcGetSelectedCandidatePair(int pc, char *local, int localSize, c
|
||||
|
||||
// DataChannel
|
||||
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 rtcCreateDataChannelEx(int pc, const char *label,
|
||||
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.enableIceTcp = config->enableIceTcp;
|
||||
c.disableAutoNegotiation = config->disableAutoNegotiation;
|
||||
|
||||
if (config->portRangeBegin > 0 || config->portRangeEnd > 0) {
|
||||
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([&] {
|
||||
DataChannelInit dci = {};
|
||||
if (init) {
|
||||
@@ -408,7 +411,7 @@ int rtcAddDataChannelEx(int pc, const char *label, const rtcDataChannelInit *ini
|
||||
|
||||
auto peerConnection = getPeerConnection(pc);
|
||||
int dc = emplaceDataChannel(
|
||||
peerConnection->addDataChannel(string(label ? label : ""), std::move(dci)));
|
||||
peerConnection->createDataChannel(string(label ? label : ""), std::move(dci)));
|
||||
|
||||
if (auto ptr = getUserPointer(pc))
|
||||
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) {
|
||||
return wrap([dc] {
|
||||
auto dataChannel = getDataChannel(dc);
|
||||
|
||||
@@ -232,7 +232,8 @@ void PeerConnection::setRemoteDescription(Description description) {
|
||||
|
||||
if (type == Description::Type::Offer) {
|
||||
// This is an offer, we need to answer
|
||||
setLocalDescription(Description::Type::Answer);
|
||||
if (!impl()->config.disableAutoNegotiation)
|
||||
setLocalDescription(Description::Type::Answer);
|
||||
} else {
|
||||
// This is an answer
|
||||
// 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;
|
||||
}
|
||||
|
||||
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
|
||||
// setup:passive. [...] Thus, setup:active is RECOMMENDED.
|
||||
// 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 channelImpl = impl()->emplaceDataChannel(role, std::move(label), std::move(init));
|
||||
auto channel = std::make_shared<DataChannel>(channelImpl);
|
||||
|
||||
if (auto transport = impl()->getSctpTransport())
|
||||
if (transport->state() == impl::SctpTransport::State::Connected)
|
||||
@@ -278,12 +280,9 @@ shared_ptr<DataChannel> PeerConnection::addDataChannel(string label, DataChannel
|
||||
if (!local || !local->hasApplication())
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -292,6 +291,20 @@ void PeerConnection::onDataChannel(
|
||||
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) {
|
||||
impl()->localDescriptionCallback = callback;
|
||||
}
|
||||
@@ -312,19 +325,6 @@ void PeerConnection::onSignalingStateChange(std::function<void(SignalingState st
|
||||
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) {
|
||||
auto iceTransport = impl()->getIceTransport();
|
||||
return iceTransport ? iceTransport->getSelectedCandidatePair(local, remote) : false;
|
||||
|
||||
Reference in New Issue
Block a user