Skip to content

Commit

Permalink
Merge pull request #176 from Sean-Der/main
Browse files Browse the repository at this point in the history
Add peer_connection_create_datachannel
  • Loading branch information
sepfy authored Jan 2, 2025
2 parents c543e48 + fbeb5a5 commit 6261915
Show file tree
Hide file tree
Showing 5 changed files with 111 additions and 11 deletions.
1 change: 0 additions & 1 deletion src/ice.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ int ice_candidate_from_description(IceCandidate* candidate, char* description, c
candidate_start += strlen("a=");
}
candidate_start += strlen("candidate:");
printf("candidate_start: %s\n", candidate_start);

// a=candidate:448736988 1 udp 2122260223 172.17.0.1 49250 typ host generation 0 network-id 1 network-cost 50
// a=candidate:udpcandidate 1 udp 120 192.168.1.102 8000 typ host
Expand Down
49 changes: 49 additions & 0 deletions src/peer_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,55 @@ int peer_connection_datachannel_send_sid(PeerConnection* pc, char* message, size
#endif
}

int peer_connection_create_datachannel(PeerConnection* pc, DecpChannelType channel_type, uint16_t priority, uint32_t reliability_parameter, char* label, char* protocol) {
return peer_connection_create_datachannel_sid(pc, channel_type, priority, reliability_parameter, label, protocol, 0);
}

int peer_connection_create_datachannel_sid(PeerConnection* pc, DecpChannelType channel_type, uint16_t priority, uint32_t reliability_parameter, char* label, char* protocol, uint16_t sid) {
int rtrn = -1;

if (!sctp_is_connected(&pc->sctp)) {
LOGE("sctp not connected");
return rtrn;
}

// 0 1 2 3
// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Message Type | Channel Type | Priority |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Reliability Parameter |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | Label Length | Protocol Length |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | |
// | Label |
// | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
// | |
// | Protocol |
// | |
// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
int msg_size = 12 + strlen(label) + strlen(protocol);
uint16_t priority_big_endian = htons(priority);
uint32_t reliability_big_endian = ntohl(reliability_parameter);
uint16_t label_length = htons(strlen(label));
uint16_t protocol_length = htons(strlen(protocol));
char* msg = calloc(1, msg_size);

msg[0] = DATA_CHANNEL_OPEN;
memcpy(msg + 2, &priority_big_endian, sizeof(uint16_t));
memcpy(msg + 4, &reliability_big_endian, sizeof(uint32_t));
memcpy(msg + 8, &label_length, sizeof(uint16_t));
memcpy(msg + 10, &protocol_length, sizeof(uint16_t));
memcpy(msg + 12, label, strlen(label));
memcpy(msg + 12 + strlen(label), protocol, strlen(protocol));

rtrn = sctp_outgoing_data(&pc->sctp, msg, msg_size, PPID_CONTROL, sid);
free(msg);
return rtrn;
}

static char* peer_connection_dtls_role_setup_value(DtlsSrtpRole d) {
return d == DTLS_SRTP_ROLE_SERVER ? "a=setup:passive" : "a=setup:active";
}
Expand Down
14 changes: 14 additions & 0 deletions src/peer_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ typedef enum DataChannelType {

} DataChannelType;

typedef enum DecpChannelType {
DATA_CHANNEL_RELIABLE = 0x00,
DATA_CHANNEL_RELIABLE_UNORDERED = 0x80,
DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT = 0x01,
DATA_CHANNEL_PARTIAL_RELIABLE_REXMIT_UNORDERED = 0x81,
DATA_CHANNEL_PARTIAL_RELIABLE_TIMED = 0x02,
DATA_CHANNEL_PARTIAL_RELIABLE_TIMED_UNORDERED = 0x82,
} DecpChannelType;

typedef enum MediaCodec {

CODEC_NONE = 0,
Expand Down Expand Up @@ -84,6 +93,11 @@ void peer_connection_destroy(PeerConnection* pc);
void peer_connection_close(PeerConnection* pc);

int peer_connection_loop(PeerConnection* pc);

int peer_connection_create_datachannel(PeerConnection* pc, DecpChannelType channel_type, uint16_t priority, uint32_t reliability_parameter, char* label, char* protocol);

int peer_connection_create_datachannel_sid(PeerConnection* pc, DecpChannelType channel_type, uint16_t priority, uint32_t reliability_parameter, char* label, char* protocol, uint16_t sid);

/**
* @brief send message to data channel
* @param[in] peer connection
Expand Down
1 change: 1 addition & 0 deletions src/ssl_transport.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#include "mbedtls/entropy.h"
#include "mbedtls/ssl.h"

#include <sys/select.h>
#include "config.h"
#include "ports.h"
#include "ssl_transport.h"
Expand Down
57 changes: 47 additions & 10 deletions tests/test_peer_connection.c
Original file line number Diff line number Diff line change
@@ -1,13 +1,20 @@
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include "peer.h"

#define MAX_CONNECTION_ATTEMPTS 25
#define OFFER_DATACHANNEL_MESSAGE "Hello World"
#define ANSWER_DATACHANNEL_MESSAGE "Foobar"
#define DATACHANNEL_NAME "libpeer-datachannel"

int test_complete = 0;

typedef struct {
PeerConnection *offer_peer_connection, *answer_peer_connection;
int onmessage_offer_called, onmessage_answer_called, test_complete;
} TestUserData;

static void onconnectionstatechange_offerer_peer_connection(PeerConnectionState state, void* user_data) {
Expand All @@ -28,14 +35,26 @@ static void onicecandidate_answerer_peer_connection(char* description, void* use
peer_connection_set_remote_description(test_user_data->offer_peer_connection, description);
}

static void ondatachannel_onmessage_offerer_peer_connection(char* msg, size_t len, void* userdata, uint16_t sid) {
TestUserData* test_user_data = (TestUserData*)userdata;

if (strcmp(msg, ANSWER_DATACHANNEL_MESSAGE) == 0) {
test_user_data->onmessage_offer_called = 1;
}
}

static void ondatachannel_onmessage_answerer_peer_connection(char* msg, size_t len, void* userdata, uint16_t sid) {
TestUserData* test_user_data = (TestUserData*)userdata;

if (strcmp(msg, OFFER_DATACHANNEL_MESSAGE) == 0) {
test_user_data->onmessage_answer_called = 1;
}
}

static void* peer_connection_task(void* user_data) {
PeerConnection* peer_connection = (PeerConnection*)user_data;

while (1) {
if (peer_connection_get_state(peer_connection) == PEER_CONNECTION_COMPLETED) {
break;
}

while (!test_complete) {
peer_connection_loop(peer_connection);
usleep(1000);
}
Expand Down Expand Up @@ -73,23 +92,41 @@ int main(int argc, char* argv[]) {
peer_connection_onicecandidate(test_user_data.offer_peer_connection, onicecandidate_offerer_peer_connection);
peer_connection_onicecandidate(test_user_data.answer_peer_connection, onicecandidate_answerer_peer_connection);

peer_connection_ondatachannel(test_user_data.offer_peer_connection, ondatachannel_onmessage_offerer_peer_connection, NULL, NULL);
peer_connection_ondatachannel(test_user_data.answer_peer_connection, ondatachannel_onmessage_answerer_peer_connection, NULL, NULL);

peer_connection_create_offer(test_user_data.offer_peer_connection);

pthread_create(&offer_thread, NULL, peer_connection_task, test_user_data.offer_peer_connection);
pthread_create(&answer_thread, NULL, peer_connection_task, test_user_data.answer_peer_connection);

int attempts = 0;
while (1) {
if (peer_connection_get_state(test_user_data.offer_peer_connection) == PEER_CONNECTION_COMPLETED && peer_connection_get_state(test_user_data.answer_peer_connection) == PEER_CONNECTION_COMPLETED) {
break;
} else if (attempts == MAX_CONNECTION_ATTEMPTS) {
int attempts = 0, datachannel_created = 0;
while (attempts < MAX_CONNECTION_ATTEMPTS) {
if (!datachannel_created && peer_connection_get_state(test_user_data.offer_peer_connection) == PEER_CONNECTION_COMPLETED) {
if (peer_connection_create_datachannel(test_user_data.offer_peer_connection, DATA_CHANNEL_RELIABLE, 0, 0, DATACHANNEL_NAME, "bar") == 18) {
datachannel_created = 1;
}
}

if (peer_connection_get_state(test_user_data.offer_peer_connection) == PEER_CONNECTION_COMPLETED &&
peer_connection_get_state(test_user_data.answer_peer_connection) == PEER_CONNECTION_COMPLETED &&
test_user_data.onmessage_offer_called == 1 &&
test_user_data.onmessage_answer_called == 1) {
break;
}

peer_connection_datachannel_send(test_user_data.offer_peer_connection, OFFER_DATACHANNEL_MESSAGE, sizeof(OFFER_DATACHANNEL_MESSAGE));
peer_connection_datachannel_send(test_user_data.answer_peer_connection, ANSWER_DATACHANNEL_MESSAGE, sizeof(ANSWER_DATACHANNEL_MESSAGE));

attempts++;
usleep(250000);
}

if (strcmp(DATACHANNEL_NAME, peer_connection_lookup_sid_label(test_user_data.answer_peer_connection, 0)) != 0) {
return 1;
}

test_complete = 1;
peer_connection_destroy(test_user_data.offer_peer_connection);
peer_connection_destroy(test_user_data.answer_peer_connection);

Expand Down

0 comments on commit 6261915

Please sign in to comment.