/* Process model C++ form file: msProcedure.pr.cpp */
/* Portions of this file copyright 1986-2010 by OPNET Technologies, Inc. */


/*
 =========================== NOTE ==========================
 This file is automatically generated from msProcedure.pr.m
 during a process model compilation.

 Do NOT manually edit this file.
 Manual edits will be lost during the next compilation.
 =========================== NOTE ==========================
*/



/* This variable carries the header into the object file */
const char msProcedure_pr_cpp [] = "MIL_3_Tfile_Hdr_ 160A 30A modeler 7 517077AA 517077AA 1 esl2-14 skathire 0 0 none none 0 0 none 0 0 0 0 0 0 0 0 2871 6                                                                                                                                                                                                                                                                                                                                                                                                         ";
#include <string.h>



/* OPNET system definitions */
#include <opnet.h>



/* Header Block */

#include "msRecord.h"

#define DETACH_SRC_IN_STRM 2
#define DETACH_ACCEPT 0x06
#define ATTACH_REJECT 0x04

/* transition macros */
#define DETACH_SRC_ARRIVAL (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == DETACH_SRC_IN_STRM)

#define GMM_RCV_IN_STRM 0
#define ATTACH_SRC_IN_STRM 1
#define GMM_XMT_OUT_STRM 0

#define ATTACH_ACCEPT 0x02

/* transition macros */
#define ATTACH_SRC_ARRIVAL (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == ATTACH_SRC_IN_STRM)

#define GMM_RCV_ARRIVAL (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == GMM_RCV_IN_STRM)

#define SM_RCV_IN_STRM 6

#define ACTIVATION_SRC_IN_STRM 3

#define USER_DATA_XMT_OUT_STRM 1
#define SM_XMT_OUT_STRM 2

#define ACTIVATION_ACCEPT 66
#define ACTIVATION_REJECT 67
#define DEACTIVATION_ACCEPT 71


/* transition macros */
#define ACTIVATION_SRC_ARRIVAL (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == ACTIVATION_SRC_IN_STRM)

#define SM_RCV_ARRIVAL (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == SM_RCV_IN_STRM)


#define DEACTIVATION_SRC_IN_STRM 4
/* transition macros */
#define DEACTIVATION_SRC_ARRIVAL (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == DEACTIVATION_SRC_IN_STRM)

#define USER_DATA_SRC_IN_STRM 5
/* transition macros */
#define USER_DATA_SRC_ARRIVAL (op_intrpt_type () == \
OPC_INTRPT_STRM && op_intrpt_strm () == USER_DATA_SRC_IN_STRM)

/* End of Header Block */

#if !defined (VOSD_NO_FIN)
#undef	BIN
#undef	BOUT
#define	BIN		FIN_LOCAL_FIELD(_op_last_line_passed) = __LINE__ - _op_block_origin;
#define	BOUT	BIN
#define	BINIT	FIN_LOCAL_FIELD(_op_last_line_passed) = 0; _op_block_origin = __LINE__;
#else
#define	BINIT
#endif /* #if !defined (VOSD_NO_FIN) */



/* State variable definitions */
class msProcedure_state
	{
	private:
		/* Internal state tracking for FSM */
		FSM_SYS_STATE

	public:
		msProcedure_state (void);

		/* Destructor contains Termination Block */
		~msProcedure_state (void);

		/* State Variables */
		Distribution *	         		imsi_distribution                               ;	/* Allocated the value of the imsi using uniform distribution */
		Stathandle	             		detachProcessTime_gsh                           ;	/* Statistics handle that keep track of the time required to */
		                        		                                                	/* perform a detach procedure (detachRequest sent time -     */
		                        		                                                	/* detachAccept receive time)                                */
		char	                   		debugStr[1000]                                  ;
		Stathandle	             		attachProcessTime_gsh                           ;
		Stathandle	             		activationProcessTime_gsh                       ;
		Stathandle	             		deactivationProcessTime_gsh                     ;
		MSStatus	               		msStatus[100]                                   ;	/* Allocates enough memory space for 100 MS.  Currently */
		                        		                                                	/* onl supports 15 subscribers (constant defined in     */
		                        		                                                	/* msRecord.h)                                          */
		Stathandle	             		tlliInAttachReject_gsh                          ;
		Stathandle	             		tlliInActivateReject_gsh                        ;
		Stathandle	             		rejectCauseInActivation_gsh                     ;

		/* FSM code */
		void msProcedure (OP_SIM_CONTEXT_ARG_OPT);
		/* Diagnostic Block */
		void _op_msProcedure_diag (OP_SIM_CONTEXT_ARG_OPT);

#if defined (VOSD_NEW_BAD_ALLOC)
		void * operator new (size_t) throw (VOSD_BAD_ALLOC);
#else
		void * operator new (size_t);
#endif
		void operator delete (void *);

		/* Memory management */
		static VosT_Obtype obtype;
	};

VosT_Obtype msProcedure_state::obtype = (VosT_Obtype)OPC_NIL;

#define imsi_distribution       		op_sv_ptr->imsi_distribution
#define detachProcessTime_gsh   		op_sv_ptr->detachProcessTime_gsh
#define debugStr                		op_sv_ptr->debugStr
#define attachProcessTime_gsh   		op_sv_ptr->attachProcessTime_gsh
#define activationProcessTime_gsh		op_sv_ptr->activationProcessTime_gsh
#define deactivationProcessTime_gsh		op_sv_ptr->deactivationProcessTime_gsh
#define msStatus                		op_sv_ptr->msStatus
#define tlliInAttachReject_gsh  		op_sv_ptr->tlliInAttachReject_gsh
#define tlliInActivateReject_gsh		op_sv_ptr->tlliInActivateReject_gsh
#define rejectCauseInActivation_gsh		op_sv_ptr->rejectCauseInActivation_gsh

/* These macro definitions will define a local variable called	*/
/* "op_sv_ptr" in each function containing a FIN statement.	*/
/* This variable points to the state variable data structure,	*/
/* and can be used from a C debugger to display their values.	*/
#undef FIN_PREAMBLE_DEC
#undef FIN_PREAMBLE_CODE
#define FIN_PREAMBLE_DEC	msProcedure_state *op_sv_ptr;
#define FIN_PREAMBLE_CODE	\
		op_sv_ptr = ((msProcedure_state *)(OP_SIM_CONTEXT_PTR->_op_mod_state_ptr));


/* No Function Block */

#if !defined (VOSD_NO_FIN)
enum { _op_block_origin = __LINE__ };
#endif

/* Undefine optional tracing in FIN/FOUT/FRET */
/* The FSM has its own tracing code and the other */
/* functions should not have any tracing.		  */
#undef FIN_TRACING
#define FIN_TRACING

#undef FOUTRET_TRACING
#define FOUTRET_TRACING

/* Undefine shortcuts to state variables because the */
/* following functions are part of the state class */
#undef imsi_distribution
#undef detachProcessTime_gsh
#undef debugStr
#undef attachProcessTime_gsh
#undef activationProcessTime_gsh
#undef deactivationProcessTime_gsh
#undef msStatus
#undef tlliInAttachReject_gsh
#undef tlliInActivateReject_gsh
#undef rejectCauseInActivation_gsh

/* Access from C kernel using C linkage */
extern "C"
{
	VosT_Obtype _op_msProcedure_init (int * init_block_ptr);
	VosT_Address _op_msProcedure_alloc (VosT_Obtype, int);
	void msProcedure (OP_SIM_CONTEXT_ARG_OPT)
		{
		((msProcedure_state *)(OP_SIM_CONTEXT_PTR->_op_mod_state_ptr))->msProcedure (OP_SIM_CONTEXT_PTR_OPT);
		}

	void _op_msProcedure_svar (void *, const char *, void **);

	void _op_msProcedure_diag (OP_SIM_CONTEXT_ARG_OPT)
		{
		((msProcedure_state *)(OP_SIM_CONTEXT_PTR->_op_mod_state_ptr))->_op_msProcedure_diag (OP_SIM_CONTEXT_PTR_OPT);
		}

	void _op_msProcedure_terminate (OP_SIM_CONTEXT_ARG_OPT)
		{
		/* The destructor is the Termination Block */
		delete (msProcedure_state *)(OP_SIM_CONTEXT_PTR->_op_mod_state_ptr);
		}


} /* end of 'extern "C"' */




/* Process model interrupt handling procedure */


void
msProcedure_state::msProcedure (OP_SIM_CONTEXT_ARG_OPT)
	{
#if !defined (VOSD_NO_FIN)
	int _op_block_origin = 0;
#endif
	FIN_MT (msProcedure_state::msProcedure ());
	try
		{
		/* Temporary Variables */
		Packet *pkptr;
		
		double detachProcessTime;
		double attachProcessTime;
		double activationProcessTime;
		double deactivationProcessTime;
		double sentTime;
		/* End of Temporary Variables */


		FSM_ENTER ("msProcedure")

		FSM_BLOCK_SWITCH
			{
			/*---------------------------------------------------------*/
			/** state (init) enter executives **/
			FSM_STATE_ENTER_FORCED_NOLABEL (0, "init", "msProcedure [init enter execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [init enter execs]", state0_enter_exec)
				{
				// initialize the msStatus state variable
				int i;
				
				// currently supports only MAX_SUPPRORTED_MS subscribers
				imsi_distribution = op_dist_load ("uniform_int", 0, MAX_SUPPORTED_MS-1);
				attachProcessTime_gsh = op_stat_reg ("Attach Process Time",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				deactivationProcessTime_gsh = op_stat_reg ("Deactivation Process Time",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				activationProcessTime_gsh = op_stat_reg ("Activation Process Time",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				detachProcessTime_gsh = op_stat_reg ("Detach Process Time",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				tlliInAttachReject_gsh = op_stat_reg ("TLLI in Attach Reject",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				tlliInActivateReject_gsh = op_stat_reg ("TLLI in Activate Reject",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				rejectCauseInActivation_gsh = op_stat_reg ("Reject Cause in Activate Reject",
					OPC_STAT_INDEX_NONE, OPC_STAT_GLOBAL);
				
				for (i=0; i < MAX_SUPPORTED_MS; i++)
					{
					    msStatus[i].status = MSStatus_Detached;
					}
				}
				FSM_PROFILE_SECTION_OUT (state0_enter_exec)

			/** state (init) exit executives **/
			FSM_STATE_EXIT_FORCED (0, "init", "msProcedure [init exit execs]")


			/** state (init) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "init", "idle", "tr_0", "msProcedure [init -> idle : default / ]")
				/*---------------------------------------------------------*/



			/** state (idle) enter executives **/
			FSM_STATE_ENTER_UNFORCED (1, "idle", state1_enter_exec, "msProcedure [idle enter execs]")

			/** blocking after enter executives of unforced state. **/
			FSM_EXIT (3,"msProcedure")


			/** state (idle) exit executives **/
			FSM_STATE_EXIT_UNFORCED (1, "idle", "msProcedure [idle exit execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [idle exit execs]", state1_exit_exec)
				{
				int intrpt_type;
				int i;
				
				/* Determine the interrupt type as the model perform .	*/
				intrpt_type = op_intrpt_type ();
				if (intrpt_type == OPC_INTRPT_ENDSIM)
					{	
					printf("State information of MS after simulation, 0 = Detached, 1 = Attached, 2 = Activated\n");
					for (i=0; i <= 12; i++)
						{
						printf("IMSI:   %d\tMM State: %d\n", i, msStatus[i].status);
						}
					}
				}
				FSM_PROFILE_SECTION_OUT (state1_exit_exec)


			/** state (idle) transition processing **/
			FSM_PROFILE_SECTION_IN ("msProcedure [idle trans conditions]", state1_trans_conds)
			FSM_INIT_COND (ATTACH_SRC_ARRIVAL)
			FSM_TEST_COND (GMM_RCV_ARRIVAL)
			FSM_TEST_COND (ACTIVATION_SRC_ARRIVAL)
			FSM_TEST_COND (SM_RCV_ARRIVAL)
			FSM_TEST_COND (DEACTIVATION_SRC_ARRIVAL)
			FSM_TEST_COND (DETACH_SRC_ARRIVAL)
			FSM_TEST_COND (USER_DATA_SRC_ARRIVAL)
			FSM_DFLT_COND
			FSM_TEST_LOGIC ("idle")
			FSM_PROFILE_SECTION_OUT (state1_trans_conds)

			FSM_TRANSIT_SWITCH
				{
				FSM_CASE_TRANSIT (0, 2, state2_enter_exec, ;, "ATTACH_SRC_ARRIVAL", "", "idle", "attachXmt", "tr_1", "msProcedure [idle -> attachXmt : ATTACH_SRC_ARRIVAL / ]")
				FSM_CASE_TRANSIT (1, 3, state3_enter_exec, ;, "GMM_RCV_ARRIVAL", "", "idle", "gmmMsgRcv", "tr_3", "msProcedure [idle -> gmmMsgRcv : GMM_RCV_ARRIVAL / ]")
				FSM_CASE_TRANSIT (2, 4, state4_enter_exec, ;, "ACTIVATION_SRC_ARRIVAL", "", "idle", "activationXmt", "tr_7", "msProcedure [idle -> activationXmt : ACTIVATION_SRC_ARRIVAL / ]")
				FSM_CASE_TRANSIT (3, 5, state5_enter_exec, ;, "SM_RCV_ARRIVAL", "", "idle", "smMsgRcv", "smMsgRcv", "msProcedure [idle -> smMsgRcv : SM_RCV_ARRIVAL / ]")
				FSM_CASE_TRANSIT (4, 6, state6_enter_exec, ;, "DEACTIVATION_SRC_ARRIVAL", "", "idle", "deactivationXmt", "tr_11", "msProcedure [idle -> deactivationXmt : DEACTIVATION_SRC_ARRIVAL / ]")
				FSM_CASE_TRANSIT (5, 7, state7_enter_exec, ;, "DETACH_SRC_ARRIVAL", "", "idle", "detachXmt", "tr_14", "msProcedure [idle -> detachXmt : DETACH_SRC_ARRIVAL / ]")
				FSM_CASE_TRANSIT (6, 8, state8_enter_exec, ;, "USER_DATA_SRC_ARRIVAL", "", "idle", "userDataXmt", "tr_47", "msProcedure [idle -> userDataXmt : USER_DATA_SRC_ARRIVAL / ]")
				FSM_CASE_TRANSIT (7, 1, state1_enter_exec, ;, "default", "", "idle", "idle", "tr_6", "msProcedure [idle -> idle : default / ]")
				}
				/*---------------------------------------------------------*/



			/** state (attachXmt) enter executives **/
			FSM_STATE_ENTER_FORCED (2, "attachXmt", state2_enter_exec, "msProcedure [attachXmt enter execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [attachXmt enter execs]", state2_enter_exec)
				{
				int imsi;
				pkptr = op_pk_get (ATTACH_SRC_IN_STRM);
				
				// set the imsi of the MS
				imsi = (int)op_dist_outcome(imsi_distribution);
				op_pk_nfd_set (pkptr, "imsi",
					imsi);
				
				// send the attach only if MS status is detached
				if (msStatus[imsi].status == MSStatus_Detached)
					{	  
				    op_pk_send(pkptr, GMM_XMT_OUT_STRM);
					sentTime = op_sim_time ();
					// set the attach request sent time
				    msStatus[imsi].attachReqSentTime = sentTime;
					}
				else
					{
					op_pk_destroy(pkptr);
					}
				}
				FSM_PROFILE_SECTION_OUT (state2_enter_exec)

			/** state (attachXmt) exit executives **/
			FSM_STATE_EXIT_FORCED (2, "attachXmt", "msProcedure [attachXmt exit execs]")


			/** state (attachXmt) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "attachXmt", "idle", "tr_2", "msProcedure [attachXmt -> idle : default / ]")
				/*---------------------------------------------------------*/



			/** state (gmmMsgRcv) enter executives **/
			FSM_STATE_ENTER_FORCED (3, "gmmMsgRcv", state3_enter_exec, "msProcedure [gmmMsgRcv enter execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [gmmMsgRcv enter execs]", state3_enter_exec)
				{
				double detachReqSentTime;
				double attachReqSentTime;
				Packet * attachCompletePkPtr;
				int messageType;
				int tlli;
				
				pkptr = op_pk_get(GMM_RCV_IN_STRM);
				// retrieve the message type of message sent by SGSN
				op_pk_nfd_get (pkptr, "messageType", &messageType);
				
				switch (messageType) {
				    case ATTACH_ACCEPT:
				                
					    // retrieve the allocatedPTMSI from attach accept
					    op_pk_nfd_get(pkptr, "allocatedPTMSI", &tlli);
				        // reply SGSN with AttachComplete
					    attachCompletePkPtr = op_pk_create_fmt ("attachComplete");
					    op_pk_nfd_set(attachCompletePkPtr, "TLLI", tlli);
					    op_pk_send(attachCompletePkPtr, GMM_XMT_OUT_STRM);
					
					     // change the msStatus to MS_ATTACHED
					     msStatus[tlli].status = MSStatus_Attached;
					     
					     // record attachProcessTime
					     attachProcessTime = op_sim_time() - msStatus[tlli].attachReqSentTime;
				         op_stat_write(attachProcessTime_gsh, attachProcessTime);
					
					    break;
				    case DETACH_ACCEPT:	    
				
					    // retrieve the tlli from detach accept
					    op_pk_nfd_get(pkptr, "TLLI", &tlli); 
				        //sprintf (debugStr, "Detach Accept Recv. Detach Req sent time %f", detachReqSentTime);
				        //op_prg_odb_print_major ("Debug message for MS-SGSN", debugStr, OPC_NIL);
				
				        //sprintf (debugStr, "Detach Accept Recv. Detach Accept Recv time %f", op_sim_time());
				        //op_prg_odb_print_major ("Debug message for MS-SGSN", debugStr, OPC_NIL);
					
					    // change the msStatus to MS_DETACHED
					    msStatus[tlli].status = MSStatus_Detached;
								 
						// record detachProcessTime
				        detachProcessTime = op_sim_time() - msStatus[tlli].detachReqSentTime;
				        op_stat_write(detachProcessTime_gsh, detachProcessTime);
				        break;
				    case ATTACH_REJECT:	    
				
					    // retrieve the tlli from attach reject
					    op_pk_nfd_get(pkptr, "TLLI", &tlli); 
				        
				        op_stat_write(tlliInAttachReject_gsh, tlli);
				        break;
					default:
					    break;
					}
				op_pk_destroy(pkptr);
				}
				FSM_PROFILE_SECTION_OUT (state3_enter_exec)

			/** state (gmmMsgRcv) exit executives **/
			FSM_STATE_EXIT_FORCED (3, "gmmMsgRcv", "msProcedure [gmmMsgRcv exit execs]")


			/** state (gmmMsgRcv) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "gmmMsgRcv", "idle", "tr_4", "msProcedure [gmmMsgRcv -> idle : default / ]")
				/*---------------------------------------------------------*/



			/** state (activationXmt) enter executives **/
			FSM_STATE_ENTER_FORCED (4, "activationXmt", state4_enter_exec, "msProcedure [activationXmt enter execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [activationXmt enter execs]", state4_enter_exec)
				{
				int tlli;
				
				pkptr = op_pk_get (ACTIVATION_SRC_IN_STRM);
				
				//sprintf (debugStr, "Activation Req sent.  Activation Req sent time %f", sentTime);
				//op_prg_odb_print_major ("Debug message for MS-SGSN", debugStr, OPC_NIL);
				
				// set the tlli of the MS
				tlli = (int)op_dist_outcome(imsi_distribution);
				op_pk_nfd_set (pkptr, "TLLI",
					tlli);
				
				// send Activate PDP Request only if the MS is attached 
				if (msStatus[tlli].status == MSStatus_Attached)
					{
				    op_pk_send(pkptr, SM_XMT_OUT_STRM);
					sentTime = op_sim_time ();
					// set the activation request sent time
				    msStatus[tlli].activationReqSentTime = sentTime;
					}
				else
					{
					op_pk_destroy(pkptr);
					}
				}
				FSM_PROFILE_SECTION_OUT (state4_enter_exec)

			/** state (activationXmt) exit executives **/
			FSM_STATE_EXIT_FORCED (4, "activationXmt", "msProcedure [activationXmt exit execs]")


			/** state (activationXmt) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "activationXmt", "idle", "tr_5", "msProcedure [activationXmt -> idle : default / ]")
				/*---------------------------------------------------------*/



			/** state (smMsgRcv) enter executives **/
			FSM_STATE_ENTER_FORCED (5, "smMsgRcv", state5_enter_exec, "msProcedure [smMsgRcv enter execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [smMsgRcv enter execs]", state5_enter_exec)
				{
				double activationReqSentTime;
				double deactivationReqSentTime;
				int messageType;
				int tlli, smCause;
				
				pkptr = op_pk_get(SM_RCV_IN_STRM);
				// retrieve the message type of message sent by SGSN
				op_pk_nfd_get (pkptr, "messageType", &messageType);
				
				// retrieve the tlli from detach accept
				op_pk_nfd_get(pkptr, "TLLI", &tlli); 
				
				switch (messageType) {
				    case ACTIVATION_ACCEPT:
				       
				        sprintf (debugStr, "Activation Accept Recv. Activation Req sent time %f", activationReqSentTime);
				        //op_prg_odb_print_major ("Debug message for MS-SGSN", debugStr, OPC_NIL);
				
				        sprintf (debugStr, "Activation Accept Recv. Activation Accept Recv time %f", op_sim_time());
				        //op_prg_odb_print_major ("Debug message for MS-SGSN", debugStr, OPC_NIL);
					
					    // change the msStatus to MS_ACTIVATED
					    msStatus[tlli].status = MSStatus_Activated;
					
					    // record activationProcessTime
				        activationProcessTime = op_sim_time() - msStatus[tlli].activationReqSentTime;
				        op_stat_write(activationProcessTime_gsh, activationProcessTime); 
				        break;
					case DEACTIVATION_ACCEPT:
				       
					    // change the msStatus to MS_ATTACHED
					    msStatus[tlli].status = MSStatus_Attached;
												  
				        // record deactivationProcessTime
						deactivationProcessTime = op_sim_time() - msStatus[tlli].deactivationReqSentTime;
				        op_stat_write(deactivationProcessTime_gsh, deactivationProcessTime);	
					
					    break;
					case ACTIVATION_REJECT:  
					    
						op_pk_nfd_get(pkptr, "smCause", 
				                &smCause);						  
					    op_stat_write(rejectCauseInActivation_gsh, smCause);
				        // record the imis in Activation Reject
				        if (smCause == 30)
							{	
							op_stat_write(tlliInActivateReject_gsh, tlli);	
							}
					
					    break;
					default:
					    break;
					}
				op_pk_destroy(pkptr);
				}
				FSM_PROFILE_SECTION_OUT (state5_enter_exec)

			/** state (smMsgRcv) exit executives **/
			FSM_STATE_EXIT_FORCED (5, "smMsgRcv", "msProcedure [smMsgRcv exit execs]")


			/** state (smMsgRcv) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "smMsgRcv", "idle", "tr_8", "msProcedure [smMsgRcv -> idle : default / ]")
				/*---------------------------------------------------------*/



			/** state (deactivationXmt) enter executives **/
			FSM_STATE_ENTER_FORCED (6, "deactivationXmt", state6_enter_exec, "msProcedure [deactivationXmt enter execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [deactivationXmt enter execs]", state6_enter_exec)
				{
				int tlli;
				
				pkptr = op_pk_get (DEACTIVATION_SRC_IN_STRM);
				
				// set the tlli of the MS
				tlli = (int)op_dist_outcome(imsi_distribution);
				op_pk_nfd_set (pkptr, "TLLI",
					tlli);
				
				// send Deactivate PDP Request only if the MS is activated 
				if (msStatus[tlli].status == MSStatus_Activated)
					{
				    op_pk_send(pkptr, SM_XMT_OUT_STRM);
					sentTime = op_sim_time ();
					// set the deactivation request sent time
				    msStatus[tlli].deactivationReqSentTime = sentTime;
					}
				else
					{
					op_pk_destroy(pkptr);
					}
				}
				FSM_PROFILE_SECTION_OUT (state6_enter_exec)

			/** state (deactivationXmt) exit executives **/
			FSM_STATE_EXIT_FORCED (6, "deactivationXmt", "msProcedure [deactivationXmt exit execs]")


			/** state (deactivationXmt) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "deactivationXmt", "idle", "tr_10", "msProcedure [deactivationXmt -> idle : default / ]")
				/*---------------------------------------------------------*/



			/** state (detachXmt) enter executives **/
			FSM_STATE_ENTER_FORCED (7, "detachXmt", state7_enter_exec, "msProcedure [detachXmt enter execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [detachXmt enter execs]", state7_enter_exec)
				{
				int tlli;
				
				pkptr = op_pk_get(DETACH_SRC_IN_STRM);
				//sprintf (debugStr, "Detach Req sent.  Detach Req sent time %f", sentTime);
				//op_prg_odb_print_major ("Debug message for MS-SGSN", debugStr, OPC_NIL);
				
				// set the tlli of the MS
				tlli = (int)op_dist_outcome(imsi_distribution);
				op_pk_nfd_set (pkptr, "TLLI",
					tlli);
				
				// send Detach Request only if the MS is attached or 
				// activated
				if ( (msStatus[tlli].status == MSStatus_Attached) ||
				    (msStatus[tlli].status == MSStatus_Activated) )
					{
				    op_pk_send(pkptr, GMM_XMT_OUT_STRM);
					sentTime = op_sim_time ();
					// set the detach request sent time
				    msStatus[tlli].detachReqSentTime = sentTime;
					}
				else
					{
					op_pk_destroy(pkptr);
					}
				}
				FSM_PROFILE_SECTION_OUT (state7_enter_exec)

			/** state (detachXmt) exit executives **/
			FSM_STATE_EXIT_FORCED (7, "detachXmt", "msProcedure [detachXmt exit execs]")


			/** state (detachXmt) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "detachXmt", "idle", "tr_26", "msProcedure [detachXmt -> idle : default / ]")
				/*---------------------------------------------------------*/



			/** state (userDataXmt) enter executives **/
			FSM_STATE_ENTER_FORCED (8, "userDataXmt", state8_enter_exec, "msProcedure [userDataXmt enter execs]")
				FSM_PROFILE_SECTION_IN ("msProcedure [userDataXmt enter execs]", state8_enter_exec)
				{
				int tlli,nsapi;
				Packet * ipDataPkPtr;
				Packet * sndcpPkPtr;
				// retrieve pointer to ipv4 datagram packet
				pkptr = op_pk_get (USER_DATA_SRC_IN_STRM);
				// set the ipData, 30K
				ipDataPkPtr = op_pk_create(30720);
				op_pk_nfd_set (pkptr, "data", ipDataPkPtr);
				
				tlli = (int)op_dist_outcome(imsi_distribution);
				// transmit data only if MS status is activated
				if (msStatus[tlli].status == MSStatus_Activated)
					{	  
				    // create sndcp packet
					sndcpPkPtr = op_pk_create_fmt ("sndcpPacket");
					// set the tlli and nsapi of the packet
				    nsapi = 5;
				    op_pk_nfd_set (sndcpPkPtr, "TLLI",
					    tlli);
				    op_pk_nfd_set (sndcpPkPtr, "nsapi",
					    nsapi);
					// set the encapsulated IP packet
					op_pk_nfd_set (sndcpPkPtr, "data", pkptr);
					
				    op_pk_send(sndcpPkPtr, USER_DATA_XMT_OUT_STRM);
					}
				else
					{
				    op_pk_destroy(pkptr);
					}
				}
				FSM_PROFILE_SECTION_OUT (state8_enter_exec)

			/** state (userDataXmt) exit executives **/
			FSM_STATE_EXIT_FORCED (8, "userDataXmt", "msProcedure [userDataXmt exit execs]")


			/** state (userDataXmt) transition processing **/
			FSM_TRANSIT_FORCE (1, state1_enter_exec, ;, "default", "", "userDataXmt", "idle", "tr_48", "msProcedure [userDataXmt -> idle : default / ]")
				/*---------------------------------------------------------*/



			}


		FSM_EXIT (0,"msProcedure")
		}
	catch (...)
		{
		Vos_Error_Print (VOSC_ERROR_ABORT,
			(const char *)VOSC_NIL,
			"Unhandled C++ exception in process model (msProcedure)",
			(const char *)VOSC_NIL, (const char *)VOSC_NIL);
		}
	}




void
msProcedure_state::_op_msProcedure_diag (OP_SIM_CONTEXT_ARG_OPT)
	{
	/* No Diagnostic Block */
	}

void
msProcedure_state::operator delete (void* ptr)
	{
	FIN (msProcedure_state::operator delete (ptr));
	Vos_Poolmem_Dealloc (ptr);
	FOUT
	}

msProcedure_state::~msProcedure_state (void)
	{

	FIN (msProcedure_state::~msProcedure_state ())


	/* No Termination Block */


	FOUT
	}


#undef FIN_PREAMBLE_DEC
#undef FIN_PREAMBLE_CODE

#define FIN_PREAMBLE_DEC
#define FIN_PREAMBLE_CODE

void *
msProcedure_state::operator new (size_t)
#if defined (VOSD_NEW_BAD_ALLOC)
		throw (VOSD_BAD_ALLOC)
#endif
	{
	void * new_ptr;

	FIN_MT (msProcedure_state::operator new ());

	new_ptr = Vos_Alloc_Object (msProcedure_state::obtype);
#if defined (VOSD_NEW_BAD_ALLOC)
	if (new_ptr == VOSC_NIL) throw VOSD_BAD_ALLOC();
#endif
	FRET (new_ptr)
	}

/* State constructor initializes FSM handling */
/* by setting the initial state to the first */
/* block of code to enter. */

msProcedure_state::msProcedure_state (void) :
		_op_current_block (0)
	{
#if defined (OPD_ALLOW_ODB)
		_op_current_state = "msProcedure [init enter execs]";
#endif
	}

VosT_Obtype
_op_msProcedure_init (int * init_block_ptr)
	{
	FIN_MT (_op_msProcedure_init (init_block_ptr))

	msProcedure_state::obtype = Vos_Define_Object_Prstate ("proc state vars (msProcedure)",
		sizeof (msProcedure_state));
	*init_block_ptr = 0;

	FRET (msProcedure_state::obtype)
	}

VosT_Address
_op_msProcedure_alloc (VosT_Obtype, int)
	{
#if !defined (VOSD_NO_FIN)
	int _op_block_origin = 0;
#endif
	msProcedure_state * ptr;
	FIN_MT (_op_msProcedure_alloc ())

	/* New instance will have FSM handling initialized */
#if defined (VOSD_NEW_BAD_ALLOC)
	try {
		ptr = new msProcedure_state;
	} catch (const VOSD_BAD_ALLOC &) {
		ptr = VOSC_NIL;
	}
#else
	ptr = new msProcedure_state;
#endif
	FRET ((VosT_Address)ptr)
	}



void
_op_msProcedure_svar (void * gen_ptr, const char * var_name, void ** var_p_ptr)
	{
	msProcedure_state		*prs_ptr;

	FIN_MT (_op_msProcedure_svar (gen_ptr, var_name, var_p_ptr))

	if (var_name == OPC_NIL)
		{
		*var_p_ptr = (void *)OPC_NIL;
		FOUT
		}
	prs_ptr = (msProcedure_state *)gen_ptr;

	if (strcmp ("imsi_distribution" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->imsi_distribution);
		FOUT
		}
	if (strcmp ("detachProcessTime_gsh" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->detachProcessTime_gsh);
		FOUT
		}
	if (strcmp ("debugStr" , var_name) == 0)
		{
		*var_p_ptr = (void *) (prs_ptr->debugStr);
		FOUT
		}
	if (strcmp ("attachProcessTime_gsh" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->attachProcessTime_gsh);
		FOUT
		}
	if (strcmp ("activationProcessTime_gsh" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->activationProcessTime_gsh);
		FOUT
		}
	if (strcmp ("deactivationProcessTime_gsh" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->deactivationProcessTime_gsh);
		FOUT
		}
	if (strcmp ("msStatus" , var_name) == 0)
		{
		*var_p_ptr = (void *) (prs_ptr->msStatus);
		FOUT
		}
	if (strcmp ("tlliInAttachReject_gsh" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->tlliInAttachReject_gsh);
		FOUT
		}
	if (strcmp ("tlliInActivateReject_gsh" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->tlliInActivateReject_gsh);
		FOUT
		}
	if (strcmp ("rejectCauseInActivation_gsh" , var_name) == 0)
		{
		*var_p_ptr = (void *) (&prs_ptr->rejectCauseInActivation_gsh);
		FOUT
		}
	*var_p_ptr = (void *)OPC_NIL;

	FOUT
	}

