module BSSGP_Emulation {

import from General_Types all;
import from Osmocom_Types all;
import from NS_Types all;
import from NS_Emulation all;
import from BSSGP_Types all;
import from Osmocom_Gb_Types all;
import from IPL4asp_Types all;

import from MobileL3_GMM_SM_Types all;
import from MobileL3_Types all;

import from LLC_Types all;
import from LLC_Templates all;

import from SNDCP_Types all;

/***********************************************************************
 * Communication between Client Components and Main Component
 ***********************************************************************/

type record BssgpStatusIndication {
	Nsei		nsei,
	BssgpBvci	bvci,
	BvcState	state
}

template BssgpStatusIndication t_BssgpStsInd(template Nsei nsei, template BssgpBvci bvci, template BvcState state) := {
	nsei := nsei,
	bvci := bvci,
	state := state
}

type enumerated BvcState {
	BVC_S_BLOCKED,
	BVC_S_UNBLOCKED
};

/* port from our (internal) point of view */
type port BSSGP_SP_PT message {
	in	PDU_BSSGP,
		PDU_L3_MS_SGSN,
		PDU_L3_SGSN_MS;
	out	BssgpDecoded,
		NsStatusIndication,
		BssgpStatusIndication,
		ASP_Event,
		PDU_L3_MS_SGSN,
		PDU_L3_SGSN_MS;
} with { extension "internal" };

/* port from the user point of view */
type port BSSGP_PT message {
	in	ASP_Event,
		NsStatusIndication,
		BssgpStatusIndication,
		BssgpDecoded,
		PDU_L3_MS_SGSN,
		PDU_L3_SGSN_MS;
	out	PDU_BSSGP,
		PDU_L3_SGSN_MS,
		PDU_L3_MS_SGSN;
} with { extension "internal" };

signature BSSGP_register_client(hexstring imsi, OCT4 tlli, BssgpCellId cell_id);
signature BSSGP_unregister_client(hexstring imsi);
signature BSSGP_llgmm_assign(OCT4 tlli_old, OCT4 tlli);

type port BSSGP_PROC_PT procedure {
	inout BSSGP_register_client, BSSGP_unregister_client, BSSGP_llgmm_assign;
} with { extension "internal" };


/***********************************************************************
 * Client Component for a single MS/TLLI
 ***********************************************************************/

type component BSSGP_Client_CT {
	port BSSGP_PT BSSGP;
	port BSSGP_PROC_PT BSSGP_PROC;
};

/***********************************************************************
 * Main Component
 ***********************************************************************/

function BssgpStart(BssgpConfig cfg) runs on BSSGP_CT {
	g_cfg := cfg;
	f_init();
	f_ScanEvents();
}

private function f_init() runs on BSSGP_CT {
	/* Connect the UDP socket */
	f_change_state(BVC_S_BLOCKED);
}

type component BSSGP_CT {
	/* UDP port towards the bottom (IUT) */
	port NS_PT BSCP;
	/* NS-User SAP towards the user */
	port BSSGP_SP_PT BSSGP_SP;
	port BSSGP_PROC_PT BSSGP_PROC;

	var BssgpConfig g_cfg;

	var BvcState g_ptp_bvc_state := BVC_S_BLOCKED;
	timer g_T1 := 15.0;
	timer g_T2 := 60.0;

	var ClientEntity ClientTable[16];
}

type record ClientEntity {
	OCT4 tlli,
	OCT4 tlli_old optional,
	hexstring imsi,
	BssgpCellId cell_id,
	BSSGP_Client_CT comp_ref,
	/* LLC entities, one for each SAPI */
	LLC_Entity llc[16]
};

type record LLC_Entity {
	boolean sgsn_role,
	/* N(U) on transmit side for next PDU */
	uint9_t n_u_tx_next,
	/* N(U) on receive side, last PDU */
	uint9_t n_u_rx_last optional
};

private template LLC_Entity t_LLC_init(boolean sgsn_role := false) := {
	sgsn_role := sgsn_role,
	n_u_tx_next := 0,
	n_u_rx_last := -
}

type record BssgpConfig {
	Nsvci nsei,
	Nsvci bvci,
	BssgpCellId cell_id,
	boolean sgsn_role
};

function f_BnsUdReq(template PDU_BSSGP pdu, BssgpBvci bvci)
runs on BSSGP_CT return NsUnitdataRequest {
	var NsUnitdataRequest udr := {
		bvci := bvci,
		nsei := g_cfg.nsei,
		/* for some weird reason we get "Dynamic test case error: Text encoder: Encoding an
		 * unbound integer value." when trying to send the reocrd rather than the octetstring */
		//sdu := omit,
		//bssgp := valueof(pdu)
		sdu := enc_PDU_BSSGP(valueof(pdu)),
		bssgp := omit
	}
	return udr;
}

function f_BnsUdInd(template PDU_BSSGP pdu, template BssgpBvci bvci)
runs on BSSGP_CT return template NsUnitdataIndication {
	var template NsUnitdataIndication udi := {
		bvci := bvci,
		nsei := g_cfg.nsei,
		sdu := *,
		bssgp := pdu
	}
	return udi;
}

private function f_change_state(BvcState new_state) runs on BSSGP_CT {
	log("BSSGP State Transition: ", g_ptp_bvc_state, " -> ", new_state);
	g_ptp_bvc_state := new_state;
	for (var integer i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isbound(ClientTable[i].comp_ref)) {
			BSSGP_SP.send(t_BssgpStsInd(g_cfg.nsei, g_cfg.bvci, g_ptp_bvc_state)) to ClientTable[i].comp_ref;
		}
	}
}

private function f_sendReset() runs on BSSGP_CT {
	var PDU_BSSGP pdu := valueof(ts_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, g_cfg.bvci, g_cfg.cell_id));
	log("PDU: ", pdu);
	log("ENC: ", enc_PDU_BSSGP(pdu));

	/* BVC-RESET is always sent via the SIGNALLING BVCI, see Table 5.4.1 */
	BSCP.send(f_BnsUdReq(pdu, 0));
	g_T2.start;
	//f_change_state(BVC_S_WAIT_RESET);
}

private function f_sendUnblock() runs on BSSGP_CT {
	BSCP.send(f_BnsUdReq(t_BVC_UNBLOCK(g_cfg.bvci), 0));
	g_T1.start;
}

private function f_sendBlock(BssgpCause cause) runs on BSSGP_CT {
	BSCP.send(f_BnsUdReq(t_BVC_BLOCK(g_cfg.bvci, cause), 0));
	g_T1.start;
}

private function f_sendStatus(BssgpCause cause, PDU_BSSGP pdu) runs on BSSGP_CT {
	/* FIXME: Make sure correct Signaling or PTP BVCI is used! */
	BSCP.send(f_BnsUdReq(ts_BSSGP_STATUS(g_cfg.bvci, cause, pdu), g_cfg.bvci));
}

/* attempt to extract the TLLI from a BSSGP PDU */
function f_bssgp_get_tlli(PDU_BSSGP bssgp) return template OCT4 {
	if (ischosen(bssgp.pDU_BSSGP_DL_UNITDATA)) {
		return bssgp.pDU_BSSGP_DL_UNITDATA.tLLI_current;
	} else if (ischosen(bssgp.pDU_BSSGP_UL_UNITDATA)) {
		return bssgp.pDU_BSSGP_UL_UNITDATA.tLLI;
	} else if (ischosen(bssgp.pDU_BSSGP_RA_CAPABILITY)) {
		return bssgp.pDU_BSSGP_RA_CAPABILITY.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RA_CAPABILITY_UPDATE)) {
		return bssgp.pDU_BSSGP_RA_CAPABILITY_UPDATE.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RA_CAPABILITY_UPDATE_ACK)) {
		return bssgp.pDU_BSSGP_RA_CAPABILITY_UPDATE_ACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RADIO_STATUS)) {
		return bssgp.pDU_BSSGP_RADIO_STATUS.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_SUSPEND)) {
		return bssgp.pDU_BSSGP_SUSPEND.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_SUSPEND_ACK)) {
		return bssgp.pDU_BSSGP_SUSPEND_ACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_SUSPEND_NACK)) {
		return bssgp.pDU_BSSGP_SUSPEND_NACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RESUME)) {
		return bssgp.pDU_BSSGP_RESUME.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RESUME_ACK)) {
		return bssgp.pDU_BSSGP_RESUME_ACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_RESUME_NACK)) {
		return bssgp.pDU_BSSGP_RESUME_NACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_FLUSH_LL)) {
		return bssgp.pDU_BSSGP_FLUSH_LL.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_FLUSH_LL_ACK)) {
		return bssgp.pDU_BSSGP_FLUSH_LL_ACK.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_LLC_DISCARDED)) {
		return bssgp.pDU_BSSGP_LLC_DISCARDED.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_LLC_DISCARDED)) {
		return bssgp.pDU_BSSGP_LLC_DISCARDED.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_PAGING_CS) and
		   isvalue(bssgp.pDU_BSSGP_PAGING_CS.tLLI)) {
		return bssgp.pDU_BSSGP_PAGING_CS.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_FLOW_CONTROL_MS)) {
		return bssgp.pDU_BSSGP_FLOW_CONTROL_MS.tLLI.tLLI_Value;
	} else if (ischosen(bssgp.pDU_BSSGP_FLOW_CONTROL_MS_ACK)) {
		return bssgp.pDU_BSSGP_FLOW_CONTROL_MS_ACK.tLLI.tLLI_Value;
	}
	/* TODO: Handover, PFC, LCS */
	return omit;
}

/*
private function f_tbl_init() runs on BSSGP_CT {
	var integer i;
	for (i := 0; i < sizeof(ImsiTable); i := i+1) {
		ImsiTable[i] := -;
	}

	for (i := 0; i < sizeof(TlliTable); i := i+1) {
		TlliTable[i] := -;
	}
}
*/

private function f_tbl_client_add(hexstring imsi, OCT4 tlli, BssgpCellId cell_id, BSSGP_Client_CT vc_conn)
runs on BSSGP_CT {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (not isvalue(ClientTable[i].comp_ref)) {
			log("Adding Client=", vc_conn, ", IMSI=", imsi, ", TLLI=", tlli, ", index=", i);
			ClientTable[i] := {
				tlli := tlli,
				tlli_old := omit,
				imsi := imsi,
				cell_id := cell_id,
				comp_ref := vc_conn,
				llc := -
			};
			for (var integer j := 0; j < sizeof(ClientTable[i].llc); j := j+1) {
				ClientTable[i].llc[j] := valueof(t_LLC_init(g_cfg.sgsn_role));
			}
			return;
		}
	}
	setverdict(fail, "Client Table full");
	self.stop;
}

private function f_tbl_client_del(hexstring imsi, BSSGP_Client_CT vc_conn) runs on BSSGP_CT {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].imsi) and ClientTable[i].imsi == imsi) {
			if (ClientTable[i].comp_ref != vc_conn) {
				setverdict(fail, "Cannot unregister IMSI ", imsi, " registred to ",
					   ClientTable[i].comp_ref, " from ", vc_conn);
				self.stop;
			}
			log("Removing Client IMSI=", imsi, ", index=", i);
			ClientTable[i] := { -, omit, -, -, - };
			return;
		}
	}
	setverdict(fail, "Could not find client for IMSI ", imsi);
	self.stop;
}

/* TS 44.064 7.2.1.1 LLGMM-ASSIGN */
private function f_tbl_client_llgmm_assign(OCT4 tlli_old, OCT4 tlli_new, BSSGP_Client_CT vc_conn)
runs on BSSGP_CT {
	var integer i := f_tbl_idx_by_comp(vc_conn);

	if (tlli_old == 'FFFFFFFF'O and tlli_new != 'FFFFFFFF'O) {
		/* TLLI assignment */
		ClientTable[i].tlli := tlli_new;
		ClientTable[i].tlli_old := omit;
	} else if (tlli_old != 'FFFFFFFF'O and tlli_new != 'FFFFFFFF'O) {
		/* TLLI change: both active */
		ClientTable[i].tlli := tlli_new;
		ClientTable[i].tlli_old := tlli_old;
	} else if (tlli_old != 'FFFFFFFF'O and tlli_new == 'FFFFFFFF'O) {
		/* TLLI unassignment: old shall be unassigned; new stays */
		ClientTable[i].tlli_old := omit;
	}
}

private function f_tbl_comp_by_imsi(hexstring imsi) runs on BSSGP_CT return BSSGP_Client_CT {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].imsi) and isvalue(ClientTable[i].comp_ref)
		    and ClientTable[i].imsi == imsi) {
			return ClientTable[i].comp_ref;
		}
	}
	setverdict(fail, "Couldn't find Component for IMSI ", imsi);
	self.stop;
}

private function f_tbl_comp_by_tlli(OCT4 tlli) runs on BSSGP_CT return BSSGP_Client_CT {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].comp_ref) and
		    (isvalue(ClientTable[i].tlli) and (ClientTable[i].tlli == tlli or
		     isvalue(ClientTable[i].tlli_old) and ClientTable[i].tlli_old == tlli) )) {
			return ClientTable[i].comp_ref;
		}
	}
	setverdict(fail, "Couldn't find Component for TLLI ", tlli);
	self.stop;
}

private function f_tbl_idx_by_comp(BSSGP_Client_CT comp_ref) runs on BSSGP_CT return integer {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].comp_ref) and ClientTable[i].comp_ref == comp_ref) {
			return i;
		}
	}
	setverdict(fail, "Couldn't find Client for Component ", comp_ref);
	self.stop;
}

private function f_tbl_tlli_by_comp(BSSGP_Client_CT comp_ref) runs on BSSGP_CT return OCT4 {
	var integer i;
	for (i := 0; i < sizeof(ClientTable); i := i+1) {
		if (isvalue(ClientTable[i].tlli) and isvalue(ClientTable[i].comp_ref)
		    and ClientTable[i].comp_ref == comp_ref) {
			return ClientTable[i].tlli;
		}
	}
	setverdict(fail, "Couldn't find TLLI for Component ", comp_ref);
	self.stop;
}

altstep as_allstate() runs on BSSGP_CT {
	var BSSGP_Client_CT vc_conn;
	var NsUnitdataIndication udi;
	var NsStatusIndication nsi;
	var ASP_Event evt;
	var hexstring imsi;
	var OCT4 tlli, tlli_old;
	var BssgpCellId cell_id;

	/* Respond to BLOCK for wrong NSVCI */
	[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(?, ?), 0)) -> value udi {
		log("Rx BVC-BLOCK for unknown BVCI");
		f_sendStatus(BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp);
	}

	/* Respond to RESET with correct BVCI/CellID */
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, g_cfg.bvci, g_cfg.cell_id), 0)) -> value udi {
		log("Rx BVC-RESET for Our BVCI=", g_cfg.bvci);
		BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(g_cfg.bvci, g_cfg.cell_id), 0));
		f_change_state(BVC_S_UNBLOCKED);
	}

	/* Respond to RESET for signalling BVCI 0 */
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, 0, g_cfg.cell_id), 0)) -> value udi {
		log("Rx BVC-RESET for Signaling BVCI=0");
		BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(0, g_cfg.cell_id), 0));
	}

	/* Respond to RESET with wrong NSEI/NSVCI */
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, ?, ?), 0)) -> value udi {
		log("Rx BVC-RESET for unknown BVCI");
		f_sendStatus(BSSGP_CAUSE_BVCI_UNKNOWN, udi.bssgp);
	}

	/* default case of handling unknown PDUs */
	[] BSCP.receive(f_BnsUdInd(?, ?)) -> value udi {
		log("Rx Unexpected BSSGP PDU ", udi.bssgp," in state ", g_ptp_bvc_state);
		f_sendStatus(BSSGP_CAUSE_PDU_NOT_COMPATIBLE_WITH_PROTOCOL_STATE, udi.bssgp);
	}
	/* Forwarding of ASP_Event and NsStatusIndication to user */
	[] BSCP.receive(ASP_Event:?) -> value evt {
		for (var integer i := 0; i < sizeof(ClientTable); i := i+1) {
			if (isbound(ClientTable[i].comp_ref)) {
				BSSGP_SP.send(evt) to ClientTable[i].comp_ref;
			}
		}
		}
	[] BSCP.receive(NsStatusIndication:?) -> value nsi { 
		/* if we just became NS-unblocked, send a BCC-RESET */
		if (nsi.old_state != NSE_S_ALIVE_UNBLOCKED and nsi.new_state == NSE_S_ALIVE_UNBLOCKED) {
			if (g_cfg.sgsn_role == false) {
				f_sendReset();
			}
			/* Idea: We could send BVC-UNBLOCK here like some SGSN do */
		}
		for (var integer i := 0; i < sizeof(ClientTable); i := i+1) {
			if (isbound(ClientTable[i].comp_ref)) {
				BSSGP_SP.send(nsi) to ClientTable[i].comp_ref;
			}
		}
	}

	[] BSSGP_PROC.getcall(BSSGP_register_client:{?,?,?}) -> param(imsi, tlli, cell_id) sender vc_conn {
		f_tbl_client_add(imsi, tlli, cell_id, vc_conn);
		BSSGP_PROC.reply(BSSGP_register_client:{imsi, tlli, cell_id});
		}
	[] BSSGP_PROC.getcall(BSSGP_unregister_client:{?}) -> param(imsi) sender vc_conn {
		f_tbl_client_del(imsi, vc_conn);
		BSSGP_PROC.reply(BSSGP_unregister_client:{imsi});
		}
	[] BSSGP_PROC.getcall(BSSGP_llgmm_assign:{?,?}) -> param(tlli_old, tlli) sender vc_conn {
		f_tbl_client_llgmm_assign(tlli_old, tlli, vc_conn);
		BSSGP_PROC.reply(BSSGP_llgmm_assign:{tlli_old, tlli});
		}

}

altstep as_blocked() runs on BSSGP_CT {
	[] g_T1.timeout {
		f_sendUnblock();
	}
	[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK_ACK(g_cfg.bvci), 0)) {
		g_T1.stop;
		f_change_state(BVC_S_UNBLOCKED);
	}
	[not g_cfg.sgsn_role] BSCP.receive(f_BnsUdInd(tr_BVC_RESET_ACK(g_cfg.bvci, omit), 0)) {
		f_sendUnblock();
	}
}

altstep as_unblocked() runs on BSSGP_CT {
	var BSSGP_Client_CT vc_conn;
	var NsUnitdataIndication udi;
	var PDU_BSSGP bs_pdu;
	var PDU_L3_MS_SGSN l3_mo;
	var PDU_L3_SGSN_MS l3_mt;

	/* bogus unblock, just respond with ACK */
	[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK(g_cfg.bvci), 0)) -> value udi {
		BSCP.send(f_BnsUdReq(t_BVC_UNBLOCK_ACK(g_cfg.bvci), 0));
	}
	/* Respond to BLOCK with BLOCK-ACK + change state */
	[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(g_cfg.bvci, ?), 0)) -> value udi {
		BSCP.send(f_BnsUdReq(t_BVC_BLOCK_ACK(g_cfg.bvci), 0));
		g_T1.stop;
		f_change_state(BVC_S_BLOCKED);
	}
	[] g_T1.timeout {
		f_sendBlock(BSSGP_CAUSE_OM_INTERVENTION);
	}
	[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK_ACK(g_cfg.bvci), 0)) -> value udi {
		g_T1.stop;
		f_change_state(BVC_S_BLOCKED);
	}
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET_ACK(g_cfg.bvci, g_cfg.cell_id), 0)) -> value udi {
		g_T2.stop;
		f_change_state(BVC_S_UNBLOCKED);
	}

	/* simply acknowledge all Flow Control Messages */
/*
	[g_cfg.sgsn_role] BSCP.receive(f_BnsUdInd(t_BVC_FC_BVC), g_cfg.bvci) {
		BSCP.send(f_BnsUdReq(t_BVC_FC_BVC_ACK), g_cfg.bvci);
	}
	[g_cfg.sgsn_role] BSCP.receive(f_BnsUdInd(t_BVC_FC_MS), g_cfg.bvci) {
		BSCP.send(f_BnsUdReq(t_BVC_FC_MS_ACK), g_cfg.bvci);
	}
*/

	/* FIXME: CS PAGING: dispatch by IMSI */

	/* PS PAGING: dispatch by IMSI */
	[] BSCP.receive(f_BnsUdInd(tr_BSSGP_PS_PAGING(g_cfg.bvci), g_cfg.bvci)) -> value udi {
		var hexstring imsi := udi.bssgp.pDU_BSSGP_PAGING_PS.iMSI.digits
		vc_conn := f_tbl_comp_by_imsi(imsi);
		BSSGP_SP.send(f_dec_bssgp(udi.bssgp)) to vc_conn;
	}

	/* Any other BSSGP message: If it has TLLi, route to component; otherwise broadcast */
	[] BSCP.receive(f_BnsUdInd(?, g_cfg.bvci)) -> value udi {
		var BssgpDecoded dec := f_dec_bssgp(udi.bssgp);
		var template OCT4 tlli := f_bssgp_get_tlli(udi.bssgp);
		if (isvalue(tlli)) {
			vc_conn := f_tbl_comp_by_tlli(valueof(tlli));
			BSSGP_SP.send(dec) to vc_conn;
		} else {
			log("No TLLI: Broadcasting ", dec);
			/* broadcast this message to all components */
			// TITAN DOESN'T DO THIS, *SIGH*: "BSSGP_SP.send(dec) to all component;"
			for (var integer i := 0; i < sizeof(ClientTable); i := i+1) {
				if (isbound(ClientTable[i].comp_ref)) {
					BSSGP_SP.send(dec) to ClientTable[i].comp_ref;
				}
			}
		}
	}

	/* pass virtually any PDU from user to NS-UNITDATA PDU on network */
	[] BSSGP_SP.receive(PDU_BSSGP:?) -> value bs_pdu sender vc_conn {
		BSCP.send(f_BnsUdReq(bs_pdu, g_cfg.bvci));
	}

	[not g_cfg.sgsn_role] BSSGP_SP.receive(PDU_L3_MS_SGSN:?) -> value l3_mo sender vc_conn {
		var integer idx := f_tbl_idx_by_comp(vc_conn);
		var octetstring l3_enc := enc_PDU_L3_MS_SGSN(l3_mo);
		var BIT4 sapi := f_llc_sapi_by_l3_mo(l3_mo);
		var integer n_u := f_llc_get_n_u_tx(ClientTable[idx].llc[bit2int(sapi)]);
		var octetstring llc_enc := enc_PDU_LLC(valueof(ts_LLC_UI(l3_enc, sapi, '0'B, n_u)));
		BSCP.send(f_BnsUdReq(ts_BSSGP_UL_UD(ClientTable[idx].tlli, ClientTable[idx].cell_id, llc_enc), g_cfg.bvci));
	}

	[g_cfg.sgsn_role] BSSGP_SP.receive(PDU_L3_SGSN_MS:?) -> value l3_mt sender vc_conn {
		var integer idx := f_tbl_idx_by_comp(vc_conn);
		var octetstring l3_enc := enc_PDU_L3_SGSN_MS(l3_mt);
		var BIT4 sapi := f_llc_sapi_by_l3_mt(l3_mt);
		var integer n_u := f_llc_get_n_u_tx(ClientTable[idx].llc[bit2int(sapi)]);
		var octetstring llc_enc := enc_PDU_LLC(valueof(ts_LLC_UI(l3_enc, sapi, '1'B, n_u)));
		//BSCP.send(f_BnsUdReq(ts_BSSGP_DL_UD(ClientTable[idx].tlli, ClientTable[idx].cell_id, llc_enc)), g_cfg.bvci);
	}
}

private function f_llc_get_n_u_tx(inout LLC_Entity llc) return uint9_t {
	var uint9_t ret := llc.n_u_tx_next;
	llc.n_u_tx_next := llc.n_u_tx_next + 1;
	return ret;
}

private function f_llc_sapi_by_l3_mo(PDU_L3_MS_SGSN l3_mo) return BIT4 {
	if (ischosen(l3_mo.msgs.gprs_mm)) {
		return c_LLC_SAPI_LLGMM;
	} else if (ischosen(l3_mo.msgs.gprs_sm)) {
		return c_LLC_SAPI_LLGMM;
	} else if (ischosen(l3_mo.msgs.sms)) {
		return c_LLC_SAPI_LLSMS;
	}
	setverdict(fail, "No LLC SAPI for ", l3_mo);
	self.stop;
}

private function f_llc_sapi_by_l3_mt(PDU_L3_SGSN_MS l3_mt) return BIT4 {
	if (ischosen(l3_mt.msgs.gprs_mm)) {
		return c_LLC_SAPI_LLGMM;
	} else if (ischosen(l3_mt.msgs.gprs_sm)) {
		return c_LLC_SAPI_LLGMM;
	} else if (ischosen(l3_mt.msgs.sms)) {
		return c_LLC_SAPI_LLSMS;
	}
	setverdict(fail, "No LLC SAPI for ", l3_mt);
	self.stop;
}



private function f_ScanEvents() runs on BSSGP_CT {
	log("matching against ", tr_BVC_RESET(?, g_cfg.bvci, g_cfg.cell_id));

	while (true) {
		alt {
		[g_ptp_bvc_state == BVC_S_BLOCKED] as_blocked();
		[g_ptp_bvc_state == BVC_S_UNBLOCKED] as_unblocked();
		[] as_allstate();
		}
	} /* while */
}

/* PDU_BSSGP enhanced with LLC and possibly L3 decoded payloads */
type record BssgpDecoded {
	PDU_BSSGP bssgp,
	PDU_LLC llc optional,
	PDU_L3_MS_SGSN l3_mo optional,
	PDU_L3_SGSN_MS l3_mt optional,
	PDU_SN sndcp optional
}

/* Decode a PDU_BSSGP into a BssgpDecoded (i.e. with LLC/L3 decoded, as applicable) */
private function f_dec_bssgp(PDU_BSSGP bssgp) runs on BSSGP_CT return BssgpDecoded {
	var BssgpDecoded dec := {
		bssgp := bssgp,
		llc := omit,
		l3_mo := omit,
		l3_mt := omit,
		sndcp := omit
	};

	/* Decode LLC, if it is a PDU that contains LLC */
	if (ischosen(bssgp.pDU_BSSGP_DL_UNITDATA)) {
		dec.llc := dec_PDU_LLC(bssgp.pDU_BSSGP_DL_UNITDATA.lLC_PDU.lLC_PDU);
	} else if (ischosen(bssgp.pDU_BSSGP_UL_UNITDATA)) {
		dec.llc := dec_PDU_LLC(bssgp.pDU_BSSGP_UL_UNITDATA.lLC_PDU.lLC_PDU);
	}

	/* Decode L3, if it is a LLC PDU containing L3 */
	if (isvalue(dec.llc) and match(dec.llc, tr_LLC_UI_L3)) {
		if (g_cfg.sgsn_role) {
			dec.l3_mo := dec_PDU_L3_MS_SGSN(dec.llc.pDU_LLC_UI.information_field_UI);
		} else {
			dec.l3_mt := dec_PDU_L3_SGSN_MS(dec.llc.pDU_LLC_UI.information_field_UI);
		}
	}

	/* Decode SNDCP, if it is a LLC PDU containing user plane data */
	if (isvalue(dec.llc) and match(dec.llc, tr_LLC_UI_USER)) {
		dec.sndcp := dec_PDU_SN(dec.llc.pDU_LLC_UI.information_field_UI);
	}
	return dec;
}

function f_bssgp_client_register(hexstring imsi, OCT4 tlli, BssgpCellId cell_id, BSSGP_PROC_PT PT := BSSGP_PROC)
runs on BSSGP_Client_CT {
	PT.call(BSSGP_register_client:{imsi, tlli, cell_id}) {
		[] PT.getreply(BSSGP_register_client:{imsi, tlli, cell_id}) {};
	}
}

function f_bssgp_client_unregister(hexstring imsi, BSSGP_PROC_PT PT := BSSGP_PROC)
runs on BSSGP_Client_CT {
	PT.call(BSSGP_unregister_client:{imsi}) {
		[] PT.getreply(BSSGP_unregister_client:{imsi}) {};
	}
}

/* TS 44.064 7.2.1.1 LLGMM-ASSIGN */
function f_bssgp_client_llgmm_assign(OCT4 tlli_old, OCT4 tlli_new, BSSGP_PROC_PT PT := BSSGP_PROC)
runs on BSSGP_Client_CT {
	PT.call(BSSGP_llgmm_assign:{tlli_old, tlli_new}) {
		[] PT.getreply(BSSGP_llgmm_assign:{tlli_old, tlli_new}) {};
	}
}

template BssgpDecoded tr_BD_BSSGP(template PDU_BSSGP bg) := {
	bssgp := bg,
	llc := *,
	l3_mo := *,
	l3_mt := *,
	sndcp := *
}

template BssgpDecoded tr_BD_LLC(template PDU_LLC llc) := {
	bssgp := ?,
	llc := llc,
	l3_mo := *,
	l3_mt := *,
	sndcp := *
}

template BssgpDecoded tr_BD_L3_MT(template PDU_L3_SGSN_MS mt) := {
	bssgp := ?,
	llc := ?,
	l3_mo := omit,
	l3_mt := mt,
	sndcp := omit
}

template BssgpDecoded tr_BD_L3_MO(template PDU_L3_MS_SGSN mo) := {
	bssgp := ?,
	llc := ?,
	l3_mo := mo,
	l3_mt := omit,
	sndcp := omit
}



}
