LibSip_Steps.ttcn 108 KB
Newer Older
		  // and Re-send REGISTER request with Authorization header
		  tc_ack.start(PX_SIP_TACK);
		  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();
				// Re-send protected REGISTER
				f_SendREGISTER(v_request);//LibSip
	            
	            // awaiting 200 OK REGISTER
				f_awaitingOkResponse(p_cSeq_s);
				f_getServiceRouteMapIntoRouteInRegistration(p_cSeq_s, vc_response);
			  }
			[] SIPP.receive	(mw_Response_Base(c_statusLine200, vc_callId, p_cSeq_s))
			  {
				tc_ack.stop;
				log ("Authorization was not requested as expected");
				setverdict(inconc)
			  }
		  }
		}
		else
		{
		  f_awaitingOkResponse(p_cSeq_s);
		  f_getServiceRouteMapIntoRouteInRegistration(p_cSeq_s, vc_response);
		}      

	  };
	}//end function f_Registration


	/**
	 * 
	 * @desc remove registration
	 * @param p_cSeq_s cseq parameter
	 */	
	function f_RemoveRegistration(inout CSeq p_cSeq) runs on SipComponent
	{
	  var CommaParam_List v_challenge;
	  var Credentials v_credentials;
	  var REGISTER_Request v_request := valueof(m_REGISTER_Request_expires(vc_requestUri, vc_callId,
	  p_cSeq,  vc_from, vc_to, vc_via, vc_contact, vc_authorization, "0"));
	  
	  if (PX_SIP_REGISTRATION)
	  {
		f_setHeaders_deREGISTER(p_cSeq);
      
		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(PX_SIP_TACK);
			alt
			{
			  [] SIPP.receive	(mw_Response_Base(c_statusLine401, vc_callId, p_cSeq)) -> value vc_response
				{
				  tc_ack.stop;
				  // set headers via, cseq and authorization
				  f_setHeaders_2ndREGISTER();
				  // Re-send protected REGISTER
				  f_SendREGISTER(v_request);//LibSip
				  
				  // awaiting 200 OK REGISTER
				  f_awaitingOkResponse(p_cSeq);
				  f_getServiceRouteMapIntoRouteInRegistration(p_cSeq, vc_response);
				}
			  [] SIPP.receive	(mw_Response_Base(c_statusLine200, vc_callId, p_cSeq))
				{
				  tc_ack.stop;
				  log ("Authorization was not requested as expected");
				  setverdict(inconc)
				}
			}
		}
		else
		{
		  f_awaitingOkResponse(p_cSeq);
		}
	  }
	} // end f_RemoveRegistration

	/**
	 * 
	 * @desc remove registration without authorization
	 * @param p_cSeq_s cseq parameter
	 */	
	function f_RemoveRegistration_wo_authorization(inout CSeq p_cSeq) runs on SipComponent
	{
	  var SemicolonParam_List tmp_params;
	  if (PX_SIP_REGISTRATION)
	  {
		f_setHeaders_deREGISTER(p_cSeq);
      	f_SendREGISTER(m_REGISTER_Request_expires(vc_requestUri, vc_callIdReg, p_cSeq,
		  vc_from, vc_to, vc_via, vc_contact, vc_authorization, "0" ));
   	    f_awaitingOkResponse(p_cSeq);		
	  }
	} // end f_RemoveRegistration_wo_authorization

}//end group Registration

	group Subscription {
	
		/**
		 * 
		 * @desc  UE send subscrbe, await on 200 OK, await notify and send 200 OK
		 * @param p_cSeq_s		cseq parameter 
		 * @param p_register	subscribe template
		 */
		function f_Subscription(inout CSeq p_cSeq_s, template SUBSCRIBE_Request p_subscribe) runs on SipComponent
		{
		  f_setHeaders_SUBSCRIBE(p_cSeq_s);
		  //send SUBSCRIBE
		  f_SendSUBSCRIBE(p_subscribe);
		  // awaiting 200 OK SUBSCRIBE
		  f_awaitingOkResponse(p_cSeq_s);
		  
		  //await NOTIFY and send reply 200 OK
		  f_awaitingNOTIFY_sendReply(mw_NOTIFY_Request_Base(vc_callId));
	  
		}//end function f_Subscription

		/**
		 * 
		 * @desc  UE send subscrbe, await on 200 OK, await notify and send 200 OK
		 * @param p_cSeq_s		cseq parameter 
		 * @param p_register	subscribe template
		 */
		function f_SubscriptionWithNotification(inout CSeq p_cSeq_s, template SUBSCRIBE_Request p_subscribe, template NOTIFY_Request p_notify) runs on SipComponent
		{
		  f_setHeaders_SUBSCRIBE(p_cSeq_s);
		  //send SUBSCRIBE
		  f_SendSUBSCRIBE(p_subscribe);
		  // awaiting 200 OK SUBSCRIBE
		  f_awaitingOkResponse(p_cSeq_s);
		  
		  //await NOTIFY and send reply 200 OK
		  f_awaitingNOTIFY_sendReply(p_notify);
	  
		}//end function f_Subscription

	}//end group Subscription

group Preambles {
	
	/**
	 * 
	 * @desc  Set variables and default initialization for user profile
	 * @param p_userprofile	user profile of call
	 * @param p_cSeq_s 		cseq parameter
	 */
	function f_SIP_preamble_woREG(in integer p_userprofile, inout CSeq p_cSeq_s)  runs on SipComponent
	{
		//varables and altsteps
		f_init_component(p_cSeq_s);

		//Preamble
		f_init_userprofile(p_userprofile); // assignment of PIXIT values to component variable
		vc_sdp_local := valueof(m_SDP_bandwidth(valueof(m_media_dynPT(PX_SIP_SDP_dyn, PX_SIP_SDP_encoding)), vc_userprofile));
	}
	
	/**
	 * 
	 * @desc  Set variables and default initialization for user profile and handle registration and authentication with MD5 
	 * @param p_userprofile   	user profile of call
	 * @param p_cSeq_s		  	cseq parameter
	 * @param p_register		register template
	 */
	function f_SIP_preamble_withREG(in integer p_userprofile, inout CSeq p_cSeq_s, template REGISTER_Request p_register)  runs on SipComponent
	{
		//preamble
		f_SIP_preamble_woREG(p_userprofile, p_cSeq_s);
		
		//Registration, Awaiting
		f_Registration(p_cSeq_s, p_register, PX_SIP_REGISTER_AUTHENTICATION_ENABLED);
	}	
	
}// end group Preambles

group Postambles {

	/**
	 * 
	 * @desc function send BYE and awaits reponse
	 * @param p_CallId parameter for outgoing BYE
	 * @param p_cSeq parameter for outgoing BYE
	 * @param p_from parameter for outgoing BYE
	 * @param p_to parameter for outgoing BYE
	 * @param p_reqHostPort parameter for outgoing BYE
	 */
	function f_terminateCall(SipUrl p_requestUri, CallId p_CallId, inout CSeq p_cSeq, From p_from,
	  template To p_to) runs on SipComponent
	{
	  // Sending of a BYE request to release the call and expect a final response
	  f_SendBYE(m_BYE_Request_cause(p_requestUri, p_CallId, p_cSeq, p_from, valueof(p_to), vc_via, PX_SIP_BYE_CAUSE));
      
	  tc_resp.start(PX_SIP_TRESP);
	  alt
	  {
		[] SIPP.receive	(mw_Response_Base(mw_statusLine1xx, p_CallId, p_cSeq))
		  {
			repeat;
		  }
		[] SIPP.receive	(mw_Response_Base(mw_statusLineFinal, p_CallId, p_cSeq))
		  {
			tc_resp.stop;
		  }
		[] tc_resp.timeout
		  {
			stop
		  }
	  }
	} // end function f_terminateCall

	function f_cancelCall(template CANCEL_Request p_request)
	runs on SipComponent
	{
	  // This function is called to bring back the IUT in idle condition
	  // in case of errors or unexpected behaviour.
      
	  // Sending of a CANCEL request with the same Cseq
	  f_SendCANCEL(p_request);
	  tc_resp.start(PX_SIP_TRESP);
	  alt
	  {
		[] SIPP.receive	(mw_Response_Base(c_statusLine200, vc_callId, vc_cSeq))
		  {
			tc_resp.stop;
		  }
	  }
	}

} // end group Postambles

group SipChecks
{


	/* 
	*  @desc check the presence of conversation at SIP side
	*		 
	*/
	function f_check_Conversation() runs on SipComponent
	{
	var boolean v_result;
	var charstring v_question := "confirm if conversation at SIP port";
		
	if (PX_SIP_CheckConversation) {				
		opPort.call(s_SIP_conversation:{v_question, -})
		{[] opPort.getreply(s_SIP_conversation:{-, true}) {}
		 [] opPort.getreply(s_SIP_conversation:{-, false}) 
			{all timer.stop;
			 setverdict(fail);
			 syncPort.send(m_syncClientStop);
			 stop;}
		}
	}

	f_selfOrClientSyncAndVerdict(c_uPlane, f_getVerdict()); // Note: implemented in test bodies
		
	return			
	} // end of f_check_Conversation

	/* 
	*  @desc check the presence of conversation at SIP side
	*		 
	*/
	function f_check_Ringing() runs on SipComponent
	{
	var boolean v_result;
	var charstring v_question := "confirm if ringing at SIP port";
		
	if (PX_SIP_CheckRinging) {				
		opPort.call(s_SIP_ringing:{v_question, -})
		{[] opPort.getreply(s_SIP_ringing:{-, true}) {}
		 [] opPort.getreply(s_SIP_ringing:{-, false}) 
			{all timer.stop;
			 setverdict(fail);
			 syncPort.send(m_syncClientStop);
			 stop;}
		}
	}

	f_selfOrClientSyncAndVerdict(c_Ringing, f_getVerdict());
	return			
	} // end of f_check_Ringing

	/* 
	*  @desc check the announcement at SIP side (UE A)
	*		 
	*/
	function f_check_AnnouncementUE_A() runs on SipComponent
	{
	var boolean v_result;
	var charstring v_question := "confirm if announcement at UE A";
		
	if (PX_SIP_CheckConversation) {				
		opPort.call(s_SIP_announcementA:{v_question, -})
		{[] opPort.getreply(s_SIP_announcementA:{-, true}) {}
		 [] opPort.getreply(s_SIP_announcementA:{-, false}) 
			{all timer.stop;
			 setverdict(fail);
			 syncPort.send(m_syncClientStop);
			 stop;}
		}
	}

	f_selfOrClientSyncAndVerdict(c_annoucA, f_getVerdict());
	return			
	} // end of f_check_AnnouncementUE_A

	/* 
	*  @desc check the announcement at SIP side (UE B)
	*		 
	*/
	function f_check_AnnouncementUE_B() runs on SipComponent
	{
	var boolean v_result;
	var charstring v_question := "confirm if announcement at UE B";
		
	if (PX_SIP_CheckConversation) {				
		opPort.call(s_SIP_announcementB:{v_question, -})
		{[] opPort.getreply(s_SIP_announcementB:{-, true}) {}
			[] opPort.getreply(s_SIP_announcementB:{-, false}) 
			{all timer.stop;
				setverdict(fail);
				syncPort.send(m_syncClientStop);
				stop;}
		}
	}

	f_selfOrClientSyncAndVerdict(c_annoucB, f_getVerdict());
	return			
	} // end of f_check_AnnouncementUE_B

	/* 
	*  @desc check the announcement at SIP side
	*		 
	*/
	function f_check_Announcement() runs on SipComponent
	{
	var boolean v_result;
	var charstring v_question := "confirm if announcement at SIP side";
		
	if (PX_SIP_CheckConversation) {				
		opPort.call(s_SIP_announcement:{v_question, -})
		{[] opPort.getreply(s_SIP_announcement:{-, true}) {}
		 [] opPort.getreply(s_SIP_announcement:{-, false}) 
			{all timer.stop;
			 setverdict(fail);
			 syncPort.send(m_syncClientStop);
			 stop;}
		}
	}

	f_selfOrClientSyncAndVerdict(c_annouc, f_getVerdict());
	return			
	} // end of f_check_Announcement

	/* 
	*  @desc check the Voice message at SIP side
	*		 
	*/
	function f_check_VoiceMessage() runs on SipComponent
	{
	var boolean v_result;
	var charstring v_question := "confirm if voice message at SIP side";
		
	if (PX_SIP_CheckConversation) {				
		opPort.call(s_SIP_voiceMessage:{v_question, -})
		{[] opPort.getreply(s_SIP_voiceMessage:{-, true}) {}
		 [] opPort.getreply(s_SIP_voiceMessage:{-, false}) 
			{all timer.stop;
			 setverdict(fail);
			 syncPort.send(m_syncClientStop);
			 stop;}
		}
	}

	f_selfOrClientSyncAndVerdict(c_voicem, f_getVerdict());
	return			
	} // end of f_check_Announcement
	
	/* 
	*  @desc check the stop of media stream
	*		 
	*/
	function f_check_MediaStopped() runs on SipComponent
	{
	var boolean v_result;
	var charstring v_question := "confirm if media stream stopped";
		
	if (PX_SIP_CheckConversation) {				
		opPort.call(s_SIP_mediastopped:{v_question, -})
		{[] opPort.getreply(s_SIP_mediastopped:{-, true}) {}
		 [] opPort.getreply(s_SIP_mediastopped:{-, false}) 
			{all timer.stop;
			 setverdict(fail);
			 syncPort.send(m_syncClientStop);
			 stop;}
		}
	}

	f_selfOrClientSyncAndVerdict(c_uPlaneStop, f_getVerdict());
	return			
	} // end of f_check_MediaStopped

}

group DefaultsTestStep
{
    	
    	
	/**
	* @desc	This default handles receiving of the sync server
	*		STOP message and calls the RT HUT postamble. (copy from common lib)
	*/	
	altstep a_Sip_catchSyncStop() runs on SipComponent 
	{
		[]	syncPort.receive(m_syncServerStop)
		{
			tc_sync.stop ;
			log("**** a_Sip_catchSyncStop: Test component received STOP signal from MTC - going to IDLE state **** ");
			//TODO complete postamble
			f_terminate_component();
			log("**** a_Sip_catchSyncStop: TEST COMPONENT NOW STOPPING ITSELF! **** ") ;
			setverdict(inconc);
			stop ;
		}
	}
	

	/**
	 * 
	 * @desc main default altstep to handle unexpected messages and timeout
	 * @verdict fail for all unexpected branches
	 */	
 	altstep a_clearRegistration() runs on SipComponent
	{
		var Response v_response;
		var Request v_request;
		  
		[] any timer.timeout 
		{
			setverdict(fail); 
			all timer.stop; 
			//TODO check how to solve release of call 
			//f_SendCANCEL(m_CANCEL_Request(vc_callId, vc_cSeq, vc_from, vc_cancel_To, vc_reqHostPort, vc_via )); // difference between registration state or transaction state
			f_RemoveRegistration(vc_cSeq); 
			f_check2Null("");	
		}

	  	// 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
		}

	  	// allow 100 replies
		[] SIPP.receive(mw_Response_Base(c_statusLine100,vc_callId, vc_cSeq))
		  {
			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
		  { 
			f_setHeadersOnReceiptOfResponse(v_response.msgHeader.cSeq, 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
		  { 
			f_setHeadersOnReceiptOfResponse(v_response.msgHeader.cSeq, 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 subscribe on proxy
		[] SIPP.receive(mw_SUBSCRIBE_Request_Base)->value v_request sender vc_sent_label
		  { 
			f_setHeadersOnReceiptOfRequest(v_request); 
			f_send200OK();
			f_setHeadersGeneral(vc_cSeq, "NOTIFY"); // cseq, contact, branch, via
			f_SendNOTIFY(m_NOTIFY_Request_Base(vc_requestUri, vc_callId, vc_cSeq, vc_from, vc_to, vc_via));
			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
		  {
			setverdict(fail);
			f_setHeadersOnReceiptOfRequest(v_request); 
			f_send200OK();
			f_RemoveRegistration(vc_cSeq); 
			f_check2Null("");	
			}			  
			  
		// unexpected CANCEL is acknowledged to avoid retransmissions
		[] SIPP.receive(mw_CANCEL_Request_Base(?))-> value v_request sender vc_sent_label
		  {
			setverdict(fail);
			f_setHeadersOnReceiptOfRequest(v_request);
			//Answer to the CANCEL
			f_send200OK();
			f_RemoveRegistration(vc_cSeq); 
			f_check2Null("");	
			}			  
	  [] SIPP.receive
		{
			setverdict(fail); 
			all timer.stop; 
			f_SendCANCEL(m_CANCEL_Request_Base(vc_requestUri, vc_callId, vc_cSeq, vc_from, vc_cancel_To, vc_via )); // difference between registration state or transaction state
			f_RemoveRegistration(vc_cSeq); 
			f_check2Null("");	
		}
	}
	
	/**
	 * 
	 * @desc altstep handle authentication for INVITE message
	 */	
	altstep a_altstep_401or407() runs on SipComponent {
		[] any port.check (receive) {
			var CommaParam_List v_challenge;
			var Credentials v_Credentials;
			var Response v_Response;
			var Request v_Request := valueof (vc_requestFor407);
					
			tc_ack.start (PX_SIP_TACK);
			alt {
				[] SIPP.receive (mw_Response_Base((c_statusLine401,c_statusLine407),
											  vc_callId,
											  vc_cSeq)) -> value v_Response {
					tc_ack.stop;
					//	get tag from To header if available							
					vc_to := v_Response.msgHeader.toField;
					if (vc_cSeq.method == "INVITE"){
						// send ACK
	   					f_SendACK(m_ACK_Request_Base(vc_requestUri, vc_callId, vc_cSeq, vc_from, vc_to, vc_via));
					}							
					// resent the INVITE message with Proxyauthorization header include
					// Extract challenge and calculate credentials for a response.
					if (ischosen (v_Response
						.msgHeader
						.proxyAuthenticate
						.challenge
						.otherChallenge // instead of digestCln (changed by axr to comply to alcatel)
						)) {
						v_challenge :=
							v_Response
								.msgHeader
								.proxyAuthenticate
								.challenge
								.otherChallenge.authParams; 
						v_Credentials :=
							f_calculatecCredentials(vc_userprofile,
								vc_requestFor407.msgHeader.cSeq.method,
								v_challenge);
					} else {
						log ("No scheme in Proxy Authenticate header!!");
						setverdict (inconc);
						stop;
					}

					vc_branch := c_branchCookie & f_getRndTag();
					vc_via := {
						fieldName := VIA_E,
						viaBody := {
							valueof (m_ViaBody_currIpaddr(vc_branch, vc_userprofile))}
					};

					v_Request.msgHeader.via := vc_via;
					// Increment CSeq sequence number of and add the credentials
					// to the original saved INVITE message.
					vc_cSeq.method := vc_requestFor407.msgHeader.cSeq.method;
					vc_cSeq.seqNumber := vc_cSeq.seqNumber + 1;
					v_Request.msgHeader.cSeq.seqNumber :=
						vc_cSeq.seqNumber;
					v_Request.msgHeader.proxyAuthorization.fieldName :=
						PROXY_AUTHORIZATION_E;
					v_Request.msgHeader.proxyAuthorization.credentials :=
						v_Credentials;
							
					// Re-send the saved INVITE with Authorization header
					// included.
					SIPP.send (v_Request) to vc_sent_label;
				}
			}
		}
	}
    	
    	
} // end of group DefaultsTestStep
} // end module LibSip_Steps