LibSip_Steps.ttcn 121 KB
Newer Older
				connections := omit,
				bandwidth := omit,
				key := omit,						
				attributes := omit
			};
			
		if (32<loc_codec or loc_codec<1) {
			log("Unexpected SDP variant");
			setverdict(inconc); 
			return (v_media)}

		if (loc_sdp == 1) {}
		else if (loc_sdp == 2) {
			v_media.media_field.fmts := {PX_SIP_SDP_dyn}; //{ "98", "0" };
			v_media.attributes := {{
			rtpmap := { attr_value := PX_SIP_SDP_dyn & " " & v_codecs[loc_codec-1] } // PX_SIP_SDP_dyn := 98
			}}
		} else if (loc_sdp == 3) {
			v_media.media_field.fmts := { "8" }
		} else if (loc_sdp == 4) {
			v_media.media_field.fmts := { "99", "8" };
			v_media.attributes := {{
				rtpmap := { attr_value := "99 " & v_codecs[loc_codec-1] }
						}}
		} else if (loc_sdp == 5) {
			v_media.media_field.media := "image";
			v_media.media_field.transport := "udptl";
			v_media.media_field.fmts := { "t38" }
		} else if (loc_sdp == 6) {
			v_media.media_field.media := "image";
			v_media.media_field.transport := "tcptl";
			v_media.media_field.fmts := { "t38" }
		} else {
			log("Unexpected SDP variant"); setverdict(inconc) 
		};
			
		return (v_media);
	}

	/** 
	*  @desc repare media/attribute lines
	*		 
	*/
	function f_prepare_SDP(integer loc_sdp, integer loc_codec) runs on SipComponent
	{

		vc_sdp_local.media_list := {f_prepare_media(loc_sdp,loc_codec)};
	}
	
	/**
	* 
	* @desc function that copy media/attribute lines from remote to local SDP variable
	*/
	function f_prepare_SDP_answer() runs on SipComponent
	{
		var integer mn, cn := 0, i, j, k :=0;
		var charstring v_PT, v_rtpmap := "";
		var SDP_attribute_list v_mediaAttributes := {};
		//increase session version
		vc_sdp_local.origin.session_version := 	int2str(str2int(vc_sdp_local.origin.session_version)+1);
		// if more than one codec, select the firs one
		mn:= sizeof(vc_sdp_local.media_list);
		for (i :=0;  i < mn; i := i+1)
		{
			//for every single media
			if (ispresent(vc_sdp_local.media_list[i].attributes))
			{
				cn := sizeof(vc_sdp_local.media_list[i].attributes);
			};
			if (sizeof(vc_sdp_local.media_list[i].media_field.fmts)>1) 
			{
				// select the first one
				v_PT := vc_sdp_local.media_list[i].media_field.fmts[0];
				vc_sdp_local.media_list[i].media_field.fmts := {v_PT};
				for (j :=0; j<cn; j:=j+1)
				{
					if (ischosen(vc_sdp_local.media_list[i].attributes[j].rtpmap))
					{
						if (v_PT == regexp(vc_sdp_local.media_list[i].attributes[j].rtpmap.attr_value,	"[ \t]#(0,)([/d]+)*",	0))
						{
							v_rtpmap := vc_sdp_local.media_list[i].attributes[j].
							rtpmap.attr_value;
							v_mediaAttributes[k] := {rtpmap := {attr_value := v_rtpmap}};
							k := k+1;
						} // else line is not copied
					}


					// simplified handling of status attributes (copy/keep status from peer):
					// a) copy/keep SDP_attribute_curr (invert tags if applicable)
					if (ischosen(vc_sdp_local.media_list[i].attributes[j].curr))
					{
						// invert local/remote status tags
						if (vc_sdp_local.media_list[i].attributes[j].curr.statusType == "local")
							{vc_sdp_local.media_list[i].attributes[j].curr.statusType := "remote"};
						if (vc_sdp_local.media_list[i].attributes[j].curr.statusType == "remote")
							{vc_sdp_local.media_list[i].attributes[j].curr.statusType := "local"};
						// invert send/recv direction tags
						if (vc_sdp_local.media_list[i].attributes[j].curr.direction == "send")
							{vc_sdp_local.media_list[i].attributes[j].curr.direction := "recv"};
						if (vc_sdp_local.media_list[i].attributes[j].curr.direction == "recv")
							{vc_sdp_local.media_list[i].attributes[j].curr.direction := "send"};
					}				
					// b) copy/keep SDP_attribute_des (keep strength, invert tags if applicable)	
					else if (ischosen(vc_sdp_local.media_list[i].attributes[j].des))
					{
						// invert local/remote status tags
						if (vc_sdp_local.media_list[i].attributes[j].des.statusType == "local")
							{vc_sdp_local.media_list[i].attributes[j].des.statusType := "remote"};
						if (vc_sdp_local.media_list[i].attributes[j].des.statusType == "remote")
							{vc_sdp_local.media_list[i].attributes[j].des.statusType := "local"};
						// invert send/recv direction tags
						if (vc_sdp_local.media_list[i].attributes[j].des.direction == "send")
							{vc_sdp_local.media_list[i].attributes[j].des.direction := "recv"};
						if (vc_sdp_local.media_list[i].attributes[j].des.direction == "recv")
							{vc_sdp_local.media_list[i].attributes[j].des.direction := "send"};
					}				
					// c) simplification: assume no SDP_attribute_conf	
					else if (ischosen(vc_sdp_local.media_list[i].attributes[j].conf))
					{
						// todo: handle SDP_attribute_conf
					}					
						
					 
					else 
					{
						// simple copy of attribute
						v_mediaAttributes[k] := vc_sdp_local.media_list[i].attributes[j];
						k := k+1;
					}
				}
				vc_sdp_local.media_list[i].attributes := v_mediaAttributes;
			}
		}
		// add handling of prenegotiation, change ports if required etc.
		//if prenegotiation...
	}

	/** 
	*  @desc reject SDP offer by setting media ports to 0
	*		 
	*/
	function f_reject_SDP_offer() runs on SipComponent
	{
		var integer mn, i;
		f_copy_SDP(); // TO BE DONE with more details!
		//increase session version
		vc_sdp_local.origin.session_version := int2str(str2int(vc_sdp_local.origin.session_version)+1);
		// if more than one codec, select the firs one
		mn:= sizeof(vc_sdp_local.media_list);
		for (i :=0;  i < mn; i := i+1)
		{
			vc_sdp_local.media_list[i].media_field.ports := {0, omit};
			vc_sdp_local.media_list[i].attributes := omit; //{};
		};
	}

rennoch's avatar
rennoch committed
	/**
rennoch's avatar
rennoch committed
	 * @desc 	copies SDP message elements from remote to local component variable: 
	 * 				- bandwidth
	 * 				- session version (will be incremented)
	 * 				- media list
	 * 			modify the direction attribute of an SDP media list entry within an SDP message (vc_sdp_local)
	 * @param 	p_medianum 		list position number of the media (if value 0 identifies first media list element)
	 * @param 	p_direction		the new direction attribute to be included in the media entry
rennoch's avatar
rennoch committed
	 * @verdict 
	 */
	function f_SIP_modMediaDirection(integer p_medianum, template SDP_attribute p_direction) runs on SipComponent
	{
rennoch's avatar
rennoch committed
		var boolean v_set_direction; // flag indicates if direction attribute has been modified
		var integer v_mn := 0; 		 // length of media list (number of entries)
		var integer v_cn := 0; 		 // number of attributes of a media entry
		var integer i, j, k := 0;
		var SDP_attribute_list v_mediaAttributes := {}; // collect the media attributes (to be assigned at end of function)
		
		f_copy_SDP(); // copy SDP session bandwidth and media list from remote to local component variable
		
		// increment session version
		vc_sdp_local.origin.session_version := int2str(str2int(vc_sdp_local.origin.session_version)+1);
rennoch's avatar
rennoch committed
		
		// if more than one codec, select the first one
		v_mn:= sizeof(vc_sdp_local.media_list);

		if (p_medianum == 0) //specific media requested
rennoch's avatar
rennoch committed
    		{
    			p_medianum := 1; // start checking from first media
    		};
		if (p_medianum > 0) //specific media requested
rennoch's avatar
rennoch committed
    		{
    			if (not(p_medianum > v_mn)) 
    				{v_mn := p_medianum}
    		};
    		
		// handling of media list elements
		for (i :=0;  i < v_mn; i := i+1)
		{
rennoch's avatar
rennoch committed
			v_cn := 0; // initialize the number of attributes of the media list entry
rennoch's avatar
rennoch committed
			if (ispresent(vc_sdp_local.media_list)) //media_list is optional
			{						
//				log("vc_sdp_local.media_list[i] ",vc_sdp_local.media_list[i]);
				if (ispresent(vc_sdp_local.media_list[i].attributes))
				{
					v_cn := sizeof(vc_sdp_local.media_list[i].attributes);
				};
				
				v_set_direction := false;
				//if (sizeof(vc_sdp_local.media_list[i].media_field.fmts)>1) 
				// select the first one
rennoch's avatar
rennoch committed
				for (j :=0; j<v_cn; j:=j+1)
				{ 
					if (ischosen(vc_sdp_local.media_list[i].attributes[j].recvonly)
							or ischosen(vc_sdp_local.media_list[i].attributes[j].sendonly)
							or ischosen(vc_sdp_local.media_list[i].attributes[j].inactive)
							or ischosen(vc_sdp_local.media_list[i].attributes[j].sendrecv))
						{
							v_mediaAttributes[k] := valueof(p_direction); 
							v_set_direction := true;
						}
				 		else // non-direction attributes will be copied
						{
							v_mediaAttributes[k] := vc_sdp_local.media_list[i].attributes[j];
							k := k+1;
						}
				}
				
				if (not v_set_direction) 
					{ v_mediaAttributes[k] := valueof(p_direction)};
				vc_sdp_local.media_list[i].attributes := v_mediaAttributes;
    				
		}	 
		// add handling of prenegotiation, change ports if required etc.
		//if prenegotiation...
	}
	
     /** 
     *  @desc modify session and media attributes direction
     *		 
     */
     function f_SIP_modSessionDirection(template SDP_attribute p_direction) runs on SipComponent
     {
      var boolean v_set_direction;
      var integer v_mn:= 0, i:=0;
      var SDP_attribute_list v_mediaAttributes := {};
      
	  if (ispresent(vc_sdp_local.attributes))
		{ v_mn:= sizeof(vc_sdp_local.attributes);			
       
          for (i :=0;  i < v_mn; i := i+1)
          {//for every single attribute (that is not omit)    
                 if (ischosen(vc_sdp_local.attributes[i].recvonly)
                   or ischosen(vc_sdp_local.attributes[i].sendonly)
                   or ischosen(vc_sdp_local.attributes[i].inactive)
                   or ischosen(vc_sdp_local.attributes[i].sendrecv))
                 {
                  v_mediaAttributes[i] := valueof(p_direction); 
                  v_set_direction := true;
                 }
                 else // simple copy of attribute
                 {v_mediaAttributes[i] := vc_sdp_local.attributes[i]}        				 
           }
           if (not v_set_direction) // if not sent before
               { v_mediaAttributes[v_mn] := valueof(p_direction)};
           vc_sdp_local.attributes := v_mediaAttributes;       
		};    
    }
 
	/** 
	*  @desc c
	*		 
	*/


    /*
     * 
     * @desc check (from remote) and set (local) the session/media attribute lines on directions
     * @param p_direction_in incoming SDP attribute that need to be checked
     * @param p_direction_out SDP attribute that should be included in the SDP answer (to be returned to peer)
     * @return 
     * @verdict 
     */	
	function f_SIP_checksetSDPreqDirection(template SDP_attribute p_direction_in, template SDP_attribute p_direction_out) runs on SipComponent
	{	var template SDP_attribute v_direction_out := p_direction_out;
		// check incoming SDP attribute
		if (not (ispresent(vc_request.messageBody) and f_check_attribute(vc_request.messageBody.sdpMessageBody,p_direction_in))) 
			{setverdict(fail);};
		if (match(omit,p_direction_out))//not isvalue(v_direction_out))//MRO
			{v_direction_out := f_get_attribute_answer(vc_request.messageBody.sdpMessageBody, p_direction_in);}
		f_SIP_modMediaDirection(1, v_direction_out); // handling of attribute in media description
		f_SIP_modSessionDirection(v_direction_out); // handling of attribute in session		
	}

	/*
		* 
		* @desc check (from remote) and set (local)the session/media attribute lines on directions
		* @param p_direction_in attribute to be check
		* @param p_direction_out attrubyte to be 
		* @return 
		* @verdict 
		*/	
    function f_SIP_checkSDPrespDirection(template SDP_attribute p_direction_in) runs on SipComponent
    {		
    	// check incoming SDP attribute
    	if (not (ispresent(vc_response.messageBody) and f_check_attribute(vc_response.messageBody.sdpMessageBody,p_direction_in))) 
    		{setverdict(fail);};
    }

	/** 
	*  @desc check media/attribute lines from remote
	*		 
	*/
	function f_SIP_checkMediaDirection(integer p_medianum, template SDP_attribute p_direction) runs on SipComponent
	return boolean
	{
		var integer v_mn, v_cn := 0, i, j;
		var boolean v_result := false;
		//increase session version
		vc_sdp_remote.origin.session_version := int2str(str2int(vc_sdp_remote.origin.session_version)+1);
		// if more than one codec, select the firs one
		v_mn:= sizeof(vc_sdp_remote.media_list);
		if (p_medianum == 0) //specific media requested
		{
			p_medianum := 1; // start checking from first media
		};
		if (p_medianum > 0) //specific media requested
		{
			if (p_medianum > v_mn) {return false}
			else {v_mn := p_medianum}
		};
		for (i :=p_medianum-1;  i < v_mn; i := i+1)
		{
			//for every single media
			if (ispresent(vc_sdp_remote.media_list[i].attributes))
			{
				v_cn := sizeof(vc_sdp_remote.media_list[i].attributes);
				log (v_cn);
			};
			if (sizeof(vc_sdp_remote.media_list[i].attributes)>0) 
			{
				// select the first one
				log(vc_sdp_remote.media_list[i].attributes);
				for (j :=0; j<sizeof(vc_sdp_remote.media_list[i].attributes); j:=j+1)
				{
					log(vc_sdp_remote.media_list[i].attributes[j]);
					if (ischosen(vc_sdp_remote.media_list[i].attributes[j].recvonly)
							or ischosen(vc_sdp_remote.media_list[i].attributes[j].sendonly)
							or ischosen(vc_sdp_remote.media_list[i].attributes[j].inactive)
							or ischosen(vc_sdp_remote.media_list[i].attributes[j].sendrecv))
					{
						if (match(vc_sdp_remote.media_list[i].attributes[j],p_direction))
						{ v_result :=  true; }
						else { return  false; }
					}

					//v_result :=  true; // TODO This is a shortcut since direction attributes are not decoded
				}
			}
		}
		return v_result
	}

	/** 
	*  @desc copy media/attribute lines from remote to local SDP variable
	*		 
	*/
	function f_copy_SDP() runs on SipComponent
		if (ispresent(vc_sdp_remote.bandwidth))
rennoch's avatar
rennoch committed
				{vc_sdp_local.bandwidth := vc_sdp_remote.bandwidth}
			else {vc_sdp_local.bandwidth := {}};
			
		if (ispresent(vc_sdp_remote.media_list))
		{
rennoch's avatar
rennoch committed
                //			// cleaning of media before assignment	
                //			if (ispresent(vc_sdp_local.media_list))
                //			{
                //				for (var integer i:=0; i<sizeof(vc_sdp_local.media_list); i:=i+1)
                //				{			
                //					vc_sdp_local.media_list[i] := omit ; 						  
                //				}			
                //			};		
			vc_sdp_local.media_list := vc_sdp_remote.media_list;
		}
	}
}//end group SDPOperations

group AwaitingMessage {

	/**
	 * 
	 * @desc Function waiting for any MSG -request/response 
	 */
	function f_awaitingAnyPassOnTimeout() runs on SipComponent
	{
	  tc_wait.start(PX_SIP_TWAIT);
	  alt
	  {
		[] SIPP.receive	//TAU error if expect (*)
		  {
			tc_wait.stop;
			vc_boo_response:=true;
			vc_boo_request:=true;
			//setverdict(pass)
		  }
		[] tc_wait.timeout
		  {
			vc_boo_response:=false;
			vc_boo_request:=false;
			//setverdict (pass)
		  }
	  }
	} //end f_awaitingResponsePassOnTimeout

	/**
	 * 
	 * @desc Function waiting for no MSG -request/response 
	 */
	function f_awaitingNonePassOnTimeout() runs on SipComponent
	{
	  tc_wait.start(PX_SIP_TWAIT);
	  alt
	  {
		[] SIPP.receive	
		  {
			tc_wait.stop;
			setverdict(fail);
		  }
		[] tc_wait.timeout
		  {
			setverdict (pass);
		  }
	  }
	} //end f_awaitingResponsePassOnTimeout
		
	/**
	 * 
	 * @desc function awaits REGISTER
	 * @param p_register expected REGISTER request
	 */	
 	function f_awaitingREGISTER(in template REGISTER_Request p_register) runs on SipComponent
	{
      
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
		  [] SIPP.receive(p_register)-> value v_request sender vc_sent_label
			{
			  tc_resp.stop;
			  f_setHeadersOnReceiptOfREGISTER(v_request);
			}
          [] tc_resp.timeout
            {
              setverdict (fail);
            }
		}		
	}
	
	/**
	 * 
	 * @desc function awaits SUBSCRIBE
	 * @param p_register expected SUBSCRIBE request
	 */	
	function f_awaitingSUBSCRIBE(in template SUBSCRIBE_Request p_register) runs on SipComponent
	{
		var Request	v_request;
      
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
		  [] SIPP.receive(p_register)-> value v_request sender vc_sent_label
			{
			  tc_resp.stop;
			  f_setHeadersOnReceiptOfSUBSCRIBE(v_request);
			}
		  [] tc_resp.timeout
			{
			  setverdict (fail);
			}
	 * 
	 * @desc function awaits REGISTER and sends a 200 OK response
	 * @param p_reply flag used to avoid the 200OK response sending
	 */	
 	function f_awaitingREGISTER_sendReply(in template REGISTER_Request p_register, in boolean p_reply) runs on SipComponent
	{
		var Request	v_request;
      
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
		  [] SIPP.receive(p_register)-> value v_request sender vc_sent_label
			{
			  tc_resp.stop;
			  vc_request := v_request;
			  f_setHeadersOnReceiptOfREGISTER(v_request);
			  //Answer to the Request
			  if (p_reply) {f_send200OK();};
			}

		  [] tc_resp.timeout
			{
			  setverdict (fail);
			}
	 * 
	 * @desc Function waiting for a 200 OK response
	 * @param p_cSeq_s current cSeq expectation
	 */
	function f_awaitingOkResponse(inout CSeq p_cSeq_s) runs on SipComponent
	{ 

  	tc_ack.start(PX_SIP_TACK);
  	alt
  	{
		[] SIPP.receive	(mw_Response_Base(c_statusLine200, vc_callId, p_cSeq_s)) -> value vc_response
			tc_ack.stop;
			f_setHeadersOnReceiptOfResponse(vc_cSeq, vc_response);
			setverdict(pass)
		  }
		[] tc_ack.timeout
		  {
			setverdict (fail);
		  }
  	}
	} //end awaitingOkResponse

	/**
	 * 
	 * @desc Function waiting for a response
	 * @param p_Response expected response message
	 */
	function f_awaitingResponse(in template Response p_Response) runs on SipComponent
	{
	  tc_ack.start(PX_SIP_TACK);
	  alt
	  {
		[] SIPP.receive	(p_Response) -> value vc_response
		  {
			tc_ack.stop;
			f_setHeadersOnReceiptOfResponse(vc_cSeq, vc_response);
			setverdict(pass)
		  }
		[] tc_ack.timeout
		  {
			setverdict(fail);
		  }
	  }
	} //end f_awaitingResponse
	
	/**
		* 
		* @desc Function waiting for a response and send ACK on FailureResponses 4xx,5xx,6xx
		* @param p_Response expected response message
		*/
	function f_awaitingResponseSendACK(in template Response p_Response) runs on SipComponent
	{
		tc_ack.start(PX_SIP_TACK);
poglitsch's avatar
poglitsch committed
    	alt {
			[] SIPP.receive	(p_Response) -> value vc_response {
    			tc_ack.stop;
    			f_setHeadersOnReceiptOfResponse(vc_cSeq, vc_response);
				f_SendACK(m_ACK_Request_Base(vc_requestUri, vc_callId, vc_cSeq, vc_from, vc_to, vc_via));
    			setverdict(pass);
poglitsch's avatar
poglitsch committed
			[] tc_ack.timeout {
    			setverdict(fail);
    		}
    	}
	} //end f_awaitingResponse
	
	/**
		 * 
		 * @desc Function waiting for a response
		 * @param p_Response expected response message
		 */
		function f_awaitingResponsePassOnTimeout(in template Response p_Response) runs on SipComponent
		{
		  tc_ack.start(PX_SIP_TACK);
		  alt
		  {
			[] SIPP.receive	(p_Response) -> value vc_response
			  {
				tc_ack.stop;
				f_setHeadersOnReceiptOfResponse(vc_cSeq, vc_response);
				vc_boo_response:=true;
				//setverdict(pass)
			  }
			[] tc_ack.timeout
			  {
			  	vc_boo_response:=false;
			  	//setverdict (pass)
			  }
		  }
		} //end f_awaitingResponsePassOnTimeout
	
	/** 
	*  @desc await INFO request
	*		 reply with 200 OK
	*/
	function f_awaitingINFO_sendReply(in template INFO_Request p_MSG) runs on SipComponent
	{
		var INFO_Request	v_MSG;
      
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
		  [] SIPP.receive(p_MSG)-> value v_MSG sender vc_sent_label
			{
			  tc_resp.stop;
			  f_setHeadersOnReceiptOfRequest(v_MSG);
			  //Answer to the INFO
			  f_send200OK();
			}
		  [] tc_resp.timeout
			{
			  setverdict (fail);
			}
		}
	} // end of f_awaitingINFO_sendReply
	
	 * 
	 * @desc function awaiting for an incoming INVITE
	 * @param p_request expected message
	 */
	function f_awaitingINVITE(template INVITE_Request p_request) runs on SipComponent
	{
	  var INVITE_Request v_INVITE_Request;
      
	  tc_wait.start(PX_SIP_TWAIT);
	  alt
	  {
		[]SIPP.receive	(p_request) -> value v_INVITE_Request sender vc_sent_label
		  { 
			tc_wait.stop;
			vc_ignore_invite := true;
			vc_first_recv:= true; // communication has started
			f_setHeadersOnReceiptOfINVITE(v_INVITE_Request);
			SIPP.send(m_Response_Base(c_statusLine100, vc_callId, vc_cSeq, vc_from, vc_to, vc_via)) to vc_sent_label;
		  }

		[] tc_wait.timeout
		  {
			setverdict (fail);
		  }
	} //end f_awaitingINVITE

	/**
		* 
		* @desc function awaiting for an incoming INVITE
		* @param p_request expected message
		*/
	function f_awaitingINVITE_No100Response(template INVITE_Request p_request) runs on SipComponent
	{
	  var INVITE_Request v_INVITE_Request;
      
      tc_wait.start(PX_SIP_TWAIT);
      alt
      {
    	[]SIPP.receive	(p_request) -> value v_INVITE_Request sender vc_sent_label
    	  { 
    		tc_wait.stop;
    		vc_ignore_invite := true;
    		vc_first_recv:= true; // communication has started
    		f_setHeadersOnReceiptOfINVITE(v_INVITE_Request);
    	    //SIPP.send(m_Response_Base(c_statusLine100, vc_callId, vc_cSeq, vc_from, vc_to, vc_via)) to vc_sent_label;
    	  }

		[] tc_wait.timeout
		  {
			setverdict (fail);
		  }
      }
	} //end f_awaitingInviteRequest

	/**
	 * 
	 * @desc function awaiting for an incoming INVITE
	 * @param p_request expected message
	 */
	function f_awaitingINVITE_PassOnTimeout(template INVITE_Request p_request) runs on SipComponent
	{
	  var INVITE_Request v_INVITE_Request;
      
	  tc_wait.start(PX_SIP_TWAIT);
	  alt
	  {
		[]SIPP.receive	(p_request) -> value v_INVITE_Request sender vc_sent_label
		  { 
			tc_wait.stop;
			vc_ignore_invite := true;
			vc_first_recv:= true; // communication has started
			vc_boo_request := true;
			f_setHeadersOnReceiptOfINVITE(v_INVITE_Request);
			SIPP.send(m_Response_Base(c_statusLine100, vc_callId, vc_cSeq, vc_from, vc_to, vc_via)) to vc_sent_label;
		  }
		[]tc_wait.timeout
		  {
			vc_boo_request := false;
		  }
	  }
	} //end f_awaitingInviteRequest

	/**
	 * @desc function awaiting ACK request
	 */
	function f_awaitingACK(in template ACK_Request p_ACK) runs on SipComponent
	{
	  var Request v_ACK_Request;
	  tc_ack.start(PX_SIP_TACK);
      
	  alt
	  {
		[] SIPP.receive(p_ACK) -> value v_ACK_Request
		  {
			tc_ack.stop;
		  }
		// INVITE may be repeated and shall be ignored
		[]SIPP.receive(mw_INVITE_Request_Base)
		  {
			repeat;
		  }
		// Ignore othe message
		[] SIPP.receive
		  {
			repeat;
		  }

		[] tc_ack.timeout
		  {
			setverdict (fail);
		  }
	  }
	} //end f_awaitingAckRequest

	/**
	 * 
	 * @desc function awaiting BYE and sending 200OK response
	 * @param p_BYE expected BYE
	 */
	function f_awaitingBYE(in template BYE_Request p_BYE) runs on SipComponent
	{
	  var BYE_Request v_BYE_Request;
      
	  tc_resp.start(PX_SIP_TRESP);
	  alt
	  {
		[]SIPP.receive	(p_BYE) -> value v_BYE_Request sender vc_sent_label
		  {
			tc_resp.stop;
			vc_ignore_bye:= true;
			f_setHeadersOnReceiptOfBYE(v_BYE_Request);
			//f_send200OK();
		  }
		[] tc_resp.timeout
		  {
			setverdict (fail);
		  }
	 * 
	 * @desc function awaiting BYE and sending 200OK response
	 * @param p_BYE expected BYE
	 */
	function f_awaitingBYE_sendReply
	(in template BYE_Request p_BYE) runs on SipComponent
	{
	  var BYE_Request v_BYE_Request;
      
	  tc_resp.start(PX_SIP_TRESP);
	  alt
	  {
		[]SIPP.receive	(p_BYE) -> value v_BYE_Request sender vc_sent_label
		  {
			tc_resp.stop;
			vc_ignore_bye:= true;
			f_setHeadersOnReceiptOfBYE(v_BYE_Request);
			f_send200OK();
		  }
		 [] tc_resp.timeout
		  {
			setverdict (fail);
		  }
	  }		
	} // end f_awaitingBYE_sendReply
	
	/**
	 * 
	 * @desc function awaiting BYE and sending 200OK response
	 * @param p_BYE expected BYE
	 */
	function f_awaitingBYE_sendReply_PassOnTimeout(in template BYE_Request p_BYE) runs on SipComponent
	{
	  var BYE_Request v_BYE_Request;
      
	  tc_resp.start(PX_SIP_TRESP);
	  alt
	  {
		[]SIPP.receive	(p_BYE) -> value v_BYE_Request sender vc_sent_label
		  {
			tc_resp.stop;
			vc_ignore_bye:= true;
			vc_boo_request := true;
			f_setHeadersOnReceiptOfBYE(v_BYE_Request);
			f_send200OK();
		  }
		[] tc_resp.timeout
		  {
		  	vc_boo_request := false;
		  }
		
	  }		
	} // end f_awaitingBYE_sendReply_PassOnTimeout

	/**
	* 
	* @desc function awaiting CANCEL
	* @param p_CANCEL expected CANCEL
	*/
	function f_awaitingCANCEL(in template CANCEL_Request p_CANCEL) runs on SipComponent
	{
		var CANCEL_Request v_MSG;
     
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
		[]SIPP.receive	(p_CANCEL) -> value v_MSG sender vc_sent_label
		  {
			tc_resp.stop;
			f_setHeadersOnReceiptOfRequest(v_MSG);
		  }
		[] tc_resp.timeout
		  {
			setverdict (fail);
		  }
		}		
	} // end f_awaitingCANCEL
	/** 
	*  @desc await MESSAGE request
	*/
	function f_awaitingMESSAGE(in template MESSAGE_Request p_MSG) runs on SipComponent
	{
		var MESSAGE_Request	v_MSG;
  
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
		  [] SIPP.receive(p_MSG)-> value v_MSG sender vc_sent_label
			{
			  tc_resp.stop;
			  f_setHeadersOnReceiptOfRequest(v_MSG);
			}
		  [] SIPP.receive(mw_MESSAGE_Request_Base)-> value v_MSG sender vc_sent_label
			{
			  tc_resp.stop;
			  f_setHeadersOnReceiptOfRequest(v_MSG);
			  log("Received MESSAGE not as expected!");
			  setverdict (fail);
		  [] tc_resp.timeout
			{
			  setverdict (fail);
			}
		}
	} // end of f_awaitingMESSAGE
	
	/** 
	*  @desc await MESSAGE request
	*		 reply with 200 OK
	*/
	function f_awaitingMESSAGE_sendReply() runs on SipComponent
	{
		var MESSAGE_Request	v_MSG;
      
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
poglitsch's avatar
poglitsch committed
		  [] SIPP.receive(mw_MESSAGE_Request_Base)-> value v_MSG sender vc_sent_label
			{
			  tc_resp.stop;
			  f_setHeadersOnReceiptOfRequest(v_MSG);
			  //Answer to the MESSAGE
			  f_send200OK();
			}
		  [] tc_resp.timeout
			{
			  setverdict (fail);
			}
		}		
			
	} // end of f_awaitingMESSAGE_sendReply

	/** 
	*  @desc await MESSAGE request
	*/
	function f_awaitingMESSAGE_sendReply_PassOnTimeout(in template MESSAGE_Request p_MSG) runs on SipComponent
	{
		var MESSAGE_Request	v_MSG;
  
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
		  [] SIPP.receive(p_MSG)-> value v_MSG sender vc_sent_label
			{
			  tc_resp.stop;
			  f_setHeadersOnReceiptOfRequest(v_MSG);
			  //Answer to the MESSAGE
			  //f_send200OK();
			  vc_boo_request := true;
			  f_send200OK();
			  //setverdict (pass);
			}
		  [] tc_resp.timeout
		  	{
			  vc_boo_request := false;
			  //setverdict (pass);
		  	}
		}
	} // end of f_awaitingMESSAGE_PassOnTimeout
	
	/** 
	*  @desc await NOTIFY request
	*		 reply with 200 OK
	*/
	function f_awaitingNOTIFY_sendReply(in template NOTIFY_Request p_MSG) runs on SipComponent
	{
		var NOTIFY_Request	v_MSG;
      
		tc_resp.start(PX_SIP_TRESP);
		alt
		{
		  [] SIPP.receive(p_MSG)-> value v_MSG sender vc_sent_label
			{
			  tc_resp.stop;
			  f_getRouteMapIntoRecordRoute(vc_cSeq, v_MSG);
			  f_setHeadersOnReceiptOfRequest(v_MSG);
			  //Answer to the NOTIFY
			  f_send200OK();
			}
		  [] tc_resp.timeout
			{
			  setverdict (fail);
			}
		}
	} // end of f_awaitingNOTIFY_sendReply	

    /** 
    *  @desc await PRACK request
    *		 reply with 200 OK
    */
    function f_awaitingPRACK_sendReply(in template PRACK_Request p_MSG) runs on SipComponent
    {
    	var PRACK_Request	v_MSG;
      
    	tc_resp.start(PX_SIP_TRESP);
    	alt
    	{
    	  [] SIPP.receive(p_MSG)-> value v_MSG sender vc_sent_label
			  tc_resp.stop;
			  f_setHeadersOnReceiptOfRequest(v_MSG);
			  //Answer to the PRACK
			  f_send200OK();

		  [] tc_resp.timeout
			{
			  setverdict (fail);
			}
    	}		
    		
    } // end of f_awaitingPRACK_sendReply
	
		/** 
	*  @desc await PUBLISH request
	*		 reply with 200 OK
	*/
	function f_awaitingPUBLISH_sendReply(in template PUBLISH_Request p_MSG) runs on SipComponent
	{
		var PUBLISH_Request	v_MSG;
  
		tc_resp.start(PX_SIP_TRESP);
		alt