Skip to content

Commit

Permalink
Implement trickle ICE (pjsip#2588)
Browse files Browse the repository at this point in the history
Squash & merge trickle-ice dev branch to master.
  • Loading branch information
nanangizz authored Dec 11, 2020
1 parent dad6a34 commit d65cacd
Show file tree
Hide file tree
Showing 41 changed files with 3,145 additions and 404 deletions.
1 change: 1 addition & 0 deletions pjlib-util/src/pjlib-util-test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ static void print_stack(int sig)
static void init_signals()
{
signal(SIGSEGV, &print_stack);
signal(SIGABRT, &print_stack);
}

#else
Expand Down
1 change: 1 addition & 0 deletions pjlib/src/pjlib-test/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ static void print_stack(int sig)
static void init_signals()
{
signal(SIGSEGV, &print_stack);
signal(SIGABRT, &print_stack);
}

#else
Expand Down
155 changes: 155 additions & 0 deletions pjmedia/include/pjmedia/transport_ice.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,25 @@ typedef struct pjmedia_ice_cb
pj_status_t status,
void *user_data);

/**
* Callback to report a new ICE local candidate, e.g: after successful
* STUN Binding, after a successful TURN allocation. Only new candidates
* whose type is server reflexive or relayed will be notified via this
* callback. This callback also indicates end-of-candidate via parameter
* 'last'.
*
* Trickle ICE can use this callback to convey the new candidate
* to remote agent and monitor end-of-candidate indication.
*
* @param tp PJMEDIA ICE transport.
* @param cand The new local candidate, can be NULL when the last
* local candidate initialization failed/timeout.
* @param last PJ_TRUE if this is the last of local candidate.
*/
void (*on_new_candidate)(pjmedia_transport *tp,
const pj_ice_sess_cand *cand,
pj_bool_t last);

} pjmedia_ice_cb;


Expand Down Expand Up @@ -289,6 +308,142 @@ PJ_DECL(pj_status_t) pjmedia_ice_remove_ice_cb(pjmedia_transport *tp,
void *user_data);


/**
* Check if trickle support is signalled in the specified SDP. This function
* will check trickle indication in the media level first, if not found, it
* will check in the session level.
*
* @param sdp The SDP.
* @param med_idx The media index to be checked.
*
* @return PJ_TRUE if trickle ICE indication is found.
*/
PJ_DECL(pj_bool_t) pjmedia_ice_sdp_has_trickle(const pjmedia_sdp_session *sdp,
unsigned med_idx);


/**
* Update check list after new local or remote ICE candidates are added,
* or signal ICE session that trickling is done. Application typically would
* call this function after finding (and conveying) new local ICE candidates
* to remote, after receiving remote ICE candidates, or after receiving
* end-of-candidates indication.
*
* This function is only applicable when trickle ICE is not disabled and
* after ICE connectivity checks are started, i.e: after
* pjmedia_transport_media_start() has been invoked.
*
* @param tp The ICE media transport.
* @param rem_ufrag Remote ufrag, as seen in the SDP received from
* the remote agent.
* @param rem_passwd Remote password, as seen in the SDP received from
* the remote agent.
* @param rcand_cnt Number of new remote candidates in the array.
* @param rcand New remote candidates array.
* @param rcand_end Set to PJ_TRUE if remote has signalled
* end-of-candidate.
*
* @return PJ_SUCCESS, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjmedia_ice_trickle_update(
pjmedia_transport *tp,
const pj_str_t *rem_ufrag,
const pj_str_t *rem_passwd,
unsigned rcand_cnt,
const pj_ice_sess_cand rcand[],
pj_bool_t rcand_end);


/**
* Decode trickle ICE info from the specified SDP.
*
* @param sdp The SDP containing trickle ICE info.
* @param media_index The media index.
* @param mid Output, media ID.
* @param ufrag Output, ufrag.
* @param passwd Output, password.
* @param cand_cnt On input, maximum number of candidate array.
* On output, the number of candidates.
* @param cand Output, the candidates.
* @param end_of_cand Output, end of candidate indication.
*
* @return PJ_SUCCESS, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjmedia_ice_trickle_decode_sdp(
const pjmedia_sdp_session *sdp,
unsigned media_index,
pj_str_t *mid,
pj_str_t *ufrag,
pj_str_t *passwd,
unsigned *cand_cnt,
pj_ice_sess_cand cand[],
pj_bool_t *end_of_cand);


/**
* Encode trickle ICE info into the specified SDP. This function may generate
* the following SDP attributes:
* - Media ID, "a=mid".
* - ICE ufrag & password, "a=ice-ufrag" & "a=ice-pwd".
* - Trickle ICE support indication, "a=ice-options:trickle".
* - ICE candidates, "a=candidate".
* - End of candidate indication, "a=end-of-candidates".
*
* @param sdp_pool The memory pool for generating SDP attributes.
* @param sdp The SDP to be updated.
* @param mid The media ID.
* @param ufrag The ufrag, optional.
* @param passwd The password, optional.
* @param cand_cnt The number of local candidates, can be zero.
* @param cand The local candidates.
* @param end_of_cand End of candidate indication.
*
* @return PJ_SUCCESS, or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjmedia_ice_trickle_encode_sdp(
pj_pool_t *sdp_pool,
pjmedia_sdp_session *sdp,
const pj_str_t *mid,
const pj_str_t *ufrag,
const pj_str_t *passwd,
unsigned cand_cnt,
const pj_ice_sess_cand cand[],
pj_bool_t end_of_cand);


/**
* Check if trickling ICE has found any new local candidates.
*
* @param tp The ICE media transport.
*
* @return PJ_TRUE if new local canditates are available.
*/
PJ_DECL(pj_bool_t) pjmedia_ice_trickle_has_new_cand(pjmedia_transport *tp);


/**
* Check for new local candidates, and if any new or forced, update the
* specified SDP with all current local candidates to be conveyed to remote
* (e.g: via SIP INFO).
*
* @param tp The ICE media transport.
* @param sdp_pool The memory pool for generating SDP attributes.
* @param sdp The SDP.
* @param p_end_of_cand Optional, pointer to receive the indication that
* candidate gathering has been completed.
*
* @return PJ_SUCCESS if any new local candidates is found and
* SDP is updated with the candidates,
* PJ_ENOTFOUND if no new local candidate is found,
* or the appropriate error code.
*/
PJ_DECL(pj_status_t) pjmedia_ice_trickle_send_local_cand(
pjmedia_transport *tp,
pj_pool_t *sdp_pool,
pjmedia_sdp_session *sdp,
pj_bool_t *p_end_of_cand);


PJ_END_DECL


Expand Down
36 changes: 18 additions & 18 deletions pjmedia/src/pjmedia/stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -1939,24 +1939,6 @@ static void on_rx_rtp( pjmedia_tp_cb_param *param)
goto on_return;
}

/* Handle incoming DTMF. */
if (hdr->pt == stream->rx_event_pt) {
pj_timestamp ts;

/* Ignore out-of-order packet as it will be detected as new
* digit. Also ignore duplicate packet as it serves no use.
*/
if (seq_st.status.flag.outorder || seq_st.status.flag.dup) {
goto on_return;
}

/* Get the timestamp of the event */
ts.u64 = pj_ntohl(hdr->ts);

handle_incoming_dtmf(stream, &ts, payload, payloadlen);
goto on_return;
}

/* See if source address of RTP packet is different than the
* configured address, and check if we need to tell the
* media transport to switch RTP remote address.
Expand Down Expand Up @@ -2013,6 +1995,24 @@ static void on_rx_rtp( pjmedia_tp_cb_param *param)
}
}

/* Handle incoming DTMF. */
if (hdr->pt == stream->rx_event_pt) {
pj_timestamp ts;

/* Ignore out-of-order packet as it will be detected as new
* digit. Also ignore duplicate packet as it serves no use.
*/
if (seq_st.status.flag.outorder || seq_st.status.flag.dup) {
goto on_return;
}

/* Get the timestamp of the event */
ts.u64 = pj_ntohl(hdr->ts);

handle_incoming_dtmf(stream, &ts, payload, payloadlen);
goto on_return;
}

/* Put "good" packet to jitter buffer, or reset the jitter buffer
* when RTP session is restarted.
*/
Expand Down
Loading

0 comments on commit d65cacd

Please sign in to comment.