Rev 209 |
Rev 212 |
Go to most recent revision |
Blame |
Compare with Previous |
Last modification |
View Log
| Download
| SVN
| Bug Tracker
/**
* @author STF471
* @version $Id: LibIms_Steps.ttcn 210 2014-09-18 11:48:33Z rennoch $
* @desc This module provides the steps used by the test component for SIP-IMS tests.
* This module is part of LibImsV3.
*/
module LibIms_Steps {
// LibSip
import from LibSip_SIPTypesAndValues all;
import from LibSip_Templates all;
import from LibSip_Steps all;
import from LibSip_PIXITS all;
import from LibSip_Interface all;
import from LibSip_MessageBodyTypes all;
import from LibSip_Common all;
// LibIms
import from LibIms_Templates all;
import from LibIms_Interface all;
import from LibIms_SIPTypesAndValues all;
group externalfunctions {
} // end group externalfunctions
group parameterOperations {
/**
* @desc Adds new Via parameter
* @param p_message (request) SIP message to be used to prepair via header
*/
function f_addNewViaParameter(
in Request p_message
) runs on ImsComponent {
var integer v_intVia;
var integer i := 0;
if (isvalue(p_message.msgHeader.via)) {
v_intVia := lengthof(p_message.msgHeader.via.viaBody);
while (i < v_intVia) {
p_message.msgHeader.via.viaBody[v_intVia] := p_message.msgHeader.via.viaBody[v_intVia - 1];
v_intVia := v_intVia - 1;
}
vc_branch := c_branchCookie & f_getRndTag();
p_message.msgHeader.via.viaBody[0] := valueof(m_ViaBody_currIpaddr(vc_branch, vc_userprofile));
vc_via := p_message.msgHeader.via;
}
}
/**
* @desc Removes own Via parameter
* @param p_message (request) SIP message to be used to prepair via header
*/
function f_removeOwnViaParameter(
in Response p_message
) runs on ImsComponent {
var integer v_intVia;
var Via v_via := c_empty_Via;
var integer i := 0;
if (ispresent(p_message.msgHeader.via)) {
v_intVia := lengthof(p_message.msgHeader.via.viaBody) - 1;
for (i := 0; i < v_intVia; i := i + 1) {
v_via.viaBody[i] := p_message.msgHeader.via.viaBody[i + 1];
}
vc_via := v_via;
}
}
/**
* @desc Adds new RecordRoute parameter and removes Route parameter
* @param p_message (request) SIP message to be used to prepair via header
*/
function f_addNewRecordRouteAndRemoveRoutParameter(
in Request p_message
) runs on ImsComponent {
var integer v_intRoute, v_intRecordRoute;
var integer i := 1;
var RouteBody v_route1;
var Route v_newRoute;
v_newRoute.fieldName := ROUTE_E;
if (isvalue(p_message.msgHeader.route)) {
v_intRoute := lengthof(p_message.msgHeader.route.routeBody);
v_route1 := p_message.msgHeader.route.routeBody[0];
while (i < v_intRoute) {
v_newRoute.routeBody[i - 1] := p_message.msgHeader.route.routeBody[i];
i := i + 1;
}
vc_route := v_newRoute;
}
if (isvalue(p_message.msgHeader.recordRoute)) {
v_intRecordRoute := lengthof(p_message.msgHeader.recordRoute.routeBody);
while (0 < v_intRecordRoute) {
p_message.msgHeader.recordRoute.routeBody[v_intRecordRoute] := p_message.msgHeader.recordRoute.routeBody[v_intRecordRoute - 1];
v_intRecordRoute := v_intRecordRoute - 1;
}
p_message.msgHeader.recordRoute.routeBody[0] := v_route1;
vc_recordRoute := valueof(p_message.msgHeader.recordRoute);
}
}
/**
* @desc Adds new RecordRoute parameter (IMS)
* @param p_rr The recordRoute parameter to add
*/
function f_addNewRecordRouteIMS(
in RecordRoute p_rr
) runs on ImsComponent
return template RecordRoute {
var integer v_intRecordRoute;
var template RecordRoute v_recordRoute := omit;
v_intRecordRoute := lengthof(p_rr.routeBody);
if (v_intRecordRoute > 0) {
while (0 < v_intRecordRoute) {
p_rr.routeBody[v_intRecordRoute] := p_rr.routeBody[v_intRecordRoute - 1];
v_intRecordRoute := v_intRecordRoute - 1;
}
p_rr.routeBody[0] := valueof(m_routeBody_currIpAddr(vc_userprofile));
vc_recordRoute := p_rr;
return vc_recordRoute;
}
else {
return (v_recordRoute);
}
}
} // end group parameterOperations
group fieldOperations {
/**
* @desc Sets BYE header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersBYE(
inout CSeq p_cSeq_s,
in SipUrl p_to_user
) runs on ImsComponent {
vc_requestUri := p_to_user; // Request URI of Invite is identical with To header
vc_route := f_route(); // update the route header field depending on vc_boo_route
vc_recordRoute := f_recordroute(); // update the route header field depending on vc_boo_route
LibSip_Steps.f_setHeadersBYE(p_cSeq_s);
} // end f_setHeadersBYE
/**
* @desc Sets CANCEL header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
*/
function f_setHeadersCANCEL(
inout CSeq p_cSeq_s
) runs on ImsComponent {
vc_route := f_route(); // update the route header field depending on vc_boo_route
vc_recordRoute := f_recordroute(); // update the route header field depending on vc_boo_route
LibSip_Steps.f_setHeadersCANCEL(p_cSeq_s);
} // end f_setHeadersCANCEL
/**
* @desc Sets headers for forward request from AS in case if AS acts as Proxy
* @param p_cSeq_s The current cSeq
* @param p_proxyMode true = proxyMode, false = B2BMode
*/
function f_setHeadersForwardRequestFromAS(
inout CSeq p_cSeq_s,
boolean p_proxyMode
) runs on ImsComponent {
var Request v_request;
v_request := vc_request;
if (p_proxyMode) {
vc_requestUri2 := v_request.requestLine.requestUri;
vc_to := v_request.msgHeader.toField;
vc_contact := v_request.msgHeader.contact;
f_addNewViaParameter(v_request);
f_addNewRecordRouteAndRemoveRoutParameter(v_request);
}
else {
// B2Bmode
vc_contact := m_Contact(m_SipUrl_contactIpaddr(vc_userprofile));
vc_callId := {
fieldName := CALL_ID_E,
callid := f_getRndCallId() & c_AT & vc_userprofile.currIpaddr
};
}
} // end function f_setHeadersForwardRequest
/**
* @desc Sets header fields for forward request from AS in case if AS acts as Proxy
*/
function f_setHeadersForwardResponseFromAS(
) runs on ImsComponent {
var Response v_response;
v_response := vc_response;
vc_caller_To := v_response.msgHeader.toField;
vc_to := v_response.msgHeader.toField;
vc_contact := v_response.msgHeader.contact;
if (ispresent(v_response.msgHeader.recordRoute)) {
vc_recordRoute := v_response.msgHeader.recordRoute;
}
f_removeOwnViaParameter(v_response);
} // end function f_setHeadersForwardResponse
/**
* @desc Sets Invite header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersINVITE(
inout CSeq p_cSeq_s,
in SipUrl p_to_user
) runs on ImsComponent {
vc_to := f_initToHeader(p_to_user); // init of vc_to using userProfile identifier
vc_from := f_initFromHeader(p_to_user, f_getRndTag()); // init of vc_from using userProfile identifier
vc_requestUri := p_to_user; // Request URI of Invite is identical with To header
if (vc_boo_route) {
vc_route := m_route_interface(vc_interfaceprofile);
}
if (vc_boo_recordRoute) {
vc_recordRoute := m_recordRoute_currIpAddr(vc_userprofile);
}
LibSip_Steps.f_setHeadersINVITE(p_cSeq_s);
} // end f_setHeadersINVITE
/**
* @desc Sets Invite header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersUPDATE(
inout CSeq p_cSeq_s,
in SipUrl p_to_user
) runs on ImsComponent {
vc_to := f_initToHeader(p_to_user); // init of vc_to using userProfile identifier
vc_from := f_initFromHeader(p_to_user, f_getRndTag()); // init of vc_from using userProfile identifier
vc_requestUri := p_to_user; // Request URI of Invite is identical with To header
if (vc_boo_route) {
vc_route := m_route_interface(vc_interfaceprofile);
}
if (vc_boo_recordRoute) {
vc_recordRoute := m_recordRoute_currIpAddr(vc_userprofile);
}
LibSip_Steps.f_setHeadersUPDATE(p_cSeq_s);
} // end f_setHeadersUPDATE
/**
* @desc Sets Message header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersMESSAGE(
inout CSeq p_cSeq_s,
in SipUrl p_to_user
) runs on ImsComponent {
vc_to := f_initToHeader(p_to_user); // init of vc_to using userProfile identifier
vc_from := f_initFromHeader(p_to_user, f_getRndTag()); // init of vc_from using userProfile identifier
vc_requestUri := p_to_user; // Request URI of Invite is identical with To header
LibSip_Steps.f_setHeadersMESSAGE(p_cSeq_s);
} // end f_setHeadersMESSAGE
/**
* @desc Sets Notify header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersNOTIFY(
inout CSeq p_cSeq_s,
in SipUrl p_to_user
) runs on ImsComponent {
LibSip_Steps.f_setHeadersNOTIFY(p_cSeq_s);
vc_branch := c_branchCookie & f_getRndTag();
vc_via := {
fieldName := VIA_E,
viaBody := {valueof(m_ViaBody_virtual_XCSCF(vc_branch, vc_userprofile))}
};
vc_to := f_initToHeader(p_to_user); // init of vc_to using userProfile identifier
vc_from := f_initFromHeader(p_to_user, f_getRndTag()); // init of vc_from using userProfile identifier
vc_requestUri := p_to_user; // Request URI of Invite is identical with To header
// contact header initialization for sending of NOTIFY from CSCF component
vc_contact := m_Contact(m_SipUrl_currIpaddr_CSCF(vc_userprofile));
} // end f_setHeadersNOTIFY
/**
* @desc Sets Publish header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersPUBLISH(
inout CSeq p_cSeq_s,
in SipUrl p_to_user
) runs on ImsComponent {
LibSip_Steps.f_setHeadersPUBLISH(p_cSeq_s);
vc_branch := c_branchCookie & f_getRndTag();
vc_via := {
fieldName := VIA_E,
viaBody := {valueof(m_ViaBody_virtual_XCSCF(vc_branch, vc_userprofile))}
};
vc_to := f_initToHeader(p_to_user); // init of vc_to using userProfile identifier
vc_from := f_initFromHeader(p_to_user, f_getRndTag()); // init of vc_from using userProfile identifier
vc_requestUri := p_to_user; // Request URI of Invite is identical with To header
if (vc_boo_route) {
vc_route := m_route_interface(vc_interfaceprofile);
}
if (vc_boo_recordRoute) {
vc_recordRoute := m_recordRoute_currIpAddr(vc_userprofile);
}
// contact header initialization for sending of PUBLISH from CSCF component
vc_contact := m_Contact(m_SipUrl_currIpaddr_CSCF(vc_userprofile));
} // end f_setHeadersPUBLISH
/**
* @desc Sets Subscribe header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersSUBSCRIBE(
inout CSeq p_cSeq_s,
in SipUrl p_to_user
) runs on ImsComponent {
vc_to := {
fieldName := TO_E,
addressField := {
nameAddr := {
displayName := omit, // optional charstring
addrSpec := p_to_user // SipUrl
}
}, // end addressField
toParams := omit
};
vc_from := f_initFromHeader(p_to_user, f_getRndTag()); // init of vc_from using userProfile identifier
vc_requestUri := p_to_user; // Request URI of Invite is identical with To header
LibSip_Steps.f_setHeadersSUBSCRIBE(p_cSeq_s);
} // end f_setHeadersSUBSCRIBE
/**
* @desc Sets headers for ReINVITE method
* @param p_cSeq_s The current cSeq
* @param p_orginatingSide true in case of Re-INVITE is send from the orgination endpoint otherwise false.
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersReINVITE(
inout CSeq p_cSeq_s,
in boolean p_orginatingSide,
in SipUrl p_to_user
) runs on ImsComponent {
var integer v_tmp, i, j, v_nbroute;
var Request v_request;
v_request := vc_request;
f_setHeadersGeneral(p_cSeq_s, "INVITE"); // cseq, contact, branch, via
vc_reqHostPort := vc_requestUri.components.sip.hostPort;
vc_requestUri := p_to_user;
if (p_orginatingSide) {
vc_to := vc_caller_To;
vc_from := vc_caller_From;
}
else {
vc_to := vc_callee_To;
vc_from := vc_callee_From;
// get route from previous ACK request
// Route Management
if (isvalue(v_request.msgHeader.recordRoute)) {
vc_recordRoute := valueof(v_request.msgHeader.recordRoute);
v_nbroute := lengthof(vc_recordRoute.routeBody);
// copy and reverse the order of the routes in route header
for (i := 0; i <= (v_nbroute - 1); i := i + 1) {
j := v_nbroute - 1 - i;
vc_route.routeBody[j] := vc_recordRoute.routeBody[i];
}
vc_route.fieldName := ROUTE_E;
vc_boo_recordRoute := true;
vc_boo_route := true;
}
else {
vc_boo_recordRoute := false;
vc_boo_route := false;
}
}
v_tmp := str2int(vc_sdp_local.origin.session_id);
vc_sdp_local.origin.session_id := int2str(v_tmp + 1);
v_tmp := str2int(vc_sdp_local.origin.session_version);
vc_sdp_local.origin.session_version := int2str(v_tmp + 1);
} // end function f_setHeadersReINVITE
/**
* @desc Sets component variables related to message header fields when sending requests from the home I-CSCF (TS) to the visited P-CSCF (SUT) (message type independent: CSeq, contact, via), function uses information from userprofile and interfaceprofile
* @param p_cSeq_s The CSeq parameter
* @param p_method The method name for cSeq header field
*/
function f_setHeadersGeneral_ICSCF(
inout CSeq p_cSeq_s,
in charstring p_method
) runs on SipComponent {
p_cSeq_s.fieldName := CSEQ_E;
p_cSeq_s.seqNumber := p_cSeq_s.seqNumber + 1;
p_cSeq_s.method := p_method;
vc_cSeq := p_cSeq_s;
vc_contact := m_Contact(m_SipUrl_contactIpaddr(vc_userprofile));
vc_branch := c_branchCookie & f_getRndTag();
vc_branch_ICSCF := c_branchCookie & f_getRndTag();
vc_via := {
fieldName := VIA_E,
viaBody := {
valueof(m_ViaBody_currIpaddr(vc_branch, vc_userprofile)),
valueof(m_ViaBody_virtualUEinPCSCF(vc_branch_ICSCF, vc_userprofile))
}
};
} // end function f_setHeadersGeneral_ICSCF
/**
* @desc Sets header field for the next outgoing REGISTER message from the visited P-CSCF to the home I-CSCF
* @param p_cSeq_s The CSeq parameter to be applied
*/
function f_setHeaders_REGISTER_PCSCF(
inout CSeq p_cSeq_s
) runs on SipComponent {
var SemicolonParam_List v_params;
f_setHeadersGeneral(p_cSeq_s, "REGISTER"); // cseq, contact, branch, via
vc_requestUri := {
scheme := c_sipScheme,
components := {
sip := {
userInfo := omit,
hostPort := {
host := vc_userprofile.registrarDomain,
portField := omit
}
}
},
urlParameters := omit,
headers := omit
};
vc_reqHostPort := vc_requestUri.components.sip.hostPort;
vc_callId := {
fieldName := CALL_ID_E,
callid := f_getRndCallId() & c_AT & vc_userprofile.currIpaddr
};
vc_callIdReg := vc_callId;
vc_to := valueof(m_To(m_SipUrl_currDomain(vc_userprofile)));
v_params := {
{
id := c_tagId,
paramValue := {
tokenOrHost := f_getRndTag()
}
}
};
vc_from := {
fieldName := FROM_E,
addressField := vc_to.addressField,
fromParams := v_params
};
if (not vc_firstREGISTER_sent) {
v_params := {
{
id := c_expiresId,
paramValue := {
tokenOrHost := c_shortRegistration
}
}
};
vc_contact.contactBody.contactAddresses[0].contactParams := v_params;
}
vc_firstREGISTER_sent := true; // f_setHeaders_Register is called in deREGISTER function
vc_authorization := {
fieldName := AUTHORIZATION_E,
body := {f_calculatecCredentials_empty(vc_userprofile)}
};
} // end function setHeaders_REGISTER_PCSCF
/**
* @desc Sets REFER header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_to_user The selected user's SIP URL
*/
function f_setHeadersREFER(
inout CSeq p_cSeq_s,
in SipUrl p_to_user
) runs on ImsComponent {
vc_requestUri := p_to_user; // Request URI of Invite is identical with To header
if (vc_boo_route) {
vc_route := m_route_interface(vc_interfaceprofile);
}
if (vc_boo_recordRoute) {
vc_recordRoute := m_recordRoute_currIpAddr(vc_userprofile);
}
LibSip_Steps.f_setHeadersREFER(p_cSeq_s);
} // end f_setHeadersREFER
/**
* @desc Sets REFER header fields (IMS addresses) extension of general settings from LibSip basic function
* @param p_cSeq_s The current cSeq
* @param p_uri The SipUrl for request URI and To header
*/
function f_setHeadersREFER_conf(
inout CSeq p_cSeq_s,
in SipUrl p_uri
) runs on ImsComponent {
vc_to := {
fieldName := TO_E,
addressField := {
nameAddr := {
displayName := omit, // optional charstring
addrSpec := p_uri // SipUrl
}
}, // end addressField
toParams := omit
};
vc_from := f_initFromHeader(p_uri, f_getRndTag()); // init of vc_from using userProfile identifier
vc_requestUri := p_uri; // Request URI of Invite is identical with To header
if (vc_boo_route) {
vc_route := m_route_interface(vc_interfaceprofile);
}
if (vc_boo_recordRoute) {
vc_recordRoute := m_recordRoute_currIpAddr(vc_userprofile);
}
LibSip_Steps.f_setHeadersREFER(p_cSeq_s);
} // end f_setHeadersREFER_conf
} // end group fieldOperations
group awaitingMessage {
}
group sendMessage {
/**
* @desc Sends PRACK message
* @param p_mb The message body of the PRACK message
* @param p_rack_cseq The cSeq of the PRACK message
*/
function f_sendPRACK_sdp(
template(value) MessageBody p_mb,
CSeq p_rack_cseq
) runs on SipComponent {
var integer v_responseNum := 1;
var template(value) PRACK_Request v_prackReq;
f_setHeadersGeneral(vc_cSeq, "PRACK"); // cseq, contact, branch, via
if (isvalue(vc_response.msgHeader.rSeq.responseNum)) {
v_responseNum := vc_response.msgHeader.rSeq.responseNum;
}
vc_rAck := m_RAck(v_responseNum, p_rack_cseq.seqNumber, p_rack_cseq.method);
v_prackReq := m_PRACK_Request_sdp(vc_requestUri, vc_callId, vc_cSeq, vc_from, vc_to, vc_via, vc_rAck, p_mb);
// added route header if required
if (isvalue(vc_response.msgHeader.recordRoute)) {
v_prackReq.msgHeader.route := f_route();
}
SIPP.send(v_prackReq) to vc_sent_label;
}
}
group globalSteps {
//NOTE STF471: removed function f_init_userprofile, have to move up to specific ATS
/**
* @desc Initializes the To header
* @param p_user Identifies the selected user's SIP URL
* @return The To header
*/
function f_initToHeader(
in SipUrl p_user
) runs on ImsComponent
return To {
var To v_to := c_empty_To;
v_to := {
fieldName := TO_E,
addressField := {
nameAddr := {
displayName := omit, // optional charstring
addrSpec := p_user // SipUrl
}
}, // end addressField
toParams := omit
};
return (v_to);
}
/**
* @desc Initializes the From header
* @param p_user Identifies the selected user' SIP URL
* @param p_tag_str The string value of the tag id
* @return The From header
*/
function f_initFromHeader(
in SipUrl p_user,
charstring p_tag_str
) runs on ImsComponent
return From {
var From v_from := c_empty_From;
v_from := {
fieldName := FROM_E,
addressField := {
nameAddr := {
displayName := omit, // optional charstring
addrSpec := p_user // SipUrl
}
}, // end addressField
fromParams := {
{
id := c_tagId,
paramValue := {
tokenOrHost := p_tag_str
}
}
}
};
return v_from;
}
//NOTE STF471: removed function f_initSipUrl, have to move up to specific ATS
//NOTE STF471: removed function f_init_interfaceprofile, have to move up to specific ATS
/**
* @desc Retrieves user DomainPort value of the user profile
* @param p_userProfile Identifies the selected user profile
* @return The Domain HostPort
*/
function f_get_userDomainPort(
in SipUserProfile p_userProfile
) runs on ImsComponent
return HostPort {
return
{
p_userProfile.homeDomain,
p_userProfile.currPort
};
}
/**
* @desc Retrieves HostPort value of the interface profile
* @param p_interface Identifies the selected interface
* @return The HostPort
*/
function f_get_interfaceHostPort(
in ImsInterfaceProfile p_interface
) runs on ImsComponent
return HostPort {
return
{
p_interface.SUTIpaddr,
p_interface.SUTPort
};
}
/**
* @desc Retrieves DomainPort value of the interface profile
* @param p_interface Identifies the selected interface
* @return The Domain HostPort
*/
function f_get_interfaceDomainPort(
in ImsInterfaceProfile p_interface
) runs on ImsComponent
return HostPort {
return
{
p_interface.SUTHomeDomain,
p_interface.SUTPort
};
}
/**
* @desc Gets the receive template for the NameAddr of the interface
* @param p_interface Identifies the selected interface
* @return The NameAddr template
*/
function f_get_interfaceNameAddr(
in ImsInterfaceProfile p_interface
) runs on ImsComponent
return template NameAddr {
return mw_SipUrl_SUTinterface(p_interface.SUTIpaddr, p_interface.SUTPort);
}
}
group registration {
/**
* @desc Registration and authentication
* @param p_cSeq_s The current cseq
* @param p_auth flag indicating if authentication is needed
* @param p_host P-CSCF domain name (formerly value from module parameter PX_IMS_TS_PCSCF_HOME_DOMAIN)
* @param p_port P-CSCF port number (formerly value from module parameter PX_IMS_TS_PCSCF_PORT)
*/
function f_Registration_IMS(
inout CSeq p_cSeq_s,
in boolean p_auth,
template(value) charstring p_host,
template(value) integer p_port
) runs on SipComponent {
f_setHeaders_REGISTER(p_cSeq_s);
f_SendREGISTER(m_REGISTER_Request_IMS(vc_requestUri, vc_callId, vc_cSeq, vc_from, vc_to, vc_via_REG, vc_contact, m_add_Authorization_digest(vc_authorization, {c_Integrity_protected_no}), p_host, p_port)); // LibSip
// awaiting of 401 and sending 2nd REGISTER and awaiting 200 OK REGISTER
if (p_auth) {
// receiving 401 Unauthorized response.
// and Re-send REGISTER request with Authorization header
tc_ack.start;
alt {
[] SIPP.receive(mw_Response_Base(c_statusLine401, vc_callId, p_cSeq_s)) -> value vc_response {
tc_ack.stop;
// set headers via, cseq and authorization
f_setHeaders_2ndREGISTER(p_cSeq_s);
f_SendREGISTER(m_REGISTER_Request_IMS(vc_requestUri, vc_callId, vc_cSeq, vc_from, vc_to, vc_via_REG, vc_contact, m_add_Authorization_digest(vc_authorization, {c_Integrity_protected_yes}), p_host, p_port)); // LibSip
// awaiting 200 OK REGISTER
f_awaitingOkResponse(p_cSeq_s);
f_getServiceRouteMapIntoRouteInRegistration(vc_response);
}
[] SIPP.receive(mw_Response_Base(c_statusLine200, vc_callId, p_cSeq_s)) {
tc_ack.stop;
log("*** " & __SCOPE__ & ": INCONC: Authorization was not requested as expected ***");
setverdict(inconc);
}
}
}
else {
f_awaitingOkResponse(p_cSeq_s);
f_getServiceRouteMapIntoRouteInRegistration(vc_response);
}
} // end function f_Registration_IMS
/**
* @desc awaiting UE1 registration (with authentication)
* @param p_cSeq_s The current cseq
* @param p_to_user The selected user's SIP URL
* @param p_qop of the peer UE (alternatively)
* @param p_register The expected REGISTER_Request - default: mw_REGISTER_authorizedRequest_IMS
*/
function f_awaitingRegistration_IMS(
inout CSeq p_cSeq_s,
in SipUrl p_to_user,
in charstring p_qop,
in template(present) REGISTER_Request p_register :=
mw_REGISTER_authorizedRequest_IMS(
mw_Authorization_digest(
mw_digestResponse(
(c_Integrity_protected_yes, c_Integrity_protected_ip_assoc_pending)
)
)
)
) runs on ImsComponent {
var SipUrl v_passociated_url;
// Awaiting 1st REGISTER
f_awaitingREGISTER(mw_REGISTER_unauthorizedRequest_IMS);
// 401 response
f_sendResponse(
m_Response_WWWauthenticate_IMS(
c_statusLine401,
vc_callId,
p_cSeq_s,
vc_caller_From,
vc_caller_To,
vc_via,
m_wwwAuthenticate(
f_calculatecChallenge_forWWWAuthorization(
p_qop,
valueof(vc_authorization.body[0].digestResponse)
)
)
)
);
// Awaiting 2nd REGISTER with authorization header
f_awaitingREGISTER(p_register);
// 200OK to complete the request
if (isvalue(vc_request.msgHeader.contact)) {
vc_contact := valueof(vc_request.msgHeader.contact);
vc_contact.contactBody.contactAddresses[0].contactParams := {
{
"expires",
{
tokenOrHost := int2str(3600)
}
}
};
}
v_passociated_url := vc_caller_From.addressField.nameAddr.addrSpec;
f_sendResponse(m_Response_2xxonREGISTER_IMS(c_statusLine200, vc_callId, p_cSeq_s, vc_callee_From, vc_callee_To, vc_via, vc_contact, p_to_user, v_passociated_url));
} // end function f_awaitingRegistration_IMS
/**
* @desc Awaiting UE1 registration (with authentication, without security headers)
* @param p_cSeq_s The current cseq
* @param p_to_user The selected user's SIP URL
* @param p_qop of the peer UE (alternatively)
*/
function f_awaitingRegistration_IMS_gm(
inout CSeq p_cSeq_s,
in SipUrl p_to_user,
in charstring p_qop
) runs on ImsComponent {
vc_ignore_subscribe := true; // handle SUBSCRIBE during the call
f_awaitingRegistration_IMS(p_cSeq_s, p_to_user, p_qop, mw_REGISTER_authorizedRequest_wo_securityheaders_IMS);
vc_DeregDone := false;
} // end function f_awaitingRegistration_IMS_gm
/**
* @desc Remove registration
* @param p_cSeq_s The current cseq
* @param p_host P-CSCF domain name (formerly value from module parameter PX_IMS_TS_PCSCF_HOME_DOMAIN)
* @param p_port P-CSCF port number (formerly value from module parameter PX_IMS_TS_PCSCF_PORT)
*/
function f_removeRegistration_IMS(
inout CSeq p_cSeq_s,
template(value) charstring p_host,
template(value) integer p_port
) runs on SipComponent {
var template(value) REGISTER_Request v_request;
if (PX_SIP_REGISTRATION) {
f_setHeaders_deREGISTER(p_cSeq_s);
v_request := m_REGISTER_Request_expires_IMS(vc_requestUri, vc_callIdReg, p_cSeq_s, vc_from, vc_to, vc_via, vc_contact, vc_authorization, p_host, p_port, "0");
v_request.msgHeader.route := f_route();
f_SendREGISTER(v_request);
if (PX_SIP_REGISTER_AUTHENTICATION_ENABLED) {
// receiving 401 Unauthorized response.
// and Re-send REGISTER request with Authorization header
tc_ack.start;
alt {
[] SIPP.receive(mw_Response_Base(c_statusLine401, vc_callIdReg, p_cSeq_s)) -> value vc_response {
tc_ack.stop;
// set headers via, cseq and authorization
f_setHeaders_2ndREGISTER(p_cSeq_s);
v_request := m_REGISTER_Request_expires_IMS(vc_requestUri, vc_callIdReg, p_cSeq_s, vc_from, vc_to, vc_via, vc_contact, vc_authorization, p_host, p_port, "0");
v_request.msgHeader.route := f_route();
// Re-send protected REGISTER
f_SendREGISTER(v_request); // LibSip
// awaiting 200 OK REGISTER
f_awaitingResponse(mw_Response_Base(c_statusLine200, vc_callIdReg, p_cSeq_s));
}
[] SIPP.receive(mw_Response_Base(c_statusLine200, vc_callIdReg, p_cSeq_s)) -> value vc_response {
tc_ack.stop;
f_setHeadersOnReceiptOfResponse(vc_response);
log("*** " & __SCOPE__ & ": INFO: Authorization was not requested as expected ***");
}
}
}
else {
f_awaitingResponse(mw_Response_Base(c_statusLine200, vc_callIdReg, p_cSeq_s));
}
}
} // end f_RemoveRegistration_IMS
} // end group registration
group preambles {
/**
* @desc Sets variables and default initialization for user profile where proxy role is present
* @param p_userprofile User profile of call
* @param p_cSeq_s The current cseq
*/
function f_IMS_preamble_MGCF(
inout CSeq p_cSeq_s
) runs on ImsComponent {
vc_boo_recordRoute := true;
vc_boo_route := true;
//NOTE STF471: removed f_init_interfaceprofile(c_interfaceProfile_IMS_SUT_MGCF);
f_IMS_preamble_woRegistration(p_cSeq_s);
}
/**
* @desc Sets variables and default initialization for user profile
* @param p_cSeq_s The current cseq
*/
function f_IMS_preamble_woRegistration(
inout CSeq p_cSeq_s
) runs on ImsComponent {
// avoid deregistration in default behavior
vc_DeregDone := true;
vc_boo_route := true;
vc_boo_recordRoute := true;
// Variables & defaults initialization
LibSip_Steps.f_init_component(p_cSeq_s);
// Preamble
//NOTE STF471: removed f_init_userprofile(p_userprofile); // assignment of PIXIT values to component variable
vc_sdp_local := valueof(m_SDP_bandwidth(m_media_dynPT(PX_SIP_SDP_DYN, PX_SIP_SDP_ENCODING, PX_SIP_SDP_CLOCKRATE, omit), vc_userprofile));
vc_contact := m_Contact(m_SipUrl_contactIpaddr(vc_userprofile));
}
//NOTE STF471 added
/**
* @desc Sets variables and default initialization for user profile
* @param p_cSeq_s The current cseq
*/
function f_IMS_preamble_woRegistration_as(
inout CSeq p_cSeq_s
) runs on ImsComponent {
// avoid deregistration in default behavior
vc_DeregDone := true;
vc_boo_route := true;
vc_boo_recordRoute := true;
// Variables & defaults initialization
LibSip_Steps.f_init_component(p_cSeq_s);
// Preamble
//NOTE STF471: removed f_init_userprofile(p_userprofile); // assignment of PIXIT values to component variable
vc_sdp_local := valueof(m_SDP_bandwidth(m_media_dynPT(PX_SIP_SDP_DYN, PX_SIP_SDP_ENCODING, PX_SIP_SDP_CLOCKRATE, omit), vc_userprofile));
}
/**
* @desc Sets variables and default initialization for user profile and handle registration and authentication with MD5
* @param p_cSeq_s The current cseq
* @param p_register Register template
*/
function f_IMS_preamble_withEmergencyRegistration(
inout CSeq p_cSeq_s,
template REGISTER_Request p_register
) runs on ImsComponent {
//NOTE STF471: removed f_init_interfaceprofile(p_interface);
// Variables & defaults initialization
f_IMS_preamble_woRegistration(p_cSeq_s);
// Preamble
f_Registration(p_cSeq_s, p_register, PX_SIP_REGISTER_AUTHENTICATION_ENABLED, true);
// deregistration in case of successful registration
vc_DeregDone := false;
}
/**
* @desc Sets variables and default initialization for user profile and handle registration and authentication with MD5
* @param p_cSeq_s The current cseq
* @param p_register Register template
*/
function f_IMS_preamble_withRegistration(
inout CSeq p_cSeq_s,
out template REGISTER_Request p_register
) runs on ImsComponent {
//NOTE STF471: removed f_init_interfaceprofile(p_interface);
// Variables & defaults initialization
f_IMS_preamble_woRegistration(p_cSeq_s);
// Preamble
f_Registration(p_cSeq_s, p_register, PX_SIP_REGISTER_AUTHENTICATION_ENABLED);
// deregistration in case of successful registration
vc_DeregDone := false;
f_setHeaders_SUBSCRIBE(p_cSeq_s);
f_Subscription(p_cSeq_s, m_SUBSCRIBE_Request_UE(vc_requestUri, vc_callId, p_cSeq_s, vc_from, vc_to, vc_via, vc_contact, vc_route_REG));
}
//NOTE STF471 added
/**
* @desc Sets variables and default initialization for user profile and handle registration and authentication with MD5
* @param p_cSeq_s The current cseq
* @param p_register Register template
*/
function f_IMS_preamble_withRegistrationWoSubscription(
inout CSeq p_cSeq_s,
out template REGISTER_Request p_register
) runs on ImsComponent {
//NOTE STF471: removed f_init_interfaceprofile(p_interface);
// Variables & defaults initialization
f_IMS_preamble_woRegistration(p_cSeq_s);
// Preamble
f_Registration(p_cSeq_s, p_register, PX_SIP_REGISTER_AUTHENTICATION_ENABLED);
// deregistration in case of successful registration
vc_DeregDone := false;
}
/**
* @desc Sets variables and default initialization for user profile and handle registration and authentication with MD5 (basic registration template)
* @param p_cSeq_s The current cseq
* @param p_host P-CSCF domain name (formerly value from module parameter PX_IMS_TS_PCSCF_HOME_DOMAIN)
* @param p_port P-CSCF port number (formerly value from module parameter PX_IMS_TS_PCSCF_PORT)
*/
function f_IMS_preamble_withRegistrationBasic(
inout CSeq p_cSeq_s,
template(value) charstring p_host,
template(value) integer p_port
) runs on ImsComponent {
//NOTE STF471: removed f_init_interfaceprofile(p_interface);
// Variables & defaults initialization
f_IMS_preamble_woRegistration(p_cSeq_s);
// Preamble
f_Registration_IMS(p_cSeq_s, PX_SIP_REGISTER_AUTHENTICATION_ENABLED, p_host, p_port);
f_setHeaders_SUBSCRIBE(p_cSeq_s);
f_Subscription(p_cSeq_s, m_SUBSCRIBE_Request_UE(vc_requestUri, vc_callId, p_cSeq_s, vc_from, vc_to, vc_via, vc_contact, vc_route_REG));
}
/**
* @desc Sets variables and default initialization for user profile and handle registration and authentication with MD5 (basic registration template)
* @param p_cSeq_s The current cseq
*/
function f_IMS_preamble_AS(
inout CSeq p_cSeq_s
) runs on ImsComponent {
// avoid deregistration in default behavior
vc_DeregDone := true;
vc_boo_route := true;
vc_boo_recordRoute := true;
vc_cSeq := p_cSeq_s;
// Defaults
vc_def_catchSyncStop := activate(a_Sip_catchSyncStop());
vc_default := activate(a_altstep_AS());
// Preamble
//NOTE STF471: removed f_init_interfaceprofile(p_interface);
//NOTE STF471: removed f_init_userprofile(p_userprofile); // assignment of PIXIT values to component variable
vc_sdp_local := valueof(m_SDP_bandwidth(m_media_dynPT(PX_SIP_SDP_DYN, PX_SIP_SDP_ENCODING, PX_SIP_SDP_CLOCKRATE, omit), vc_userprofile));
vc_contact := m_Contact(m_SipUrl_contactIpaddr(vc_userprofile));
}
} // end group preambles
group postambles {
/**
* @desc Terminates component and handles deregistration
* @param p_cSeq_s The current cseq
*/
function f_IMS_postamble_withDeRegistration(
CSeq p_cSeq_s
) runs on ImsComponent {
f_RemoveRegistration(p_cSeq_s);
f_terminate_component();
}
/**
* @desc Terminates component and optionally handles deregistration on AS as TS
* @param p_deRegistration Handle deregistration?
*/
function f_IMS_postamble_AS_withDeRegistration(
boolean p_deRegistration
) runs on ImsComponent {
if (p_deRegistration == true) {
f_awaitingREGISTER_sendReply(mw_REGISTER_Request_Base, true);
}
f_terminate_component();
}
/**
* @desc Terminates component without registration
*/
function f_SIP_postamble_IMS1_withoutRegistration(
) runs on ImsComponent {
f_terminate_component();
}
/**
* @desc Terminates component without de-registration
*/
function f_IMS_postamble_withoutDeRegistration(
) runs on ImsComponent {
f_terminate_component();
}
/**
* @desc Terminates component with de-registration
* @param p_to_user The selected user's SIP URL
* @param p_qop of the peer UE (alternatively)
*/
function f_SIP_postamble_IMS1_awaitDeRegistration(
in SipUrl p_to_user,
in charstring p_qop
) runs on ImsComponent {
var SipUrl v_passociated_url;
// Awaiting 1st REGISTER
f_awaitingREGISTER(mw_REGISTER_unauthorizedRequest_IMS);
// 401 response
f_sendResponse(m_Response_WWWauthenticate_IMS(c_statusLine401, vc_callId, vc_cSeq, vc_caller_From, vc_caller_To, vc_via, m_wwwAuthenticate(f_calculatecChallenge_forWWWAuthorization(p_qop, valueof(vc_authorization.body[0].digestResponse)))));
// Awaiting 2nd REGISTER with authorization header
f_awaitingREGISTER(mw_REGISTER_unauthorizedRequest_IMS);
// 200OK to complete the request
v_passociated_url := vc_caller_From.addressField.nameAddr.addrSpec;
f_sendResponse(m_Response_2xxonREGISTER_IMS(c_statusLine200, vc_callId, vc_cSeq, vc_callee_From, vc_callee_To, vc_via, vc_contact, p_to_user, v_passociated_url));
f_terminate_component();
}
/**
* @desc Terminates component with de-registration
* @param p_to_user The selected user's SIP URL
* @param p_qop of the peer UE (alternatively)
*/
function f_IMS_postamble_awaitDeRegistration(
in SipUrl p_to_user,
in charstring p_qop
) runs on ImsComponent {
var SipUrl v_passociated_url;
// Awaiting 1st REGISTER
f_awaitingREGISTER(mw_REGISTER_unauthorizedRequest_IMS);
// 401 response
f_sendResponse(m_Response_WWWauthenticate_IMS(c_statusLine401, vc_callId, vc_cSeq, vc_caller_From, vc_caller_To, vc_via, m_wwwAuthenticate(f_calculatecChallenge_forWWWAuthorization(p_qop, valueof(vc_authorization.body[0].digestResponse)))));
// Awaiting 2nd REGISTER with authorization header
f_awaitingREGISTER(mw_REGISTER_unauthorizedRequest_IMS);
// 200OK to complete the request
v_passociated_url := vc_caller_From.addressField.nameAddr.addrSpec;
f_sendResponse(m_Response_2xxonREGISTER_IMS(c_statusLine200, vc_callId, vc_cSeq, vc_callee_From, vc_callee_To, vc_via, vc_contact, p_to_user, v_passociated_url));
f_terminate_component();
}
/**
* @desc Awaits de-registration
* @param p_to_user The selected user's SIP URL
* @param p_qop of the peer UE (alternatively)
*/
function f_IMS_awaitDeRegistration(
in SipUrl p_to_user,
in charstring p_qop
) runs on ImsComponent {
var SipUrl v_passociated_url;
// Awaiting 1st REGISTER
f_awaitingREGISTER(mw_REGISTER_unauthorizedRequest_IMS);
// 401 response
f_sendResponse(m_Response_WWWauthenticate_IMS(c_statusLine401, vc_callId, vc_cSeq, vc_caller_From, vc_caller_To, vc_via, m_wwwAuthenticate(f_calculatecChallenge_forWWWAuthorization(p_qop, valueof(vc_authorization.body[0].digestResponse)))));
// Awaiting 2nd REGISTER with authorization header
f_awaitingREGISTER(mw_REGISTER_unauthorizedRequest_IMS);
// 200OK to complete the request
v_passociated_url := vc_caller_From.addressField.nameAddr.addrSpec;
f_sendResponse(m_Response_2xxonREGISTER_IMS(c_statusLine200, vc_callId, vc_cSeq, vc_callee_From, vc_callee_To, vc_via, vc_contact, p_to_user, v_passociated_url));
}
//NOTE STF471: renamed f_SIP_postamble_UE(1|2)_withoutRegistration to f_SIP_postamble_UE_withoutRegistration
/**
* @desc Terminates component without registration
*/
function f_SIP_postamble_UE_withoutRegistration(
) runs on ImsComponent {
f_terminate_component();
}
/**
* @desc Sends BYE and awaits response (IMS)
* @param p_requestUri The Request URI
* @param p_callId CallId parameter for outgoing BYE
* @param p_cSeq_s CSeq parameter for outgoing BYE
* @param p_from From parameter for outgoing BYE
* @param p_to To parameter for outgoing BYE
*/
function f_terminateCall_IMS(
SipUrl p_requestUri,
CallId p_callId,
inout CSeq p_cSeq_s,
From p_from,
template(value) To p_to
) runs on ImsComponent {
LibSip_Steps.f_setHeadersBYE(p_cSeq_s);
// Sending of a BYE request to release the call and expect a final response
f_SendBYE(m_BYE_Request_IMS(p_requestUri, p_callId, p_cSeq_s, p_from, p_to, vc_via, vc_route));
tc_resp.start;
alt {
[] SIPP.receive(mw_Response_Base(mw_statusLine1xx, p_callId, p_cSeq_s)) {
repeat;
}
[] SIPP.receive(mw_Response_Base(mw_statusLineFinal, p_callId, p_cSeq_s)) {
tc_resp.stop;
}
// timeout should be handled in default_alt_step
}
} // end function f_terminateCall_IMS
/**
* @desc Sends BYE and awaits response (UE)
* @param p_requestUri The Request URI
* @param p_callId CallId parameter for outgoing BYE
* @param p_cSeq_s CSeq parameter for outgoing BYE
* @param p_from From parameter for outgoing BYE
* @param p_to To parameter for outgoing BYE
* @param p_recordRoute RecordRoute parameter for outgoing BYE - default: omit
*/
function f_terminateCall_UE(
SipUrl p_requestUri,
CallId p_callId,
inout CSeq p_cSeq_s,
From p_from,
template(value) To p_to,
template RecordRoute p_recordRoute := omit
) runs on ImsComponent {
var Route v_route;
LibSip_Steps.f_setHeadersBYE(p_cSeq_s);
// Sending of a BYE request to release the call and expect a final response
if (ispresent(p_recordRoute)) {
v_route := {ROUTE_E, valueof(p_recordRoute.routeBody)};
f_SendBYE(m_BYE_Request_UE(p_requestUri, p_callId, p_cSeq_s, p_from, valueof(p_to), vc_via, v_route));
}
else {
f_SendBYE(m_BYE_Request_UE(p_requestUri, p_callId, p_cSeq_s, p_from, valueof(p_to), vc_via, vc_route));
}
tc_resp.start;
alt {
[] SIPP.receive(mw_Response_Base(mw_statusLine1xx, p_callId, p_cSeq_s)) {
repeat;
}
[] SIPP.receive(mw_Response_Base(mw_statusLineFinal, p_callId, p_cSeq_s)) {
tc_resp.stop;
}
// timeout should be handled in default_alt_step
}
} // end function f_terminateCall_UE
/**
* @desc Sends BYE and awaits response and De-registration
* @param p_requestUri The Request URI
* @param p_callId CallId parameter for outgoing BYE
* @param p_cSeq_s CSeq parameter for outgoing BYE
* @param p_from From parameter for outgoing BYE
* @param p_to To parameter for outgoing BYE
* @param p_qop of the peer UE (alternatively)
*/
function f_terminateCall_UE_withDeReg(
SipUrl p_requestUri,
CallId p_callId,
inout CSeq p_cSeq_s,
From p_from,
template(value) To p_to,
in charstring p_qop
) runs on ImsComponent {
LibSip_Steps.f_setHeadersBYE(p_cSeq_s);
// Sending of a BYE request to release the call and expect a final response
f_SendBYE(m_BYE_Request_UE(p_requestUri, p_callId, p_cSeq_s, p_from, p_to, vc_via, vc_route));
tc_resp.start;
alt {
[] SIPP.receive(mw_Response_Base(mw_statusLine1xx, p_callId, p_cSeq_s)) {
repeat;
}
[] SIPP.receive(mw_Response_Base(mw_statusLineFinal, p_callId, p_cSeq_s)) {
tc_resp.stop;
}
// timeout should be handled in default_alt_step
}
action("Please de-register");
f_IMS_awaitDeRegistration(p_requestUri, p_qop);
} // end function f_terminateCall_UE_withDeReg
}
group defaults {
/**
* @desc Altstep for clearing registration (IMS user)
* @param p_to_user The selected user's SIP URL
* @param p_qop of the peer UE (alternatively)
* @verdict fail for all unexpected branches
*/
altstep a_clearRegistration_IMSuser(
in SipUrl p_to_user,
in charstring p_qop
) runs on ImsComponent {
var Response v_response;
var Request v_request;
var CSeq v_cSeq;
[] any timer.timeout {
log("*** " & testcasename() & ": FAIL: Timeout while waiting for message. ***");
setverdict(fail);
all timer.stop;
vc_callId := vc_callIdReg;
action("Please de-register");
f_IMS_awaitDeRegistration(p_to_user, p_qop);
f_componentStop();
}
// allow repeated INVITEs
[vc_ignore_invite] SIPP.receive(mw_INVITE_Request_Base) {
repeat;
}
// allow repeated BYEs after ack of the first BYE
[vc_ignore_bye] SIPP.receive(mw_BYE_Request_Base(?)) {
repeat;
}
[] SIPP.receive(mw_ACK_Request_Base(?)) {
repeat;
}
// allow 100 replies
[] SIPP.receive(mw_Response_Base(c_statusLine100, ?, ?)) {
repeat;
}
// ignore 181 if flag is set (following TS 183004 §4.5.2.1)
[vc_ignore181] SIPP.receive(mw_Response_Base(c_statusLine181, vc_callId, vc_cSeq)) -> value v_response sender vc_sent_label {
v_cSeq := valueof(v_response.msgHeader.cSeq);
f_setHeadersOnReceiptOfResponse(v_response);
repeat;
}
// according to SIP chap.8.1.3.2
[] SIPP.receive(mw_Response_Base(c_statusLine183, vc_callId, vc_cSeq)) {
repeat;
}
// ignore 484 if flag is set
[vc_ignore484] SIPP.receive(mw_Response_Base(c_statusLine484, vc_callId, vc_cSeq)) {
repeat;
}
[vc_ignore4xx] SIPP.receive(mw_Response_Base(mw_statusLine4xx, vc_callId, ?)) -> value v_response sender vc_sent_label {
v_cSeq := valueof(v_response.msgHeader.cSeq);
f_setHeadersOnReceiptOfResponse(v_response);
f_SendACK(m_ACK_Request_route(vc_requestUri, vc_callId, v_response.msgHeader.cSeq, vc_from, vc_to, vc_via, vc_route));
repeat;
}
[vc_ignore200OKinv] SIPP.receive(mw_Response_Base(c_statusLine200, vc_callId, ?)) {
repeat;
}
[] SIPP.receive(mw_INFO_Request_Base(vc_callId)) -> value v_request sender vc_sent_label {
f_setHeadersOnReceiptOfRequest(v_request);
f_send200OK();
repeat;
}
// awaiting of Notify
[] SIPP.receive(mw_NOTIFY_Request_Base(vc_callId)) -> value v_request sender vc_sent_label {
f_setHeadersOnReceiptOfRequest(v_request);
f_send200OK();
repeat;
}
// awaiting of subscribe from UE
[vc_ignore_subscribe] SIPP.receive(mw_SUBSCRIBE_Request_Base) -> value v_request sender vc_sent_label {
f_setHeadersOnReceiptOfSUBSCRIBE(v_request);
f_send200OK();
repeat;
}
// awaiting of subscribe on proxy
[] SIPP.receive(mw_SUBSCRIBE_Request_Base) -> value v_request sender vc_sent_label {
f_setHeadersOnReceiptOfRequest(v_request);
f_sendResponse(m_Response_Contact(c_statusLine200, vc_callId, vc_cSeq, vc_callee_From, vc_callee_To, vc_via, vc_contact));
f_SendNOTIFY(m_NOTIFY_Request_contact(v_request.msgHeader.contact.contactBody.contactAddresses[0].addressField.nameAddr.addrSpec, vc_callId, vc_cSeq, vc_callee_From, vc_callee_To, vc_via, vc_contact));
f_awaitingOkResponse(vc_cSeq);
repeat;
}
// unexpected BYE is acknowledged to avoid retransmissions
[] SIPP.receive(mw_BYE_Request_Base(?)) -> value v_request sender vc_sent_label {
log("*** " & testcasename() & ": FAIL: Unexpected BYE message received. ***");
setverdict(fail);
f_setHeadersOnReceiptOfRequest(v_request);
f_send200OK();
action("Please de-register");
f_IMS_awaitDeRegistration(p_to_user, p_qop);
f_componentStop();
}
// unexpected CANCEL is acknowledged to avoid retransmissions
[] SIPP.receive(mw_CANCEL_Request_Base(?)) -> value v_request sender vc_sent_label {
log("*** " & testcasename() & ": FAIL: Unexpected CANCEL message received. ***");
setverdict(fail);
f_setHeadersOnReceiptOfRequest(v_request);
// Answer to the CANCEL
f_send200OK();
action("Please de-register");
f_IMS_awaitDeRegistration(p_to_user, p_qop);
f_componentStop();
}
// catch 4xx response
[] SIPP.receive(mw_Response_Base(mw_statusLine4xx, vc_callId, ?)) -> value v_response sender vc_sent_label {
log("*** " & testcasename() & ": FAIL: Unexpected 4xx response received. ***");
setverdict(fail);
v_cSeq := valueof(v_response.msgHeader.cSeq);
f_setHeadersOnReceiptOfResponse(v_response);
LibSip_Steps.f_setHeadersACK();
f_SendACK(m_ACK_Request_route(vc_requestUri, vc_callId, v_response.msgHeader.cSeq, vc_from, vc_to, vc_via, vc_route));
action("Please de-register");
f_IMS_awaitDeRegistration(p_to_user, p_qop);
f_componentStop();
}
// catch 5xx response
[] SIPP.receive(mw_Response_Base(mw_statusLine5xx, vc_callId, ?)) -> value v_response sender vc_sent_label {
log("*** " & testcasename() & ": FAIL: Unexpected 5xx response received. ***");
setverdict(fail);
v_cSeq := valueof(v_response.msgHeader.cSeq);
f_setHeadersOnReceiptOfResponse(v_response);
LibSip_Steps.f_setHeadersACK();
f_SendACK(m_ACK_Request_route(vc_requestUri, vc_callId, v_response.msgHeader.cSeq, vc_from, vc_to, vc_via, vc_route));
action("Please de-register");
f_IMS_awaitDeRegistration(p_to_user, p_qop);
f_componentStop();
}
// catch invalid REGISTER
[] SIPP.receive(mw_REGISTER_Request_Base) -> value v_request sender vc_sent_label {
log("*** " & testcasename() & ": FAIL: Unexpected REGISTER received. ***");
setverdict(fail);
f_componentStop();
}
// any
[] SIPP.receive {
log("*** " & testcasename() & ": FAIL: Unexpected message received. ***");
setverdict(fail);
all timer.stop;
action("Please de-register");
f_IMS_awaitDeRegistration(p_to_user, p_qop);
f_componentStop();
}
}
/**
* @desc Main default altstep to handle unexpected messages and timeout
* @verdict fail for all unexpected branches
*/
altstep a_altstep_AS(
) runs on SipComponent {
var Request v_request;
[] any timer.timeout {
log("*** " & testcasename() & ": FAIL: Timeout while waiting for message. ***");
setverdict(fail);
all timer.stop;
}
// allow repeated INVITEs
[vc_ignore_invite] SIPP.receive(mw_INVITE_Request_Base) {
repeat;
}
// handle REGISTER requests
[] SIPP.receive(mw_REGISTER_Request_Base) -> value v_request sender vc_sent_label {
f_setHeadersOnReceiptOfREGISTER(v_request);
// vc_contact := vc_request.msgHeader.contact;
f_sendResponse(m_Response_Contact(c_statusLine200, vc_callId, vc_cSeq, vc_caller_From, vc_caller_To, vc_via, vc_contact));
repeat;
}
// according to SIP chap.8.1.3.2
[] SIPP.receive(mw_Response_Base(c_statusLine183, vc_callId, vc_cSeq)) {
repeat;
}
// unexpected CANCEL is acknowledged to avoid retransmissions
[] SIPP.receive(mw_CANCEL_Request_Base(?)) -> value v_request sender vc_sent_label {
log("*** " & testcasename() & ": FAIL: Unexpected CANCEL message received. ***");
setverdict(fail);
f_setHeadersOnReceiptOfRequest(v_request);
f_send200OK();
}
// unexpected BYE is acknowledged to avoid retransmissions
[] SIPP.receive(mw_BYE_Request_Base(?)) -> value v_request sender vc_sent_label {
log("*** " & testcasename() & ": FAIL: Unexpected BYE message received. ***");
setverdict(fail);
f_setHeadersOnReceiptOfRequest(v_request);
f_send200OK();
}
[] SIPP.receive(mw_Response_Base(?, vc_callId, vc_cSeq)) -> value vc_response {
log("*** " & testcasename() & ": FAIL: Unexpected response message in " & __SCOPE__ & " received. ***");
setverdict(fail);
repeat;
}
// any
[] SIPP.receive {
log("*** " & testcasename() & ": FAIL: Unexpected message received. ***");
setverdict(fail);
all timer.stop;
}
}
}
} // module LibIms_Steps