Commit 59405e81 authored by Ghislain MARY's avatar Ghislain MARY

Use event queues to notify the end of ICE check list processing to the application.

parent e78531ce
......@@ -186,13 +186,9 @@ typedef struct _IceCheckList {
uint64_t ta_time; /**< Time when the Ta timer has been processed for the last time */
uint64_t keepalive_time; /**< Time when the last keepalive packet has been sent for this stream */
uint32_t foundation_generator; /**< Autoincremented integer to generate unique foundation values */
void (*success_cb)(void *stream, struct _IceCheckList *cl); /**< Callback function called when ICE processing finishes successfully for the check list */
void *stream_ptr; /**< Pointer to the media stream corresponding to the check list, to be used as an argument in the success callback */
} IceCheckList;
typedef void (*ice_check_list_success_cb)(void *stream, IceCheckList *cl);
#ifdef __cplusplus
extern "C"{
......@@ -225,14 +221,6 @@ MS2_PUBLIC void ice_session_destroy(IceSession *session);
*/
MS2_PUBLIC IceCheckList * ice_check_list_new(void);
/**
* Register the callback function to be called when the processing of the check list is successful
*
* @param success_cb Pointer to a callback function to be called when the processing of the check list is successful
* @param stream_ptr Pointer to the media stream to be passed as a parameter to the callback function
*/
MS2_PUBLIC void ice_check_list_register_success_cb(IceCheckList *cl, ice_check_list_success_cb success_cb, void *stream_ptr);
/**
* Destroy a previously allocated ICE check list.
*
......@@ -468,14 +456,14 @@ MS2_PUBLIC void ice_session_pair_candidates(IceSession *session);
*
* This function is called from the audiostream or the videostream and is NOT to be called by the user.
*/
void ice_check_list_process(IceCheckList* cl, const RtpSession* rtp_session);
void ice_check_list_process(IceCheckList* cl, RtpSession* rtp_session);
/**
* Handle a STUN packet that has been received.
*
* This function is called from the audiostream or the videostream and is NOT to be called by the user.
*/
void ice_handle_stun_packet(IceCheckList* cl, const RtpSession* rtp_session, const OrtpEventData* evt_data);
void ice_handle_stun_packet(IceCheckList* cl, RtpSession* rtp_session, const OrtpEventData* evt_data);
/**
* Get the remote address, RTP port and RTCP port to use to send the stream once the ICE process has finished successfully.
......
......@@ -271,9 +271,6 @@ MS2_PUBLIC void audio_stream_enable_zrtp(AudioStream *stream, OrtpZrtpParams *pa
/* enable SRTP on the audio stream */
MS2_PUBLIC bool_t audio_stream_enable_strp(AudioStream* stream, enum ortp_srtp_crypto_suite_t suite, const char* snd_key, const char* rcv_key);
/* set the remote address to send the audio stream to according to an ICE check list */
MS2_PUBLIC void audio_stream_set_remote_from_ice(void *stream, IceCheckList *cl);
/*****************
Video Support
*****************/
......@@ -378,9 +375,6 @@ MS2_PUBLIC bool_t video_stream_enable_strp(VideoStream* stream, enum ortp_srtp_c
/* if enabled, the display filter will internaly rotate the video, according to the device orientation */
MS2_PUBLIC void video_stream_enable_display_filter_auto_rotate(VideoStream* stream, bool_t enable);
/* set the remote address to send the video stream to according to an ICE check list */
void video_stream_set_remote_from_ice(void *stream, IceCheckList *cl);
/**
* Small API to display a local preview window.
**/
......
......@@ -207,6 +207,18 @@ static void audio_stream_process_rtcp(AudioStream *stream, mblk_t *m){
}while(rtcp_next_packet(m));
}
static void audio_stream_set_remote_from_ice(AudioStream *st){
char addr[64];
int rtp_port = 0;
int rtcp_port = 0;
if (st->ice_check_list == NULL) return;
memset(addr, '\0', sizeof(addr));
ice_get_remote_addr_and_ports_from_valid_pairs(st->ice_check_list, addr, sizeof(addr), &rtp_port, &rtcp_port);
ms_message("audio_stream_set_remote_from_ice: addr=%s rtp_port=%u rtcp_port=%u", addr, rtp_port, rtcp_port);
rtp_session_set_remote_addr_full(st->session, addr, rtp_port, rtcp_port);
}
void audio_stream_iterate(AudioStream *stream){
if (stream->is_beginning && ms_time(NULL)-stream->start_time>15){
rtp_session_set_rtcp_report_interval(stream->session,5000);
......@@ -225,6 +237,8 @@ void audio_stream_iterate(AudioStream *stream){
ms_message("audio_stream_iterate(): local statistics available\n\tLocal's current jitter buffer size:%f ms",rtp_session_get_jitter_stats(stream->session)->jitter_buffer_size_ms);
}else if ((evt==ORTP_EVENT_STUN_PACKET_RECEIVED)&&(stream->ice_check_list)){
ice_handle_stun_packet(stream->ice_check_list,stream->session,ortp_event_get_data(ev));
}else if ((evt==ORTP_EVENT_ICE_CHECK_LIST_PROCESSING_FINISHED)&&(stream->ice_check_list)&&(ortp_event_get_data(ev)->info.ice_processing_successful==TRUE)){
audio_stream_set_remote_from_ice(stream);
}
ortp_event_destroy(ev);
}
......@@ -666,18 +680,6 @@ void audio_stream_set_features(AudioStream *st, uint32_t features){
st->features = features;
}
void audio_stream_set_remote_from_ice(void *stream, IceCheckList *cl){
char addr[64];
int rtp_port = 0;
int rtcp_port = 0;
AudioStream *st = (AudioStream *)stream;
memset(addr, '\0', sizeof(addr));
ice_get_remote_addr_and_ports_from_valid_pairs(cl, addr, sizeof(addr), &rtp_port, &rtcp_port);
ms_message("audio_stream_set_remote_from_ice: addr=%s rtp_port=%u rtcp_port=%u", addr, rtp_port, rtcp_port);
rtp_session_set_remote_addr_full(st->session, addr, rtp_port, rtcp_port);
}
AudioStream *audio_stream_new(int locport, bool_t ipv6){
AudioStream *stream=(AudioStream *)ms_new0(AudioStream,1);
MSFilterDesc *ec_desc=ms_filter_lookup_by_name("MSOslec");
......
......@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "mediastreamer2/msticker.h"
#include "mediastreamer2/ice.h"
#include "ortp/ortp.h"
#define ICE_MAX_NB_CANDIDATES 10
......@@ -90,13 +91,18 @@ typedef struct _Addr_Ports {
} Addr_Ports;
// TODO: We need this function to push events in the rtp event queue but it should not be made public in oRTP.
// Should we not move ice processing to oRTP instead?
extern void rtp_session_dispatch_event(RtpSession *session, OrtpEvent *ev);
static int ice_compare_transport_addresses(const IceTransportAddress *ta1, const IceTransportAddress *ta2);
static int ice_compare_pair_priorities(const IceCandidatePair *p1, const IceCandidatePair *p2);
static int ice_find_nominated_valid_pair_from_componentID(const IceValidCandidatePair* valid_pair, const uint16_t* componentID);
static void ice_pair_set_state(IceCandidatePair *pair, IceCandidatePairState state);
static void ice_compute_candidate_foundation(IceCandidate *candidate, IceCheckList *cl);
static void ice_set_credentials(char **ufrag, char **pwd, const char *ufrag_str, const char *pwd_str);
static void ice_conclude_processing(IceCheckList* cl, const RtpSession* rtp_session);
static void ice_conclude_processing(IceCheckList* cl, RtpSession* rtp_session);
/******************************************************************************
......@@ -219,12 +225,6 @@ IceCheckList * ice_check_list_new(void)
return cl;
}
void ice_check_list_register_success_cb(IceCheckList *cl, ice_check_list_success_cb success_cb, void *stream_ptr)
{
cl->success_cb = success_cb;
cl->stream_ptr = stream_ptr;
}
static void ice_compute_pair_priority(IceCandidatePair *pair, const IceRole *role)
{
/* Use formula defined in 5.7.2 to compute pair priority. */
......@@ -961,7 +961,7 @@ static void ice_update_nominated_flag_on_binding_request(const IceCheckList *cl,
}
}
static void ice_handle_received_binding_request(IceCheckList *cl, const RtpSession *rtp_session, const OrtpEventData *evt_data, const StunMessage *msg, const StunAddress4 *remote_addr, const char *src6host)
static void ice_handle_received_binding_request(IceCheckList *cl, RtpSession *rtp_session, const OrtpEventData *evt_data, const StunMessage *msg, const StunAddress4 *remote_addr, const char *src6host)
{
IceTransportAddress taddr;
IceCandidate *prflx_candidate;
......@@ -1123,8 +1123,6 @@ static void ice_update_pair_states_on_binding_response(IceCheckList *cl, IceCand
/* Change the state of all Frozen pairs with the same foundation to Waiting. */
ms_list_for_each2(cl->check_list, (void (*)(void*,void*))ice_change_state_of_frozen_pairs_to_waiting, pair);
// TODO: If there is a pair in the valid list for every component of this media stream, unfreeze checks for other media streams
}
/* Update the nominated flag of a candidate pair according to 7.1.3.2.4. */
......@@ -1149,7 +1147,7 @@ static int ice_find_not_failed_or_succeeded_pair(const IceCandidatePair *pair, c
return !((pair->state != ICP_Failed) && (pair->state != ICP_Succeeded));
}
static void ice_handle_received_binding_response(IceCheckList *cl, const RtpSession *rtp_session, const OrtpEventData *evt_data, const StunMessage *msg, const StunAddress4 *remote_addr)
static void ice_handle_received_binding_response(IceCheckList *cl, RtpSession *rtp_session, const OrtpEventData *evt_data, const StunMessage *msg, const StunAddress4 *remote_addr)
{
IceCandidatePair *succeeded_pair;
IceCandidatePair *valid_pair;
......@@ -1185,7 +1183,7 @@ static void ice_handle_received_binding_response(IceCheckList *cl, const RtpSess
ice_conclude_processing(cl, rtp_session);
}
static void ice_handle_received_error_response(IceCheckList *cl, const RtpSession *rtp_session, const StunMessage *msg)
static void ice_handle_received_error_response(IceCheckList *cl, RtpSession *rtp_session, const StunMessage *msg)
{
IceCandidatePair *pair;
MSList *elem = ms_list_find_custom(cl->check_list, (MSCompareFunc)ice_find_pair_from_transactionID, &msg->msgHdr.tr_id);
......@@ -1221,7 +1219,7 @@ static void ice_handle_received_error_response(IceCheckList *cl, const RtpSessio
ice_conclude_processing(cl, rtp_session);
}
void ice_handle_stun_packet(IceCheckList *cl, const RtpSession *rtp_session, const OrtpEventData *evt_data)
void ice_handle_stun_packet(IceCheckList *cl, RtpSession *rtp_session, const OrtpEventData *evt_data)
{
StunMessage msg;
StunAddress4 remote_addr;
......@@ -1762,10 +1760,11 @@ static void ice_continue_processing_on_next_check_list(IceCheckList *cl)
}
/* Conclude ICE processing as defined in 8.1. */
static void ice_conclude_processing(IceCheckList *cl, const RtpSession *rtp_session)
static void ice_conclude_processing(IceCheckList *cl, RtpSession *rtp_session)
{
CheckList_RtpSession cr;
CheckList_Bool cb;
OrtpEvent *ev;
if (cl->state == ICL_Running) {
if (cl->session->role == IR_Controlling) {
......@@ -1783,14 +1782,16 @@ static void ice_conclude_processing(IceCheckList *cl, const RtpSession *rtp_sess
if (cb.result == TRUE) {
if (cl->state != ICL_Completed) {
cl->state = ICL_Completed;
ms_message("Finished ICE check list processing successfully!");
ms_message("ice: Finished ICE check list processing successfully!");
ice_dump_valid_list(cl);
/* Call the success callback function. */
cl->success_cb(cl->stream_ptr, cl);
/* Initialise keepalive time. */
cl->keepalive_time = cl->session->ticker->time;
ice_check_list_stop_retransmissions(cl);
ice_continue_processing_on_next_check_list(cl);
/* Notify the application of the successful processing. */
ev = ortp_event_new(ORTP_EVENT_ICE_CHECK_LIST_PROCESSING_FINISHED);
ortp_event_get_data(ev)->info.ice_processing_successful = TRUE;
rtp_session_dispatch_event(rtp_session, ev);
}
} else {
cb.cl = cl;
......@@ -1799,9 +1800,12 @@ static void ice_conclude_processing(IceCheckList *cl, const RtpSession *rtp_sess
if (cb.result == TRUE) {
if (cl->state != ICL_Failed) {
cl->state = ICL_Failed;
ms_message("Failed ICE check list processing!");
// TODO: Call a callback function to notify the application of the end of the ICE processing for this check list
ms_message("ice: Failed ICE check list processing!");
ice_dump_valid_list(cl);
/* Notify the application of the failed processing. */
ev = ortp_event_new(ORTP_EVENT_ICE_CHECK_LIST_PROCESSING_FINISHED);
ortp_event_get_data(ev)->info.ice_processing_successful = FALSE;
rtp_session_dispatch_event(rtp_session, ev);
}
}
}
......@@ -1835,7 +1839,7 @@ static void ice_check_retransmissions_pending(const IceCandidatePair *pair, bool
}
/* Schedule checks as defined in 5.8. */
void ice_check_list_process(IceCheckList *cl, const RtpSession *rtp_session)
void ice_check_list_process(IceCheckList *cl, RtpSession *rtp_session)
{
CheckList_RtpSession_Time params;
IceCandidatePairState state;
......
......@@ -155,6 +155,18 @@ static void video_steam_process_rtcp(VideoStream *stream, mblk_t *m){
}while(rtcp_next_packet(m));
}
static void video_stream_set_remote_from_ice(VideoStream *stream){
char addr[64];
int rtp_port = 0;
int rtcp_port = 0;
if (stream->ice_check_list == NULL) return;
memset(addr, '\0', sizeof(addr));
ice_get_remote_addr_and_ports_from_valid_pairs(stream->ice_check_list, addr, sizeof(addr), &rtp_port, &rtcp_port);
ms_message("video_stream_set_remote_from_ice: addr=%s rtp_port=%u rtcp_port=%u", addr, rtp_port, rtcp_port);
rtp_session_set_remote_addr_full(stream->session, addr, rtp_port, rtcp_port);
}
void video_stream_iterate(VideoStream *stream){
/*
if (stream->output!=NULL)
......@@ -170,6 +182,8 @@ void video_stream_iterate(VideoStream *stream){
video_steam_process_rtcp(stream,evd->packet);
}else if ((evt == ORTP_EVENT_STUN_PACKET_RECEIVED) && (stream->ice_check_list)) {
ice_handle_stun_packet(stream->ice_check_list,stream->session,ortp_event_get_data(ev));
}else if ((evt==ORTP_EVENT_ICE_CHECK_LIST_PROCESSING_FINISHED)&&(stream->ice_check_list)&&(ortp_event_get_data(ev)->info.ice_processing_successful==TRUE)){
video_stream_set_remote_from_ice(stream);
}
ortp_event_destroy(ev);
}
......@@ -201,18 +215,6 @@ static void choose_display_name(VideoStream *stream){
#endif
}
void video_stream_set_remote_from_ice(void *stream, IceCheckList *cl){
char addr[64];
int rtp_port = 0;
int rtcp_port = 0;
VideoStream *st = (VideoStream *)stream;
memset(addr, '\0', sizeof(addr));
ice_get_remote_addr_and_ports_from_valid_pairs(cl, addr, sizeof(addr), &rtp_port, &rtcp_port);
ms_message("video_stream_set_remote_from_ice: addr=%s rtp_port=%u rtcp_port=%u", addr, rtp_port, rtcp_port);
rtp_session_set_remote_addr_full(st->session, addr, rtp_port, rtcp_port);
}
VideoStream *video_stream_new(int locport, bool_t use_ipv6){
VideoStream *stream = (VideoStream *)ms_new0 (VideoStream, 1);
stream->session=create_duplex_rtpsession(locport,use_ipv6);
......
......@@ -606,7 +606,6 @@ void setup_media_streams(MediastreamDatas* args) {
if (args->ice_local_candidates_nb || args->ice_remote_candidates_nb) {
args->audio->ice_check_list = ice_check_list_new();
ice_check_list_register_success_cb(args->audio->ice_check_list, audio_stream_set_remote_from_ice, args->audio);
rtp_session_set_pktinfo(args->audio->session,TRUE);
ice_session_add_check_list(args->ice_session, args->audio->ice_check_list);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment