asterisk: Implement and test SIP Digest Authorization
Related: SYS#6782 Change-Id: Ib469f1906927a3f246876040086ff115fbf4c032
This commit is contained in:
parent
95058fd76c
commit
05eaa1a531
|
@ -11,6 +11,7 @@ module Asterisk_Tests {
|
||||||
* SPDX-License-Identifier: GPL-2.0-or-later
|
* SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import from TCCOpenSecurity_Functions all;
|
||||||
import from General_Types all;
|
import from General_Types all;
|
||||||
import from Osmocom_Types all;
|
import from Osmocom_Types all;
|
||||||
import from Native_Functions all;
|
import from Native_Functions all;
|
||||||
|
@ -44,6 +45,7 @@ type component ConnHdlr extends SIP_ConnHdlr {
|
||||||
type record ConnHdlrPars {
|
type record ConnHdlrPars {
|
||||||
float t_guard,
|
float t_guard,
|
||||||
charstring user,
|
charstring user,
|
||||||
|
charstring password,
|
||||||
SipUrl registrar_sip_url,
|
SipUrl registrar_sip_url,
|
||||||
SipAddr registrar_sip_record,
|
SipAddr registrar_sip_record,
|
||||||
CallidString registrar_sip_call_id,
|
CallidString registrar_sip_call_id,
|
||||||
|
@ -55,9 +57,11 @@ type record ConnHdlrPars {
|
||||||
}
|
}
|
||||||
|
|
||||||
template (value) ConnHdlrPars t_Pars(charstring user,
|
template (value) ConnHdlrPars t_Pars(charstring user,
|
||||||
charstring displayname := "\"Anonymous\"") := {
|
charstring displayname := "\"Anonymous\"",
|
||||||
|
charstring password := "secret") := {
|
||||||
t_guard := 30.0,
|
t_guard := 30.0,
|
||||||
user := user,
|
user := user,
|
||||||
|
password := password,
|
||||||
registrar_sip_url := valueof(ts_SipUrlHost(mp_remote_sip_host)),
|
registrar_sip_url := valueof(ts_SipUrlHost(mp_remote_sip_host)),
|
||||||
registrar_sip_record := ts_SipAddr(ts_HostPort(mp_remote_sip_host),
|
registrar_sip_record := ts_SipAddr(ts_HostPort(mp_remote_sip_host),
|
||||||
ts_UserInfo(user),
|
ts_UserInfo(user),
|
||||||
|
@ -188,38 +192,87 @@ private function f_tr_Via_response(Via via_req) return template (present) Via {
|
||||||
via_resp_params);
|
via_resp_params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function f_tr_To_response(SipAddr to_req) return template (present) SipAddr {
|
||||||
|
return tr_SipAddr_from_val(to_req);
|
||||||
|
}
|
||||||
|
|
||||||
function f_SIP_register() runs on ConnHdlr return PDU_SIP_Response
|
function f_SIP_register() runs on ConnHdlr return PDU_SIP_Response
|
||||||
{
|
{
|
||||||
var template (present) PDU_SIP_Response exp;
|
var template (present) PDU_SIP_Response exp;
|
||||||
|
var Authorization authorization;
|
||||||
|
var Via via := g_pars.registrar_via;
|
||||||
|
var SipAddr from_sipaddr := g_pars.registrar_sip_record;
|
||||||
|
var charstring branch_value;
|
||||||
|
|
||||||
|
branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
|
||||||
|
f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
|
||||||
|
g_pars.registrar_sip_call_id,
|
||||||
|
g_pars.registrar_sip_seq_nr);
|
||||||
|
|
||||||
|
via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "branch", branch_value);
|
||||||
|
from_sipaddr.params := f_sip_param_set(from_sipaddr.params, "tag", f_sip_rand_tag());
|
||||||
SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_url,
|
SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_url,
|
||||||
g_pars.registrar_sip_call_id,
|
g_pars.registrar_sip_call_id,
|
||||||
|
from_sipaddr,
|
||||||
g_pars.registrar_sip_record,
|
g_pars.registrar_sip_record,
|
||||||
g_pars.registrar_sip_record,
|
via,
|
||||||
g_pars.registrar_via,
|
|
||||||
g_pars.registrar_sip_seq_nr,
|
g_pars.registrar_sip_seq_nr,
|
||||||
g_pars.local_contact,
|
g_pars.local_contact,
|
||||||
ts_Expires("7200")));
|
ts_Expires("7200")));
|
||||||
|
|
||||||
exp := tr_SIP_Response_REGISTER_Unauthorized(
|
exp := tr_SIP_Response_REGISTER_Unauthorized(
|
||||||
g_pars.registrar_sip_call_id,
|
g_pars.registrar_sip_call_id,
|
||||||
g_pars.registrar_sip_record,
|
from_sipaddr,
|
||||||
g_pars.registrar_sip_record,
|
f_tr_To_response(g_pars.registrar_sip_record),
|
||||||
f_tr_Via_response(g_pars.registrar_via),
|
f_tr_Via_response(via),
|
||||||
*,
|
*,
|
||||||
|
tr_WwwAuthenticate({tr_Challenge_digestCln(?)}),
|
||||||
g_pars.registrar_sip_seq_nr);
|
g_pars.registrar_sip_seq_nr);
|
||||||
as_SIP_expect_resp(exp);
|
as_SIP_expect_resp(exp);
|
||||||
|
|
||||||
/* Do the registering after calculating the md5 hash, etc. */
|
/* Digest Auth: RFC 2617 */
|
||||||
|
authorization := f_sip_digest_gen_Authorization(g_rx_sip_resp.msgHeader.wwwAuthenticate,
|
||||||
|
g_pars.user, g_pars.password,
|
||||||
|
"REGISTER", "sip:" & mp_remote_sip_host)
|
||||||
|
|
||||||
|
/* New transaction: */
|
||||||
|
g_pars.registrar_sip_seq_nr := g_pars.registrar_sip_seq_nr + 1;
|
||||||
|
branch_value := f_sip_gen_branch(f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
|
||||||
|
f_sip_SipAddr_to_str(g_pars.registrar_sip_record),
|
||||||
|
g_pars.registrar_sip_call_id,
|
||||||
|
g_pars.registrar_sip_seq_nr);
|
||||||
|
via.viaBody[0].viaParams := f_sip_param_set(via.viaBody[0].viaParams, "branch", branch_value);
|
||||||
|
|
||||||
|
SIP.send(ts_SIP_REGISTER(g_pars.registrar_sip_url,
|
||||||
|
g_pars.registrar_sip_call_id,
|
||||||
|
from_sipaddr,
|
||||||
|
g_pars.registrar_sip_record,
|
||||||
|
via,
|
||||||
|
g_pars.registrar_sip_seq_nr,
|
||||||
|
g_pars.local_contact,
|
||||||
|
ts_Expires("7200"),
|
||||||
|
authorization := authorization));
|
||||||
|
|
||||||
|
/* Wait for OK answer */
|
||||||
|
exp := tr_SIP_Response(
|
||||||
|
g_pars.registrar_sip_call_id,
|
||||||
|
from_sipaddr,
|
||||||
|
f_tr_To_response(g_pars.registrar_sip_record),
|
||||||
|
f_tr_Via_response(via),
|
||||||
|
*,
|
||||||
|
"REGISTER", 200,
|
||||||
|
g_pars.registrar_sip_seq_nr, "OK");
|
||||||
|
as_SIP_expect_resp(exp);
|
||||||
|
|
||||||
|
/* Prepare for next use: */
|
||||||
|
g_pars.registrar_sip_seq_nr := g_pars.registrar_sip_seq_nr + 1;
|
||||||
return g_rx_sip_resp;
|
return g_rx_sip_resp;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Successful MO Call, which is subsequently released by SIP side */
|
/* Test SIP registration of local clients */
|
||||||
private function f_TC_internal_registration(charstring id) runs on ConnHdlr {
|
private function f_TC_internal_registration(charstring id) runs on ConnHdlr {
|
||||||
|
|
||||||
f_SIP_register();
|
f_SIP_register();
|
||||||
/* now call is fully established */
|
|
||||||
f_sleep(2.0);
|
|
||||||
// f_SIP_deregister();
|
// f_SIP_deregister();
|
||||||
setverdict(pass);
|
setverdict(pass);
|
||||||
}
|
}
|
||||||
|
@ -233,6 +286,11 @@ testcase TC_internal_registration() runs on test_CT {
|
||||||
vc_conn.done;
|
vc_conn.done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testcase TC_selftest() runs on test_CT {
|
||||||
|
f_sip_digest_selftest();
|
||||||
|
setverdict(pass);
|
||||||
|
}
|
||||||
|
|
||||||
control {
|
control {
|
||||||
execute( TC_internal_registration() );
|
execute( TC_internal_registration() );
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ BASEDIR=../deps
|
||||||
. ../gen_links.sh.inc
|
. ../gen_links.sh.inc
|
||||||
|
|
||||||
DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
|
DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
|
||||||
FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h"
|
FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h "
|
||||||
|
FILES+="TCCOpenSecurity_Functions.ttcn TCCOpenSecurity.cc TCCOpenSecurity_Functions.hh "
|
||||||
gen_links $DIR $FILES
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
|
DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
|
||||||
|
|
|
@ -14,6 +14,7 @@ FILES="
|
||||||
SIPmsg_PT.cc
|
SIPmsg_PT.cc
|
||||||
TCCConversion.cc
|
TCCConversion.cc
|
||||||
TCCInterface.cc
|
TCCInterface.cc
|
||||||
|
TCCOpenSecurity.cc
|
||||||
"
|
"
|
||||||
|
|
||||||
../regen-makefile.sh -e $NAME $FILES
|
../regen-makefile.sh -e $NAME $FILES
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
module SIP_Templates {
|
module SIP_Templates {
|
||||||
|
|
||||||
import from SIPmsg_Types all;
|
import from SIPmsg_Types all;
|
||||||
|
import from TCCConversion_Functions all;
|
||||||
|
import from TCCOpenSecurity_Functions all;
|
||||||
|
import from Native_Functions all;
|
||||||
import from Osmocom_Types all;
|
import from Osmocom_Types all;
|
||||||
|
import from Misc_Helpers all;
|
||||||
|
|
||||||
/* wrapper type to encapsulate the Addr_Union + parameter list used in From, To. ... */
|
/* wrapper type to encapsulate the Addr_Union + parameter list used in From, To. ... */
|
||||||
type record SipAddr {
|
type record SipAddr {
|
||||||
|
@ -11,6 +15,26 @@ type record SipAddr {
|
||||||
|
|
||||||
const charstring c_SIP_VERSION := "SIP/2.0";
|
const charstring c_SIP_VERSION := "SIP/2.0";
|
||||||
|
|
||||||
|
template (value) GenericParam ts_Param(template (value) charstring id,
|
||||||
|
template (omit) charstring paramValue := omit) := {
|
||||||
|
id := id,
|
||||||
|
paramValue := paramValue
|
||||||
|
}
|
||||||
|
template (present) GenericParam tr_Param(template (present) charstring id := ?,
|
||||||
|
template charstring paramValue := *) := {
|
||||||
|
id := id,
|
||||||
|
paramValue := paramValue
|
||||||
|
}
|
||||||
|
function f_ts_Param_omit(template (value) charstring id,
|
||||||
|
template (omit) charstring paramValue := omit)
|
||||||
|
return template (omit) GenericParam
|
||||||
|
{
|
||||||
|
if (istemplatekind(paramValue, "omit")) {
|
||||||
|
return omit;
|
||||||
|
}
|
||||||
|
return ts_Param(id, paramValue);
|
||||||
|
}
|
||||||
|
|
||||||
template (value) SipUrl ts_SipUrl(template (value) HostPort host_port,
|
template (value) SipUrl ts_SipUrl(template (value) HostPort host_port,
|
||||||
template (omit) UserInfo user_info := omit) := {
|
template (omit) UserInfo user_info := omit) := {
|
||||||
scheme := "sip",
|
scheme := "sip",
|
||||||
|
@ -31,6 +55,49 @@ template (present) SipUrl tr_SipUrl(template (present) HostPort host_port := ?,
|
||||||
template (value) SipUrl ts_SipUrlHost(template (value) charstring host)
|
template (value) SipUrl ts_SipUrlHost(template (value) charstring host)
|
||||||
:= ts_SipUrl(ts_HostPort(host));
|
:= ts_SipUrl(ts_HostPort(host));
|
||||||
|
|
||||||
|
template (value) Credentials ts_Credentials_DigestResponse(template (value) CommaParam_List digestResponse) := {
|
||||||
|
digestResponse := digestResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
template (value) Credentials ts_Credentials_DigestResponseMD5(
|
||||||
|
template (value) charstring username,
|
||||||
|
template (value) charstring realm,
|
||||||
|
template (value) charstring nonce,
|
||||||
|
template (value) charstring uri,
|
||||||
|
template (value) charstring response,
|
||||||
|
template (value) charstring opaque,
|
||||||
|
template (value) charstring algorithm := "MD5",
|
||||||
|
template (value) charstring qop := "auth",
|
||||||
|
template (omit) charstring cnonce := omit,
|
||||||
|
template (omit) charstring nc := omit
|
||||||
|
) := {
|
||||||
|
digestResponse := {
|
||||||
|
// Already added by digestResponse automatically:
|
||||||
|
//ts_Param("Digest", omit),
|
||||||
|
ts_Param("username", f_sip_str_quote(username)),
|
||||||
|
ts_Param("realm", f_sip_str_quote(realm)),
|
||||||
|
ts_Param("nonce", f_sip_str_quote(nonce)),
|
||||||
|
ts_Param("uri", f_sip_str_quote(uri)),
|
||||||
|
ts_Param("response", f_sip_str_quote(response)),
|
||||||
|
ts_Param("opaque", f_sip_str_quote(opaque)),
|
||||||
|
ts_Param("algorithm", algorithm),
|
||||||
|
ts_Param("qop", qop),
|
||||||
|
// FIXME: If "omit" is passed, these below end up in;
|
||||||
|
// "Dynamic test case error: Performing a valueof or send operation on a non-specific template of type @SIPmsg_Types.GenericParam"
|
||||||
|
f_ts_Param_omit("cnonce", f_sip_str_quote(cnonce)),
|
||||||
|
f_ts_Param_omit("nc", nc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template (value) Credentials ts_Credentials_OtherAuth(template (value) OtherAuth otherResponse) := {
|
||||||
|
otherResponse := otherResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
template (value) Authorization ts_Authorization(template (value) Credentials body) := {
|
||||||
|
fieldName := AUTHORIZATION_E,
|
||||||
|
body := body
|
||||||
|
}
|
||||||
|
|
||||||
// [20.10]
|
// [20.10]
|
||||||
template (present) NameAddr tr_NameAddr(template (present) SipUrl addrSpec := ?,
|
template (present) NameAddr tr_NameAddr(template (present) SipUrl addrSpec := ?,
|
||||||
template charstring displayName := *) := {
|
template charstring displayName := *) := {
|
||||||
|
@ -262,7 +329,53 @@ template (present) Via tr_Via_from(template (present) HostPort host_port := ?,
|
||||||
viaParams := viaParams
|
viaParams := viaParams
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template (present) OtherAuth
|
||||||
|
tr_OtherAuth(template (present) charstring authScheme := ?,
|
||||||
|
template (present) CommaParam_List authParams := ?) := {
|
||||||
|
authScheme := authScheme,
|
||||||
|
authParams := authParams
|
||||||
|
}
|
||||||
|
|
||||||
|
template (value) OtherAuth
|
||||||
|
ts_OtherAuth(template (value) charstring authScheme,
|
||||||
|
template (value) CommaParam_List authParams) := {
|
||||||
|
authScheme := authScheme,
|
||||||
|
authParams := authParams
|
||||||
|
}
|
||||||
|
|
||||||
|
template (present) Challenge
|
||||||
|
tr_Challenge_digestCln(template (present) CommaParam_List digestCln := ?) := {
|
||||||
|
digestCln := digestCln
|
||||||
|
}
|
||||||
|
|
||||||
|
template (value) Challenge
|
||||||
|
ts_Challenge_digestCln(template (value) CommaParam_List digestCln) := {
|
||||||
|
digestCln := digestCln
|
||||||
|
}
|
||||||
|
|
||||||
|
template (present) Challenge
|
||||||
|
tr_Challenge_otherChallenge(template (present) OtherAuth otherChallenge := ?) := {
|
||||||
|
otherChallenge := otherChallenge
|
||||||
|
}
|
||||||
|
|
||||||
|
template (value) Challenge
|
||||||
|
ts_Challenge_otherChallenge(template (value) OtherAuth otherChallenge) := {
|
||||||
|
otherChallenge := otherChallenge
|
||||||
|
}
|
||||||
|
|
||||||
|
template (present) WwwAuthenticate
|
||||||
|
tr_WwwAuthenticate(template (present) Challenge_list challenge := ?) := {
|
||||||
|
fieldName := WWW_AUTHENTICATE_E,
|
||||||
|
challenge := challenge
|
||||||
|
}
|
||||||
|
|
||||||
|
template (value) WwwAuthenticate
|
||||||
|
ts_WwwAuthenticate(template (value) Challenge_list challenge) := {
|
||||||
|
fieldName := WWW_AUTHENTICATE_E,
|
||||||
|
challenge := challenge
|
||||||
|
}
|
||||||
|
|
||||||
template (value) MessageHeader ts_SIP_msgHeader_empty := c_SIP_msgHeader_empty;
|
template (value) MessageHeader ts_SIP_msgHeader_empty := c_SIP_msgHeader_empty;
|
||||||
template (value) MessageHeader
|
template (value) MessageHeader
|
||||||
|
@ -274,6 +387,7 @@ ts_SIP_msgh_std(template (value) CallidString call_id,
|
||||||
template (value) integer seq_nr,
|
template (value) integer seq_nr,
|
||||||
template (value) Via via,
|
template (value) Via via,
|
||||||
template (omit) ContentType content_type := omit,
|
template (omit) ContentType content_type := omit,
|
||||||
|
template (omit)Authorization authorization := omit,
|
||||||
template (value) Method_List allow_methods := c_SIP_defaultMethods,
|
template (value) Method_List allow_methods := c_SIP_defaultMethods,
|
||||||
template (omit) Expires expires := omit
|
template (omit) Expires expires := omit
|
||||||
) modifies ts_SIP_msgHeader_empty := {
|
) modifies ts_SIP_msgHeader_empty := {
|
||||||
|
@ -281,6 +395,7 @@ ts_SIP_msgh_std(template (value) CallidString call_id,
|
||||||
fieldName := ALLOW_E,
|
fieldName := ALLOW_E,
|
||||||
methods := allow_methods
|
methods := allow_methods
|
||||||
},
|
},
|
||||||
|
authorization := authorization,
|
||||||
callId := {
|
callId := {
|
||||||
fieldName := CALL_ID_E,
|
fieldName := CALL_ID_E,
|
||||||
callid := call_id
|
callid := call_id
|
||||||
|
@ -337,7 +452,8 @@ tr_SIP_msgh_std(template CallidString call_id,
|
||||||
template ContentType content_type := *,
|
template ContentType content_type := *,
|
||||||
template integer seq_nr := ?,
|
template integer seq_nr := ?,
|
||||||
template Method_List allow_methods := *,
|
template Method_List allow_methods := *,
|
||||||
template Expires expires := *
|
template Expires expires := *,
|
||||||
|
template WwwAuthenticate wwwAuthenticate := *
|
||||||
) modifies t_SIP_msgHeader_any := {
|
) modifies t_SIP_msgHeader_any := {
|
||||||
allow := tr_AllowMethods(allow_methods),
|
allow := tr_AllowMethods(allow_methods),
|
||||||
callId := {
|
callId := {
|
||||||
|
@ -363,7 +479,8 @@ tr_SIP_msgh_std(template CallidString call_id,
|
||||||
toParams := to_addr.params
|
toParams := to_addr.params
|
||||||
},
|
},
|
||||||
userAgent := *,
|
userAgent := *,
|
||||||
via := via
|
via := via,
|
||||||
|
wwwAuthenticate := wwwAuthenticate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -376,11 +493,13 @@ ts_SIP_REGISTER(template (value) SipUrl sip_url_host_port,
|
||||||
integer seq_nr,
|
integer seq_nr,
|
||||||
template (omit) Contact contact,
|
template (omit) Contact contact,
|
||||||
template (omit) Expires expires,
|
template (omit) Expires expires,
|
||||||
|
template (omit) Authorization authorization := omit,
|
||||||
template (omit) charstring body := omit) := {
|
template (omit) charstring body := omit) := {
|
||||||
requestLine := ts_SIP_ReqLine(REGISTER_E, sip_url_host_port),
|
requestLine := ts_SIP_ReqLine(REGISTER_E, sip_url_host_port),
|
||||||
msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
|
msgHeader := ts_SIP_msgh_std(call_id, from_addr, to_addr, contact,
|
||||||
"REGISTER", seq_nr, via,
|
"REGISTER", seq_nr, via,
|
||||||
f_ContentTypeOrOmit(ts_CT_SDP, body),
|
f_ContentTypeOrOmit(ts_CT_SDP, body),
|
||||||
|
authorization := authorization,
|
||||||
expires := expires),
|
expires := expires),
|
||||||
messageBody := body,
|
messageBody := body,
|
||||||
payload := omit
|
payload := omit
|
||||||
|
@ -511,15 +630,16 @@ template (present) PDU_SIP_Response
|
||||||
tr_SIP_Response(template CallidString call_id,
|
tr_SIP_Response(template CallidString call_id,
|
||||||
template SipAddr from_addr,
|
template SipAddr from_addr,
|
||||||
template SipAddr to_addr,
|
template SipAddr to_addr,
|
||||||
|
template (present) Via via := tr_Via_from(?),
|
||||||
template Contact contact,
|
template Contact contact,
|
||||||
template charstring method,
|
template charstring method,
|
||||||
template integer status_code,
|
template integer status_code,
|
||||||
template integer seq_nr := ?,
|
template integer seq_nr := ?,
|
||||||
template charstring reason := ?,
|
template charstring reason := ?,
|
||||||
template charstring body := ?) := {
|
template charstring body := *) := {
|
||||||
statusLine := tr_SIP_StatusLine(status_code, reason),
|
statusLine := tr_SIP_StatusLine(status_code, reason),
|
||||||
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
|
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
|
||||||
tr_Via_from(tr_HostPort(from_addr.addr.nameAddr.addrSpec.hostPort)),
|
via,
|
||||||
method, *, seq_nr),
|
method, *, seq_nr),
|
||||||
messageBody := body,
|
messageBody := body,
|
||||||
payload := omit
|
payload := omit
|
||||||
|
@ -533,6 +653,7 @@ tr_SIP_Response_REGISTER_Unauthorized(
|
||||||
template SipAddr to_addr,
|
template SipAddr to_addr,
|
||||||
template (present) Via via := tr_Via_from(?),
|
template (present) Via via := tr_Via_from(?),
|
||||||
template Contact contact := *,
|
template Contact contact := *,
|
||||||
|
template (present) WwwAuthenticate wwwAuthenticate := ?,
|
||||||
template integer seq_nr := ?,
|
template integer seq_nr := ?,
|
||||||
template charstring method := "REGISTER",
|
template charstring method := "REGISTER",
|
||||||
template integer status_code := 401,
|
template integer status_code := 401,
|
||||||
|
@ -541,11 +662,333 @@ tr_SIP_Response_REGISTER_Unauthorized(
|
||||||
statusLine := tr_SIP_StatusLine(status_code, reason),
|
statusLine := tr_SIP_StatusLine(status_code, reason),
|
||||||
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
|
msgHeader := tr_SIP_msgh_std(call_id, from_addr, to_addr, contact,
|
||||||
via,
|
via,
|
||||||
method, *, seq_nr),
|
method, *, seq_nr,
|
||||||
|
wwwAuthenticate := wwwAuthenticate),
|
||||||
messageBody := body,
|
messageBody := body,
|
||||||
payload := omit
|
payload := omit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function f_sip_param_find(GenericParam_List li,
|
||||||
|
template (present) charstring id := ?)
|
||||||
|
return template (omit) GenericParam {
|
||||||
|
var integer i;
|
||||||
|
|
||||||
|
for (i := 0; i < lengthof(li); i := i + 1) {
|
||||||
|
if (not ispresent(li[i])) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (match(li[i].id, id)) {
|
||||||
|
return li[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return omit;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_param_find_or_fail(GenericParam_List li,
|
||||||
|
template (present) charstring id := ?)
|
||||||
|
return GenericParam {
|
||||||
|
var template (omit) GenericParam parameter;
|
||||||
|
parameter := f_sip_param_find(li, id);
|
||||||
|
if (istemplatekind(parameter, "omit")) {
|
||||||
|
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
|
||||||
|
log2str("Param ", id, " not found in ", li));
|
||||||
|
}
|
||||||
|
return valueof(parameter);
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_param_get_value(GenericParam_List li,
|
||||||
|
template (present) charstring id := ?)
|
||||||
|
return template (omit) charstring {
|
||||||
|
var template (omit) GenericParam parameter;
|
||||||
|
parameter := f_sip_param_find(li, id);
|
||||||
|
if (istemplatekind(parameter, "omit")) {
|
||||||
|
return omit;
|
||||||
|
}
|
||||||
|
return parameter.paramValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_param_get_value_or_fail(GenericParam_List li,
|
||||||
|
template (present) charstring id := ?)
|
||||||
|
return template (omit) charstring {
|
||||||
|
var GenericParam parameter;
|
||||||
|
parameter := f_sip_param_find_or_fail(li, id);
|
||||||
|
return parameter.paramValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_param_get_value_present_or_fail(GenericParam_List li,
|
||||||
|
template (present) charstring id := ?)
|
||||||
|
return charstring {
|
||||||
|
var GenericParam parameter;
|
||||||
|
parameter := f_sip_param_find_or_fail(li, id);
|
||||||
|
if (not ispresent(parameter.paramValue)) {
|
||||||
|
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
|
||||||
|
log2str("Param ", id, " value not present in ", li));
|
||||||
|
}
|
||||||
|
return parameter.paramValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_param_match_value(GenericParam_List li,
|
||||||
|
template (present) charstring id := ?,
|
||||||
|
template charstring exp_paramValue := *)
|
||||||
|
return boolean {
|
||||||
|
var template (omit) charstring val;
|
||||||
|
val := f_sip_param_get_value_or_fail(li, id);
|
||||||
|
if (istemplatekind(val, "omit")) {
|
||||||
|
return istemplatekind(val, "omit") or istemplatekind(val, "*");
|
||||||
|
}
|
||||||
|
return match(valueof(val), exp_paramValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_param_match_value_or_fail(GenericParam_List li,
|
||||||
|
template (present) charstring id := ?,
|
||||||
|
template charstring exp_paramValue := *)
|
||||||
|
{
|
||||||
|
var template (omit) charstring val := f_sip_param_get_value_or_fail(li, id);
|
||||||
|
if (istemplatekind(val, "omit")) {
|
||||||
|
if (istemplatekind(val, "omit") or istemplatekind(val, "*")) {
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
|
||||||
|
log2str("Param ", id, " match failed: val ", val,
|
||||||
|
" vs exp ", exp_paramValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (not match(valueof(val), exp_paramValue)) {
|
||||||
|
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
|
||||||
|
log2str("Param ", id, " match failed: val ", val,
|
||||||
|
" vs exp ", exp_paramValue));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_param_remove(template (omit) GenericParam_List li_tpl, charstring id)
|
||||||
|
return GenericParam_List {
|
||||||
|
var integer i;
|
||||||
|
var GenericParam_List li;
|
||||||
|
var GenericParam_List new_li := {};
|
||||||
|
|
||||||
|
if (istemplatekind(li_tpl, "omit")) {
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
li := valueof(li_tpl);
|
||||||
|
for (i := 0; i < lengthof(li); i := i + 1) {
|
||||||
|
if (not ispresent(li[i]) or
|
||||||
|
not match(li[i].id, id)) {
|
||||||
|
new_li := new_li & {li[i]};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new_li;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_param_set(template (omit) GenericParam_List li_tpl, charstring id, charstring val)
|
||||||
|
return GenericParam_List {
|
||||||
|
var integer i;
|
||||||
|
var GenericParam_List li;
|
||||||
|
var GenericParam_List new_li := {};
|
||||||
|
var boolean found := false;
|
||||||
|
|
||||||
|
if (istemplatekind(li_tpl, "omit")) {
|
||||||
|
return { valueof(ts_Param(id, val)) };
|
||||||
|
}
|
||||||
|
|
||||||
|
li := valueof(li_tpl);
|
||||||
|
for (i := 0; i < lengthof(li); i := i + 1) {
|
||||||
|
if (not ispresent(li[i]) or
|
||||||
|
not match(li[i].id, id)) {
|
||||||
|
new_li := new_li & {li[i]};
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
new_li := new_li & { valueof(ts_Param(li[i].id, val)) };
|
||||||
|
found := true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (not found) {
|
||||||
|
new_li := new_li & { valueof(ts_Param(id, val)) };
|
||||||
|
}
|
||||||
|
return new_li;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure string is quoted. */
|
||||||
|
function f_sip_str_quote(template (value) charstring val) return charstring {
|
||||||
|
var charstring str := valueof(val);
|
||||||
|
if (lengthof(str) == 0) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str[0] != "\"") {
|
||||||
|
return "\"" & str & "\"";
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Make sure string is unquoted.
|
||||||
|
* Similar to unq() in RFC 2617 */
|
||||||
|
function f_sip_str_unquote(template (value) charstring val) return charstring {
|
||||||
|
var charstring str := valueof(val);
|
||||||
|
var integer len := lengthof(str);
|
||||||
|
|
||||||
|
if (len <= 1) {
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str[0] == "\"" and str[len - 1] == "\"") {
|
||||||
|
return substr(str, 1, len - 2);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC 2617 3.2.2.2 A1 */
|
||||||
|
function f_sip_digest_A1(charstring user, charstring realm, charstring password) return charstring {
|
||||||
|
|
||||||
|
/* RFC 2617 3.2.2.2 A1 */
|
||||||
|
var charstring A1 := f_sip_str_unquote(user) & ":" &
|
||||||
|
f_sip_str_unquote(realm) & ":" &
|
||||||
|
password;
|
||||||
|
var charstring digestA1 := f_str_tolower(f_calculateMD5(A1));
|
||||||
|
log("A1: md5('", A1, "') = ", digestA1);
|
||||||
|
return digestA1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC 2617 3.2.2.2 A2 */
|
||||||
|
function f_sip_digest_A2(charstring method, charstring uri) return charstring {
|
||||||
|
|
||||||
|
var charstring A2 := method & ":" & uri
|
||||||
|
var charstring digestA2 := f_str_tolower(f_calculateMD5(A2));
|
||||||
|
log("A2: md5('", A2, "') = ", digestA2);
|
||||||
|
return digestA2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC 2617 3.2.2.1 Request-Digest */
|
||||||
|
function f_sip_digest_RequestDigest(charstring digestA1, charstring nonce,
|
||||||
|
charstring nc, charstring cnonce,
|
||||||
|
charstring qop, charstring digestA2) return charstring {
|
||||||
|
var charstring digest_data := f_sip_str_unquote(nonce) & ":" &
|
||||||
|
nc & ":" &
|
||||||
|
cnonce & ":" &
|
||||||
|
f_sip_str_unquote(qop) & ":" &
|
||||||
|
digestA2;
|
||||||
|
var charstring req_digest := f_sip_digest_KD(digestA1, digest_data);
|
||||||
|
log("Request-Digest: md5('", digestA1, ":", digest_data ,"') = ", req_digest);
|
||||||
|
return req_digest;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC 2617 3.2.1 The WWW-Authenticate Response Header
|
||||||
|
* KD(secret, data) = H(concat(secret, ":", data))
|
||||||
|
*/
|
||||||
|
function f_sip_digest_KD(charstring secret, charstring data) return charstring {
|
||||||
|
return f_str_tolower(f_calculateMD5(secret & ":" & data));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Digest Auth: RFC 2617 */
|
||||||
|
function f_sip_digest_gen_Authorization(WwwAuthenticate www_authenticate,
|
||||||
|
charstring user, charstring password,
|
||||||
|
charstring method, charstring uri,
|
||||||
|
charstring cnonce := "0a4f113b", integer nc_int := 1) return Authorization {
|
||||||
|
var CommaParam_List digestCln;
|
||||||
|
var template (value) Authorization authorization;
|
||||||
|
var template (value) Credentials cred;
|
||||||
|
var template (omit) GenericParam rx_param;
|
||||||
|
|
||||||
|
digestCln := www_authenticate.challenge[0].digestCln;
|
||||||
|
|
||||||
|
var charstring algorithm;
|
||||||
|
rx_param := f_sip_param_find(digestCln, "algorithm");
|
||||||
|
if (istemplatekind(rx_param, "omit")) {
|
||||||
|
/* Assume MD5 if not set */
|
||||||
|
algorithm := "MD5"
|
||||||
|
} else {
|
||||||
|
algorithm := valueof(rx_param.paramValue);
|
||||||
|
if (f_strstr(algorithm, "MD5") == -1) {
|
||||||
|
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail,
|
||||||
|
log2str("Unexpected algorithm: ", algorithm));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var charstring realm := f_sip_param_get_value_present_or_fail(digestCln, "realm");
|
||||||
|
var charstring nonce := f_sip_param_get_value_present_or_fail(digestCln, "nonce");
|
||||||
|
var charstring opaque := f_sip_param_get_value_present_or_fail(digestCln, "opaque");
|
||||||
|
var charstring qop := f_sip_param_get_value_present_or_fail(digestCln, "qop");
|
||||||
|
|
||||||
|
if (f_strstr(qop, "auth") == -1) {
|
||||||
|
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, fail, log2str("Unexpected qop: ", qop));
|
||||||
|
}
|
||||||
|
var charstring selected_qop := "auth";
|
||||||
|
|
||||||
|
/* RFC 2617 3.2.2.2 A1 */
|
||||||
|
var charstring digestA1 := f_sip_digest_A1(user, realm, password);
|
||||||
|
/* RFC 2617 3.2.2.3 A2 */
|
||||||
|
var charstring digestA2 := f_sip_digest_A2(method, uri);
|
||||||
|
|
||||||
|
/* RFC 2617 3.2.2.1 Request-Digest */
|
||||||
|
var charstring nc := f_str_tolower(hex2str(int2hex(nc_int, 8)));
|
||||||
|
var charstring req_digest := f_sip_digest_RequestDigest(digestA1, nonce,
|
||||||
|
nc, cnonce,
|
||||||
|
selected_qop, digestA2);
|
||||||
|
|
||||||
|
cred := ts_Credentials_DigestResponseMD5(user, realm, nonce,
|
||||||
|
uri, req_digest,
|
||||||
|
opaque, algorithm, selected_qop, cnonce, nc);
|
||||||
|
|
||||||
|
authorization := ts_Authorization(cred);
|
||||||
|
return valueof(authorization);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RFC 2617 3.5 Example */
|
||||||
|
function f_sip_digest_selftest() {
|
||||||
|
/*
|
||||||
|
The following example assumes that an access-protected document is
|
||||||
|
being requested from the server via a GET request. The URI of the
|
||||||
|
document is "http://www.nowhere.org/dir/index.html". Both client and
|
||||||
|
server know that the username for this document is "Mufasa", and the
|
||||||
|
password is "Circle Of Life" (with one space between each of the
|
||||||
|
three words).
|
||||||
|
|
||||||
|
HTTP/1.1 401 Unauthorized
|
||||||
|
WWW-Authenticate: Digest
|
||||||
|
realm="testrealm@host.com",
|
||||||
|
qop="auth,auth-int",
|
||||||
|
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
|
||||||
|
opaque="5ccc069c403ebaf9f0171e9517f40e41"
|
||||||
|
|
||||||
|
Authorization: Digest username="Mufasa",
|
||||||
|
realm="testrealm@host.com",
|
||||||
|
nonce="dcd98b7102dd2f0e8b11d0f600bfb0c093",
|
||||||
|
uri="/dir/index.html",
|
||||||
|
qop=auth,
|
||||||
|
nc=00000001,
|
||||||
|
cnonce="0a4f113b",
|
||||||
|
response="6629fae49393a05397450978507c4ef1",
|
||||||
|
opaque="5ccc069c403ebaf9f0171e9517f40e41"
|
||||||
|
*/
|
||||||
|
var template (value) CommaParam_List digestCln := {
|
||||||
|
ts_Param("realm", f_sip_str_quote("testrealm@host.com")),
|
||||||
|
ts_Param("qop", f_sip_str_quote("auth,auth-int")),
|
||||||
|
ts_Param("nonce", f_sip_str_quote("dcd98b7102dd2f0e8b11d0f600bfb0c093")),
|
||||||
|
ts_Param("opaque", f_sip_str_quote("5ccc069c403ebaf9f0171e9517f40e41"))
|
||||||
|
};
|
||||||
|
var template (value) WwwAuthenticate www_authenticate :=
|
||||||
|
ts_WwwAuthenticate( { ts_Challenge_digestCln(digestCln) } )
|
||||||
|
|
||||||
|
var Authorization authorization :=
|
||||||
|
f_sip_digest_gen_Authorization(valueof(www_authenticate),
|
||||||
|
"Mufasa",
|
||||||
|
"Circle Of Life",
|
||||||
|
"GET",
|
||||||
|
"/dir/index.html",
|
||||||
|
cnonce := "0a4f113b",
|
||||||
|
nc_int := 1);
|
||||||
|
|
||||||
|
var CommaParam_List digestResp := authorization.body.digestResponse;
|
||||||
|
f_sip_param_match_value_or_fail(digestResp, "realm", f_sip_str_quote("testrealm@host.com"));
|
||||||
|
f_sip_param_match_value_or_fail(digestResp, "nonce", f_sip_str_quote("dcd98b7102dd2f0e8b11d0f600bfb0c093"));
|
||||||
|
f_sip_param_match_value_or_fail(digestResp, "uri", f_sip_str_quote("/dir/index.html"));
|
||||||
|
f_sip_param_match_value_or_fail(digestResp, "qop", "auth");
|
||||||
|
f_sip_param_match_value_or_fail(digestResp, "nc", "00000001");
|
||||||
|
f_sip_param_match_value_or_fail(digestResp, "cnonce", f_sip_str_quote("0a4f113b"));
|
||||||
|
f_sip_param_match_value_or_fail(digestResp, "response", f_sip_str_quote("6629fae49393a05397450978507c4ef1"));
|
||||||
|
f_sip_param_match_value_or_fail(digestResp, "opaque", f_sip_str_quote("5ccc069c403ebaf9f0171e9517f40e41"));
|
||||||
|
}
|
||||||
|
|
||||||
/* RFC 3261 8.1.1.5:
|
/* RFC 3261 8.1.1.5:
|
||||||
* "The sequence number value MUST be expressible as a 32-bit unsigned integer
|
* "The sequence number value MUST be expressible as a 32-bit unsigned integer
|
||||||
* and MUST be less than 2**31."
|
* and MUST be less than 2**31."
|
||||||
|
@ -555,4 +998,68 @@ function f_sip_rand_seq_nr() return integer {
|
||||||
return f_rnd_int(2147483648)
|
return f_rnd_int(2147483648)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Tags shall have at least 32 bit of randomness */
|
||||||
|
function f_sip_rand_tag() return charstring {
|
||||||
|
var integer rnd_int := f_rnd_int(4294967296);
|
||||||
|
return hex2str(int2hex(rnd_int, 8));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Generate a "branch" tag value.
|
||||||
|
* RFC 3261 p.105 section 8:
|
||||||
|
* "A common way to create this value is to compute a
|
||||||
|
* cryptographic hash of the To tag, From tag, Call-ID header
|
||||||
|
* field, the Request-URI of the request received (before
|
||||||
|
* translation), the topmost Via header, and the sequence number
|
||||||
|
* from the CSeq header field, in addition to any Proxy-Require
|
||||||
|
* and Proxy-Authorization header fields that may be present. The
|
||||||
|
* algorithm used to compute the hash is implementation-dependent,
|
||||||
|
* but MD5 (RFC 1321 [35]),expressed in hexadecimal, is a reasonable
|
||||||
|
* choice."
|
||||||
|
* See also Section 8.1.1.7:
|
||||||
|
* "The branch ID inserted by an element compliant with this
|
||||||
|
* specification MUST always begin with the characters "z9hG4bK"."
|
||||||
|
*/
|
||||||
|
const charstring sip_magic_cookie := "z9hG4bK";
|
||||||
|
function f_sip_gen_branch(charstring tag_to,
|
||||||
|
charstring tag_from,
|
||||||
|
charstring tag_call_id,
|
||||||
|
integer cseq) return charstring {
|
||||||
|
var charstring str := tag_to & tag_from & tag_call_id & int2str(cseq);
|
||||||
|
var charstring hash := f_calculateMD5(str);
|
||||||
|
var charstring branch := sip_magic_cookie & hash;
|
||||||
|
return branch;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_HostPort_to_str(HostPort host_port) return charstring {
|
||||||
|
var charstring str := "";
|
||||||
|
if (ispresent(host_port.host)) {
|
||||||
|
str := host_port.host;
|
||||||
|
}
|
||||||
|
if (ispresent(host_port.portField)) {
|
||||||
|
str := str & ":" & int2str(host_port.portField);
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_SipUrl_to_str(SipUrl uri) return charstring {
|
||||||
|
var charstring str := uri.scheme & f_sip_HostPort_to_str(uri.hostPort);
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_NameAddr_to_str(NameAddr naddr) return charstring {
|
||||||
|
if (ispresent(naddr.displayName)) {
|
||||||
|
return naddr.displayName & " <" & f_sip_SipUrl_to_str(naddr.addrSpec) & ">";
|
||||||
|
} else {
|
||||||
|
return f_sip_SipUrl_to_str(naddr.addrSpec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function f_sip_SipAddr_to_str(SipAddr sip_addr) return charstring {
|
||||||
|
if (ischosen(sip_addr.addr.nameAddr)) {
|
||||||
|
return f_sip_NameAddr_to_str(sip_addr.addr.nameAddr);
|
||||||
|
} else {
|
||||||
|
return f_sip_SipUrl_to_str(sip_addr.addr.addrSpecUnion);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -274,7 +274,9 @@ function f_establish_mt(inout CallPars cp) runs on ConnHdlr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OSC -> SIP */
|
/* OSC -> SIP */
|
||||||
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
|
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm,
|
||||||
|
tr_Via_from(tr_HostPort(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
|
||||||
|
*,
|
||||||
"INVITE", 100, ?, "Trying", *));
|
"INVITE", 100, ?, "Trying", *));
|
||||||
|
|
||||||
alt {
|
alt {
|
||||||
|
@ -328,7 +330,9 @@ function f_establish_mt(inout CallPars cp) runs on ConnHdlr {
|
||||||
SIP.clear;
|
SIP.clear;
|
||||||
|
|
||||||
/* 180 Ringing should not contain any SDP. */
|
/* 180 Ringing should not contain any SDP. */
|
||||||
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
|
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm,
|
||||||
|
tr_Via_from(tr_HostPort(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
|
||||||
|
*,
|
||||||
"INVITE", 180, ?, "Ringing", omit));
|
"INVITE", 180, ?, "Ringing", omit));
|
||||||
|
|
||||||
/* MSC -> OSC: After MT user has picked up and sent CC CONNECT */
|
/* MSC -> OSC: After MT user has picked up and sent CC CONNECT */
|
||||||
|
@ -342,7 +346,9 @@ function f_establish_mt(inout CallPars cp) runs on ConnHdlr {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* OSC -> SIP: OSC confirms call establishment to SIP side */
|
/* OSC -> SIP: OSC confirms call establishment to SIP side */
|
||||||
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, contact := ?,
|
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm,
|
||||||
|
tr_Via_from(tr_HostPort(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
|
||||||
|
contact := ?,
|
||||||
method := "INVITE", status_code := 200,
|
method := "INVITE", status_code := 200,
|
||||||
seq_nr := ?, reason := "OK",
|
seq_nr := ?, reason := "OK",
|
||||||
body := expect_sdp_to_sip));
|
body := expect_sdp_to_sip));
|
||||||
|
@ -506,7 +512,9 @@ function f_release_sip(inout CallPars cp) runs on ConnHdlr {
|
||||||
/* MSC -> OSC: Indicate GSM side release */
|
/* MSC -> OSC: Indicate GSM side release */
|
||||||
MNCC.send(ts_MNCC_REL_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
|
MNCC.send(ts_MNCC_REL_ind(cp.mncc_call_id, ts_MNCC_cause(0)));
|
||||||
/* OSC -> SIP: Confirmation to SIP side */
|
/* OSC -> SIP: Confirmation to SIP side */
|
||||||
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm, *,
|
as_SIP_expect_resp(tr_SIP_Response(cp.comp.sip_call_id, sip_addr_ext, sip_addr_gsm,
|
||||||
|
tr_Via_from(tr_HostPort(sip_addr_ext.addr.nameAddr.addrSpec.hostPort)),
|
||||||
|
*,
|
||||||
"BYE", 200, cp.comp.sip_seq_nr, "OK", omit));
|
"BYE", 200, cp.comp.sip_seq_nr, "OK", omit));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,8 @@ FILES="UD_PT.cc UD_PT.hh UD_PortType.ttcn UD_Types.ttcn"
|
||||||
gen_links $DIR $FILES
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
|
DIR=$BASEDIR/titan.Libraries.TCCUsefulFunctions/src
|
||||||
FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h"
|
FILES="TCCInterface_Functions.ttcn TCCConversion_Functions.ttcn TCCConversion.cc TCCInterface.cc TCCInterface_ip.h "
|
||||||
|
FILES+="TCCOpenSecurity_Functions.ttcn TCCOpenSecurity.cc TCCOpenSecurity_Functions.hh "
|
||||||
gen_links $DIR $FILES
|
gen_links $DIR $FILES
|
||||||
|
|
||||||
DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
|
DIR=$BASEDIR/titan.TestPorts.Common_Components.Socket-API/src
|
||||||
|
|
|
@ -17,6 +17,7 @@ FILES="
|
||||||
SIPmsg_PT.cc
|
SIPmsg_PT.cc
|
||||||
TCCConversion.cc
|
TCCConversion.cc
|
||||||
TCCInterface.cc
|
TCCInterface.cc
|
||||||
|
TCCOpenSecurity.cc
|
||||||
TELNETasp_PT.cc
|
TELNETasp_PT.cc
|
||||||
UD_PT.cc
|
UD_PT.cc
|
||||||
"
|
"
|
||||||
|
|
Loading…
Reference in New Issue