Skip to content

Commit

Permalink
Fix data channel open
Browse files Browse the repository at this point in the history
Previously, the data channel object was not being created
for the peer that generates the offer/datachannel.

Included fixes:

* Send ACK after receiving DATA_CHANNEL_OPEN
* Pass and return uint16_t for all SIDs instead of int
* Calls new channel and on_open callbacks inside HandleAck
* Some formatting fixes
  • Loading branch information
mo3rfan committed May 11, 2017
1 parent 4cc4d74 commit cd7b213
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 24 deletions.
2 changes: 1 addition & 1 deletion include/rtcdcpp/PeerConnection.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ class PeerConnection {

// DataChannel message parsing
void HandleNewDataChannel(ChunkPtr chunk, uint16_t sid);
void HandleDataChannelAck();
void HandleDataChannelAck(uint16_t sid);
void HandleStringMessage(ChunkPtr chunk, uint16_t sid);
void HandleBinaryMessage(ChunkPtr chunk, uint16_t sid);

Expand Down
7 changes: 4 additions & 3 deletions include/rtcdcpp/SCTPWrapper.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,18 +60,19 @@ class SCTPWrapper {
// Handle a decrypted SCTP packet
void DTLSForSCTP(ChunkPtr chunk);

void SendACK();
void CreateDCForSCTP(std::string label, std::string protocol="");

dc_open_msg *data;
int sid;
uint16_t sid;
std::string label;
std::string protocol;

dc_open_msg* GetDataChannelData();
int GetSid();
uint16_t GetSid();
std::string GetProtocol();
std::string GetLabel();
void SetDataChannelSID(int sid);
void SetDataChannelSID(uint16_t sid);

// Send a message to the remote connection
// Note, this will cause 1+ DTLSEncrypt callback calls
Expand Down
35 changes: 19 additions & 16 deletions src/PeerConnection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,11 +210,12 @@ void PeerConnection::OnSCTPMsgReceived(ChunkPtr chunk, uint16_t sid, uint32_t pp
if (ppid == PPID_CONTROL) {
SPDLOG_TRACE(logger, "Control PPID");
if (chunk->Data()[0] == DC_TYPE_OPEN) {
logger->info("DC TYPE OPEN RECEIVED");
SPDLOG_TRACE(logger, "New channel time!");
HandleNewDataChannel(chunk, sid);
} else if (chunk->Data()[0] == DC_TYPE_ACK) {
SPDLOG_TRACE(logger, "DC ACK");
HandleDataChannelAck();
HandleDataChannelAck(sid);
} else {
SPDLOG_TRACE(logger, "Unknown msg_type for ppid control: {}", chunk->Data()[0]);
}
Expand Down Expand Up @@ -257,29 +258,26 @@ void PeerConnection::HandleNewDataChannel(ChunkPtr chunk, uint16_t sid) {
auto new_channel = std::make_shared<DataChannel>(this, sid, open_msg.chan_type, label, protocol);

data_channels[sid] = new_channel;

this->sctp->SendACK();
if (this->new_channel_cb) {
this->new_channel_cb(new_channel);
} else {
logger->warn("No new channel callback, ignoring new channel");
}
}

void PeerConnection::HandleDataChannelAck() {
dc_open_msg* datachannel_data = this->sctp->GetDataChannelData();
int sid = this->sctp->GetSid();
std::string label = this->sctp->GetLabel();
std::string protocol = this->sctp->GetProtocol();
// TODO: Support overriding an existing channel
auto new_channel = std::make_shared<DataChannel>(this, sid, datachannel_data->chan_type, label, protocol);

data_channels[sid] = new_channel;

void PeerConnection::HandleDataChannelAck(uint16_t sid) {
auto new_channel = GetChannel(sid);
if (this->new_channel_cb) {
this->new_channel_cb(new_channel);
} else {
logger->warn("No new channel callback, ignoring new channel");
}
if (!new_channel) {
logger->warn("Cannot find the datachannel for sid {}", sid);
} else {
new_channel->OnOpen();
}
}

void PeerConnection::HandleStringMessage(ChunkPtr chunk, uint16_t sid) {
Expand Down Expand Up @@ -314,20 +312,25 @@ void PeerConnection::SendBinaryMsg(const uint8_t *data, int len, uint16_t sid) {
}

void PeerConnection::CreateDataChannel(std::string label, std::string protocol) {
int sid;
if(this->role == 0){
uint16_t sid;
if (this->role == 0) {
sid = 0;
} else {
sid = 1;
}
for(int i = sid; i < data_channels.size(); i = i + 2){
for (int i = sid; i < data_channels.size(); i = i + 2) {
auto iter = data_channels.find(i);
if (iter == data_channels.end()) {
sid = i;
break;
}
}
this->sctp->SetDataChannelSID(sid);

this->sctp->SetDataChannelSID(sid);

auto new_channel = std::make_shared<DataChannel>(this, sid, DATA_CHANNEL_RELIABLE, label, protocol);
data_channels[sid] = new_channel;

std::thread create_dc = std::thread(&SCTPWrapper::CreateDCForSCTP, sctp.get(), label, protocol);
logger->info("Spawning create_dc thread");
create_dc.detach();
Expand Down
20 changes: 16 additions & 4 deletions src/SCTPWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ void SCTPWrapper::Stop() {

void SCTPWrapper::DTLSForSCTP(ChunkPtr chunk) { this->recv_queue.push(chunk); }

int SCTPWrapper::GetSid(){
uint16_t SCTPWrapper::GetSid(){
return this->sid;
}

Expand All @@ -309,11 +309,23 @@ std::string SCTPWrapper::GetLabel(){
std::string SCTPWrapper::GetProtocol(){
return this->label;
}
void SCTPWrapper::SetDataChannelSID(int sid)
void SCTPWrapper::SetDataChannelSID(uint16_t sid)
{
this->sid = sid;
}

void SCTPWrapper::SendACK() {
struct sctp_sndinfo sinfo = {0}; //
int sid;
sid = this->sid;
sinfo.snd_sid = sid;
sinfo.snd_ppid = htonl(PPID_CONTROL);
uint8_t payload = DC_TYPE_ACK;
if (usrsctp_sendv(this->sock, &payload, sizeof(uint8_t), NULL, 0, &sinfo, sizeof(sinfo), SCTP_SENDV_SNDINFO, 0) < 0) {
logger->error("Sending ACK failed");
} else {
logger->info("Ack has gone through");
}
}
void SCTPWrapper::CreateDCForSCTP(std::string label, std::string protocol) {

std::unique_lock<std::mutex> l2(createDCMtx);
Expand All @@ -322,7 +334,7 @@ void SCTPWrapper::CreateDCForSCTP(std::string label, std::string protocol) {
}
struct sctp_sndinfo sinfo = {0};
int sid;
sid = this->sid ;
sid = this->sid;
sinfo.snd_sid = sid;
sinfo.snd_ppid = htonl(PPID_CONTROL);

Expand Down

0 comments on commit cd7b213

Please sign in to comment.