-
Notifications
You must be signed in to change notification settings - Fork 25
RTPEngine offer answer in opensips
RTPEngine offer/answer for interop between DTLS-SRTP capable, and non DTLS-SRTP capable user agents
We need to know if the UAC is DTLS capabe, if the UAS is DTLS capable, and what type of offer/answer scenario this is to be able to pass the correct flags to rtpengine, and to call the appropriate function.
To detect if a UAC is a DTLS capable user agent, we look for the ws, or wss transport in its Via header, then set a flag:
# Detect if UAC is websockets client and set flag for later processing
if ($(hdr(Via){via.transport}{s.tolower}) == "ws" || $(hdr(Via){via.transport}{s.tolower}) == "wss") {
setflag(uac_ws);
}
To detect if a UAS is DTLS capable, we do the same check, but when they register. We then set an attribute AVP which is restored on lookup().
# If the client is using websocket (webrtc) and save the attribute for detection later on location lookup
if ( isflagset(uac_ws) ) {
$avp(attr)="websocket";
}
if (!save("location","p0v")) {
sl_reply_error();
}
Now for each branch, we must check the attribute avp, so you must have a branch route for processing rtpengine handling.
branch_route[rtpengine] {
$var(branch_log)="branch[" + $T_branch_idx + "] :";
# set a branch flag based on the attribute avp
if( $(avp(attr)[$T_branch_idx]) == "websocket" ) {
setbflag(uas_ws);
}
xlog("L_INFO","$var(branch_log) $cs: $rm: message flags: $mf\n");
xlog("L_INFO","$var(branch_log) $cs: $rm: branch flags: $bf\n");
# handle rtp proxying for both initial and sequential requests
if ( (is_method("INVITE") || is_method("ACK") || is_method("PRACK")) && has_body("application/sdp") ) {
# set rtpengine flags based on whether uac or uas are websockets
if (isflagset(uac_ws) && isbflagset(uas_ws)) {
$var(rtpengine_flags) = "ICE=force-relay DTLS=passive";
xlog("L_INFO","$var(branch_log) $cs: $rm: uac and uas are both websockets\n");
}
else if (isflagset(uac_ws) && !isbflagset(uas_ws)) {
$var(rtpengine_flags) = "RTP/AVP replace-session-connection replace-origin ICE=remove";
xlog("L_INFO","$var(branch_log) $cs: $rm: uac is ws uas is not\n");
}
else if (!isflagset(uac_ws) && isbflagset(uas_ws)) {
$var(rtpengine_flags) = "UDP/TLS/RTP/SAVPF ICE=force";
xlog("L_INFO","$var(branch_log) $cs: $rm: uas is ws uac is not\n");
}
else if (!isflagset(uac_ws) && !isbflagset(uas_ws)) {
$var(rtpengine_flags) = "RTP/AVP replace-session-connection replace-origin ICE=remove";
xlog("L_INFO","$var(branch_log) $cs: $rm: neither uac or uas are websocket\n");
}
if( is_method("ACK") || is_method("PRACK") ){
xlog("L_INFO","$var(branch_log) $cs: $rm: rtpengine answer $var(rtpengine_flags)\n");
rtpengine_answer("$var(rtpengine_flags)");
} else {
rtpengine_offer("$var(rtpengine_flags)");
xlog("L_INFO","$var(branch_log) $cs: $rm: rtpengine offer $var(rtpengine_flags)\n");
}
}
}
Likewise, we must process all responses individually in reply route.
onreply_route["reply"] {
$var(reply_log)="onreply_route :";
xlog("L_INFO","$var(reply_log) $cs: $rs: response\n");
xlog("L_INFO","$var(reply_log) $cs: $rs: message flags: $mf\n");
xlog("L_INFO","$var(reply_log) $cs: $rs: branch flags: $bf\n");
# rtp proxying for responses
if ( has_body("application/sdp") ) {
# set rtpengine flags based on whether uac or uas are websockets
if (isflagset(uac_ws) && isbflagset(uas_ws)) {
$var(rtpengine_flags) = "ICE=force-relay DTLS=passive";
xlog("L_INFO","$var(reply_log) $cs: $rs: uac and uas are both websockets\n");
}
else if (isflagset(uac_ws) && !isbflagset(uas_ws)) {
$var(rtpengine_flags) = "UDP/TLS/RTP/SAVPF ICE=force";
xlog("L_INFO","$var(reply_log) $cs: $rs: uac is ws uas is not\n");
}
else if (!isflagset(uac_ws) && isbflagset(uas_ws)) {
$var(rtpengine_flags) = "RTP/AVP replace-session-connection replace-origin ICE=remove";
xlog("L_INFO","$var(reply_log) $cs: $rs: uas is ws uac is not\n");
}
else if (!isflagset(uac_ws) && !isbflagset(uas_ws)) {
$var(rtpengine_flags) = "RTP/AVP replace-session-connection replace-origin ICE=remove";
xlog("L_INFO","$var(reply_log) $cs: $rs: neither uac or uas are websocket\n");
}
if ( $rs=="183" ) {
xlog("L_INFO","$var(reply_log) $cs: $rs: rtpengine offer $var(rtpengine_flags)\n");
rtpengine_offer("$var(rtpengine_flags)");
} else if ( $rs=="200" ) {
xlog("L_INFO","$var(reply_log) $cs: $rs: rtpengine answer $var(rtpengine_flags)\n");
rtpengine_answer("$var(rtpengine_flags)");
}
}