Commit adbd8a9f authored by Ghislain MARY's avatar Ghislain MARY

Change stream destination when ICE processing is successful.

parent 344e0926
......@@ -117,7 +117,6 @@ typedef struct _IceCandidate {
uint16_t componentID; /**< component ID between 1 and 256: usually 1 for RTP component and 2 for RTCP component */
struct _IceCandidate *base; /**< Pointer to the candidate that is the base of the current one */
bool_t is_default; /**< Boolean value telling whether this candidate is a default candidate or not */
// TODO: relatedAddr
} IceCandidate;
/**
......@@ -134,7 +133,7 @@ typedef struct _IceCandidatePair {
uint8_t retransmissions; /**< Number of retransmissions for the connectivity check sent for the candidate pair */
IceRole role; /**< Role of the agent when the connectivity check has been sent for the candidate pair */
bool_t is_default; /**< Boolean value telling whether this candidate pair is a default candidate pair or not */
bool_t is_nominated;
bool_t is_nominated; /**< Boolean value telling whether this candidate pair is nominated or not */
bool_t wait_transaction_timeout; /**< Boolean value telling to create a new binding request on retransmission timeout */
} IceCandidatePair;
......@@ -149,8 +148,8 @@ typedef struct _IcePairFoundation {
} IcePairFoundation;
typedef struct _IceValidCandidatePair {
IceCandidatePair *valid;
IceCandidatePair *generated_from;
IceCandidatePair *valid; /**< Pointer to a valid candidate pair (it may be in the check list or not */
IceCandidatePair *generated_from; /**< Pointer to the candidate pair that generated the connectivity check producing the valid candidate pair */
} IceValidCandidatePair;
/**
......@@ -160,9 +159,9 @@ typedef struct _IceValidCandidatePair {
* Check lists are added to an ICE session using the ice_session_add_check_list() function.
*/
typedef struct _IceCheckList {
IceSession *session;
char *remote_ufrag;
char *remote_pwd;
IceSession *session; /**< Pointer to the ICE session */
char *remote_ufrag; /**< Remote username fragment for this check list (provided via SDP by the peer) */
char *remote_pwd; /**< Remote password for this check list (provided via SDP by the peer) */
MSList *local_candidates; /**< List of IceCandidate structures */
MSList *remote_candidates; /**< List of IceCandidate structures */
MSList *pairs; /**< List of IceCandidatePair structures */
......@@ -171,12 +170,17 @@ typedef struct _IceCheckList {
MSList *valid_list; /**< List of IceValidCandidatePair structures */
MSList *foundations; /**< List of IcePairFoundation structures */
MSList *componentIDs; /**< List of uint16_t */
IceCheckListState state;
IceCheckListState state; /**< Global state of the ICE check list */
uint64_t ta_time; /**< Time when the Ta timer has been processed for the last time */
uint32_t foundation_generator;
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"{
#endif
......@@ -202,11 +206,13 @@ MS2_PUBLIC void ice_session_destroy(IceSession *session);
/**
* Allocate a new ICE check list.
*
* @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
* @return Pointer to the allocated check list
*
* A check list must be allocated for each media stream of a media session and be added to an ICE session using the ice_session_add_check_list() function.
*/
MS2_PUBLIC IceCheckList * ice_check_list_new(void);
MS2_PUBLIC IceCheckList * ice_check_list_new(ice_check_list_success_cb success_cb, void *stream_ptr);
/**
* Destroy a previously allocated ICE check list.
......@@ -401,10 +407,33 @@ MS2_PUBLIC void ice_session_choose_default_candidates(IceSession *session);
*/
MS2_PUBLIC void ice_session_pair_candidates(IceSession *session);
/**
* Core ICE check list processing.
*
* 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, 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, RtpSession *session, 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.
*
* @param cl A pointer to a check list
* @param addr A pointer to the buffer to use to store the remote address
* @param addr_len The size of the buffer to use to store the remote address
* @param rtp_port A pointer to the location to store the RTP port to
* @param rtcp_port A pointer to the location to store the RTCP port to
*
* This function will usually be called from within the success callback defined while creating the ICE check list with ice_check_list_new().
*/
MS2_PUBLIC void ice_get_remote_addr_and_ports_from_valid_pairs(IceCheckList *cl, char *addr, int addr_len, int *rtp_port, int *rtcp_port);
/**
* Dump an ICE session in the traces (debug function).
*/
......
......@@ -667,6 +667,18 @@ void audio_stream_set_features(AudioStream *st, uint32_t features){
st->features = features;
}
static 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");
......@@ -678,7 +690,7 @@ AudioStream *audio_stream_new(int locport, bool_t ipv6){
/*some filters are created right now to allow configuration by the application before start() */
stream->rtpsend=ms_filter_new(MS_RTP_SEND_ID);
stream->ice_check_list=ice_check_list_new();
stream->ice_check_list=ice_check_list_new(audio_stream_set_remote_from_ice, stream);
if (ec_desc!=NULL)
stream->ec=ms_filter_new_from_desc(ec_desc);
......
......@@ -71,11 +71,23 @@ typedef struct _CheckList_Bool {
bool_t result;
} CheckList_Bool;
typedef struct _CheckList_MSListPtr {
IceCheckList *cl;
MSList **list;
} CheckList_MSListPtr;
typedef struct _LocalCandidate_RemoteCandidate {
IceCandidate *local;
IceCandidate *remote;
} LocalCandidate_RemoteCandidate;
typedef struct _Addr_Ports {
char *addr;
int addr_len;
int *rtp_port;
int *rtcp_port;
} Addr_Ports;
static int ice_compare_transport_addresses(const IceTransportAddress *ta1, const IceTransportAddress *ta2);
static int ice_compare_pair_priorities(const IceCandidatePair *p1, const IceCandidatePair *p2);
......@@ -190,7 +202,7 @@ static void ice_check_list_init(IceCheckList *cl)
cl->foundation_generator = 1;
}
IceCheckList * ice_check_list_new(void)
IceCheckList * ice_check_list_new(ice_check_list_success_cb success_cb, void *stream_ptr)
{
IceCheckList *cl = ms_new(IceCheckList, 1);
if (cl == NULL) {
......@@ -198,6 +210,8 @@ IceCheckList * ice_check_list_new(void)
return NULL;
}
ice_check_list_init(cl);
cl->success_cb = success_cb;
cl->stream_ptr = stream_ptr;
return cl;
}
......@@ -1647,7 +1661,7 @@ static void ice_conclude_processing(IceCheckList *cl, RtpSession *rtp_session)
cl->state = ICL_Completed;
ms_message("Finished ICE check list processing successfully!");
ice_dump_valid_list(cl);
// TODO: Call a callback function to notify the application of the end of the ICE processing for this check list and start transmitting media for this stream
cl->success_cb(cl->stream_ptr, cl);
// TODO: Check if all the check lists of the ICE session are completed
}
} else {
......@@ -1815,6 +1829,51 @@ void ice_session_set_base_for_srflx_candidates(IceSession *session)
}
/******************************************************************************
* RESULT ACCESSORS *
*****************************************************************************/
static void ice_get_valid_pair_for_componentID(uint16_t *componentID, CheckList_MSListPtr *cm)
{
MSList *elem = ms_list_find_custom(cm->cl->valid_list, (MSCompareFunc)ice_find_nominated_valid_pair_from_componentID, componentID);
if (elem != NULL) {
IceValidCandidatePair *valid_pair = (IceValidCandidatePair *)elem->data;
*cm->list = ms_list_append(*cm->list, valid_pair->valid);
}
}
static MSList * ice_get_valid_pairs(IceCheckList *cl)
{
CheckList_MSListPtr cm;
MSList *valid_pairs = NULL;
cm.cl = cl;
cm.list = &valid_pairs;
ms_list_for_each2(cl->componentIDs, (void (*)(void*,void*))ice_get_valid_pair_for_componentID, &cm);
return valid_pairs;
}
static void ice_get_addr_and_ports_from_valid_pair(IceCandidatePair *pair, Addr_Ports *addr_ports)
{
if (pair->local->componentID == 1) {
strncpy(addr_ports->addr, pair->remote->taddr.ip, addr_ports->addr_len);
*(addr_ports->rtp_port) = pair->remote->taddr.port;
} else if (pair->local->componentID == 2) {
*(addr_ports->rtcp_port) = pair->remote->taddr.port;
}
}
void ice_get_remote_addr_and_ports_from_valid_pairs(IceCheckList *cl, char *addr, int addr_len, int *rtp_port, int *rtcp_port) {
Addr_Ports addr_ports;
MSList *ice_pairs = ice_get_valid_pairs(cl);
addr_ports.addr = addr;
addr_ports.addr_len = addr_len;
addr_ports.rtp_port = rtp_port;
addr_ports.rtcp_port = rtcp_port;
ms_list_for_each2(ice_pairs, (void (*)(void*,void*))ice_get_addr_and_ports_from_valid_pair, &addr_ports);
ms_list_free(ice_pairs);
}
/******************************************************************************
* DEBUG FUNCTIONS *
*****************************************************************************/
......
......@@ -203,12 +203,24 @@ static void choose_display_name(VideoStream *stream){
#endif
}
static 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);
stream->evq=ortp_ev_queue_new();
stream->rtpsend=ms_filter_new(MS_RTP_SEND_ID);
stream->ice_check_list=ice_check_list_new();
stream->ice_check_list=ice_check_list_new(video_stream_set_remote_from_ice, stream);
rtp_session_register_event_queue(stream->session,stream->evq);
stream->sent_vsize.width=MS_VIDEO_SIZE_CIF_W;
stream->sent_vsize.height=MS_VIDEO_SIZE_CIF_H;
......
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