Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
project(lib)

file(GLOB SRCS "*.c")
file(GLOB SRCS "agent.c" "peer_connection.c" "*.c")

file(GLOB HEADERS "peer.h" "peer_connection.h" "peer_signaling.h")

Expand Down
74 changes: 42 additions & 32 deletions src/agent.c
Original file line number Diff line number Diff line change
Expand Up @@ -320,22 +320,28 @@ static void agent_create_binding_response(Agent* agent, StunMessage* msg, Addres
stun_msg_finish(msg, STUN_CREDENTIAL_SHORT_TERM, agent->local_upwd, strlen(agent->local_upwd));
}

static void agent_create_binding_request(Agent* agent, StunMessage* msg) {
uint64_t tie_breaker = 0; // always be controlled
static void agent_create_binding_request(Agent* agent, StunMessage* msg, int is_heartbeat) {
// send binding request
stun_msg_create(msg, STUN_CLASS_REQUEST | STUN_METHOD_BINDING);
char username[584];
memset(username, 0, sizeof(username));
snprintf(username, sizeof(username), "%s:%s", agent->remote_ufrag, agent->local_ufrag);
stun_msg_write_attr(msg, STUN_ATTR_TYPE_USERNAME, strlen(username), username);
stun_msg_write_attr(msg, STUN_ATTR_TYPE_PRIORITY, 4, (char*)&agent->nominated_pair->priority);
if (agent->mode == AGENT_MODE_CONTROLLING) {
stun_msg_write_attr(msg, STUN_ATTR_TYPE_USE_CANDIDATE, 0, NULL);
stun_msg_write_attr(msg, STUN_ATTR_TYPE_ICE_CONTROLLING, 8, (char*)&tie_breaker);
} else {
stun_msg_write_attr(msg, STUN_ATTR_TYPE_ICE_CONTROLLED, 8, (char*)&tie_breaker);
if (!is_heartbeat) {
uint64_t tie_breaker = 0; // always be controlled
stun_msg_create(msg, STUN_CLASS_REQUEST | STUN_METHOD_BINDING);
char username[584];
memset(username, 0, sizeof(username));
snprintf(username, sizeof(username), "%s:%s", agent->remote_ufrag, agent->local_ufrag);
stun_msg_write_attr(msg, STUN_ATTR_TYPE_USERNAME, strlen(username), username);
stun_msg_write_attr(msg, STUN_ATTR_TYPE_PRIORITY, 4, (char*)&agent->nominated_pair->priority);
if (agent->mode == AGENT_MODE_CONTROLLING) {
stun_msg_write_attr(msg, STUN_ATTR_TYPE_USE_CANDIDATE, 0, NULL);
stun_msg_write_attr(msg, STUN_ATTR_TYPE_ICE_CONTROLLING, 8, (char*)&tie_breaker);
} else {
stun_msg_write_attr(msg, STUN_ATTR_TYPE_ICE_CONTROLLED, 8, (char*)&tie_breaker);
}
stun_msg_finish(msg, STUN_CREDENTIAL_SHORT_TERM, agent->remote_upwd, strlen(agent->remote_upwd));
}
else{
stun_msg_create(msg, STUN_CLASS_REQUEST | STUN_METHOD_BINDING);
stun_msg_finish(msg, STUN_CREDENTIAL_SHORT_TERM, agent->remote_upwd, strlen(agent->remote_upwd));
}
stun_msg_finish(msg, STUN_CREDENTIAL_SHORT_TERM, agent->remote_upwd, strlen(agent->remote_upwd));
}

void agent_process_stun_request(Agent* agent, StunMessage* stun_msg, Address* addr) {
Expand Down Expand Up @@ -447,32 +453,36 @@ void agent_set_remote_description(Agent* agent, char* description) {
LOGD("candidate pairs num: %d", agent->candidate_pairs_num);
}

int agent_connectivity_check(Agent* agent) {
int agent_connectivity_check(Agent* agent, int is_heartbeat) {
char addr_string[ADDRSTRLEN];
uint8_t buf[1400];
StunMessage msg;
if (!is_heartbeat) {
if (agent->nominated_pair->state != ICE_CANDIDATE_STATE_INPROGRESS) {
LOGI("nominated pair is not in progress");
return -1;
}


if (agent->nominated_pair->state != ICE_CANDIDATE_STATE_INPROGRESS) {
LOGI("nominated pair is not in progress");
return -1;
}

memset(&msg, 0, sizeof(msg));
memset(&msg, 0, sizeof(msg));

if (agent->nominated_pair->conncheck % AGENT_CONNCHECK_PERIOD == 0) {
addr_to_string(&agent->nominated_pair->remote->addr, addr_string, sizeof(addr_string));
LOGD("send binding request to remote ip: %s, port: %d", addr_string, agent->nominated_pair->remote->addr.port);
agent_create_binding_request(agent, &msg);
agent_socket_send(agent, &agent->nominated_pair->remote->addr, msg.buf, msg.size);
}
if (agent->nominated_pair->conncheck % AGENT_CONNCHECK_PERIOD == 0) {
addr_to_string(&agent->nominated_pair->remote->addr, addr_string, sizeof(addr_string));
LOGD("send binding request to remote ip: %s, port: %d", addr_string, agent->nominated_pair->remote->addr.port);
agent_create_binding_request(agent, &msg, 0);
agent_socket_send(agent, &agent->nominated_pair->remote->addr, msg.buf, msg.size);
}

agent_recv(agent, buf, sizeof(buf));
agent_recv(agent, buf, sizeof(buf));

if (agent->nominated_pair->state == ICE_CANDIDATE_STATE_SUCCEEDED) {
agent->selected_pair = agent->nominated_pair;
return 0;
if (agent->nominated_pair->state == ICE_CANDIDATE_STATE_SUCCEEDED) {
agent->selected_pair = agent->nominated_pair;
return 0;
}
} else {
agent_create_binding_request(agent, &msg, 1);
agent_socket_send(agent, &agent->nominated_pair->remote->addr, msg.buf, msg.size);
}

return -1;
}

Expand Down
2 changes: 1 addition & 1 deletion src/agent.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ void agent_set_remote_description(Agent* agent, char* description);

int agent_select_candidate_pair(Agent* agent);

int agent_connectivity_check(Agent* agent);
int agent_connectivity_check(Agent* agent, int is_heartbeat);

void agent_clear_candidates(Agent* agent);

Expand Down
14 changes: 11 additions & 3 deletions src/peer_connection.c
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "sctp.h"
#include "sdp.h"


#define STATE_CHANGED(pc, curr_state) \
if (pc->oniceconnectionstatechange && pc->state != curr_state) { \
pc->oniceconnectionstatechange(curr_state, pc->config.user_data); \
Expand All @@ -29,6 +30,7 @@ struct PeerConnection {

Sdp local_sdp;
Sdp remote_sdp;
time_t last_binding_request_time;

void (*onicecandidate)(char* sdp, void* user_data);
void (*oniceconnectionstatechange)(PeerConnectionState state, void* user_data);
Expand Down Expand Up @@ -422,7 +424,7 @@ int peer_connection_loop(PeerConnection* pc) {
case PEER_CONNECTION_CHECKING:
if (agent_select_candidate_pair(&pc->agent) < 0) {
STATE_CHANGED(pc, PEER_CONNECTION_FAILED);
} else if (agent_connectivity_check(&pc->agent) == 0) {
} else if (agent_connectivity_check(&pc->agent, 0) == 0) {
STATE_CHANGED(pc, PEER_CONNECTION_CONNECTED);
}
break;
Expand All @@ -437,12 +439,19 @@ int peer_connection_loop(PeerConnection* pc) {
sctp_create_association(&pc->sctp, &pc->dtls_srtp);
pc->sctp.userdata = pc->config.user_data;
}

pc->last_binding_request_time = time(NULL);
STATE_CHANGED(pc, PEER_CONNECTION_COMPLETED);
}
break;
case PEER_CONNECTION_COMPLETED:

time_t current_time = time(NULL);
if (current_time - pc->last_binding_request_time >= 8) {
agent_connectivity_check(&pc->agent, 1);
LOGI("heartbeat sent!");
pc->last_binding_request_time = current_time;
}

#if (CONFIG_VIDEO_BUFFER_SIZE) > 0
data = buffer_peak_head(pc->video_rb, &bytes);
if (data) {
Expand Down Expand Up @@ -502,7 +511,6 @@ int peer_connection_loop(PeerConnection* pc) {
LOGW("Unknown data");
}
}

if (CONFIG_KEEPALIVE_TIMEOUT > 0 && (ports_get_epoch_time() - pc->agent.binding_request_time) > CONFIG_KEEPALIVE_TIMEOUT) {
LOGI("binding request timeout");
STATE_CHANGED(pc, PEER_CONNECTION_CLOSED);
Expand Down
14 changes: 11 additions & 3 deletions src/peer_signaling.c
Original file line number Diff line number Diff line change
Expand Up @@ -209,9 +209,17 @@ static void peer_signaling_on_pub_event(const char* msg, size_t size) {
break;
}

if (state == PEER_CONNECTION_NEW) {
peer_connection_set_remote_description(g_ps.pc, item->valuestring);
result = cJSON_CreateString("");
switch (state) {
case PEER_CONNECTION_NEW:
case PEER_CONNECTION_DISCONNECTED:
case PEER_CONNECTION_FAILED:
case PEER_CONNECTION_CLOSED: {
g_ps.id = id;
peer_connection_set_remote_description(g_ps.pc, item->valuestring);
} break;
default: {
error = cJSON_CreateRaw(RPC_ERROR_INTERNAL_ERROR);
} break;
}

} else if (strcmp(item->valuestring, RPC_METHOD_STATE) == 0) {
Expand Down