module BSSGP_Emulation {

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;

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;
	out	PDU_BSSGP,
		NsStatusIndication,
		BssgpStatusIndication,
		ASP_Event;
} with { extension "internal" };

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

function BssgpStart(boolean sgsn_role := false) runs on BSSGP_CT {
	g_sgsn_role := sgsn_role
	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;

	var boolean g_sgsn_role := true;
	var BvcState g_ptp_bvc_state := BVC_S_BLOCKED;
	timer g_T1 := 15.0;
	timer g_T2 := 60.0;
}

modulepar {
	Nsvci mp_nsei := 96;
	Nsvci mp_bvci := 196;
	BssgpCellId mp_cellid := { ra_id := { lai := { mcc_mnc := '26242F'H, lac := 13135}, rac := 0 }, cell_id := 20960 };
};

function f_BnsUdReq(template PDU_BSSGP pdu, BssgpBvci bvci := mp_bvci) return NsUnitdataRequest {
	var NsUnitdataRequest udr := {
		bvci := bvci,
		nsei := mp_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 := mp_bvci) return template NsUnitdataIndication {
	var template NsUnitdataIndication udi := {
		bvci := bvci,
		nsei := mp_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;
	BSSGP_SP.send(t_BssgpStsInd(mp_nsei, mp_bvci, g_ptp_bvc_state));
}

private function f_sendReset() runs on BSSGP_CT {
	var PDU_BSSGP pdu := valueof(ts_BVC_RESET(BSSGP_CAUSE_OM_INTERVENTION, mp_bvci, mp_cellid));
	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(mp_bvci), 0));
	g_T1.start;
}

private function f_sendBlock(BssgpCause cause) runs on BSSGP_CT {
	BSCP.send(f_BnsUdReq(t_BVC_BLOCK(mp_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(mp_bvci, cause, pdu)));
}

altstep as_allstate() runs on BSSGP_CT {
	var NsUnitdataIndication udi;
	var NsStatusIndication nsi;
	var ASP_Event evt;

	/* 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(?, mp_bvci, mp_cellid), 0)) -> value udi {
		log("Rx BVC-RESET for Our BVCI=", mp_bvci);
		BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(mp_bvci, mp_cellid), 0));
		f_change_state(BVC_S_UNBLOCKED);
	}

	/* Respond to RESET for signalling BVCI 0 */
	[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET(?, 0, mp_cellid), 0)) -> value udi {
		log("Rx BVC-RESET for Signaling BVCI=0");
		BSCP.send(f_BnsUdReq(ts_BVC_RESET_ACK(0, mp_cellid), 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 { BSSGP_SP.send(evt); }
	[] 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_sgsn_role == false) {
				f_sendReset();
			}
			/* Idea: We coudl send BVC-UNBLOCK here like some SGSN do */
		}
		BSSGP_SP.send(nsi);
	}
}

private function f_ScanEvents() runs on BSSGP_CT {
	var NsUnitdataIndication udi;
	var PDU_BSSGP bs_pdu;
	var default d;


	log("matching against ", tr_BVC_RESET(?, mp_bvci, mp_cellid));

	d := activate(as_allstate());

	while (true) {
	if (g_ptp_bvc_state == BVC_S_BLOCKED) {
		alt {
			[] g_T1.timeout {
				f_sendUnblock();
			}
			[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK_ACK(mp_bvci), 0)) {
				g_T1.stop;
				f_change_state(BVC_S_UNBLOCKED);
			}
			[not g_sgsn_role] BSCP.receive(f_BnsUdInd(tr_BVC_RESET_ACK(mp_bvci, omit), 0)) {
				f_sendUnblock();
			}
		}
	} else if (g_ptp_bvc_state == BVC_S_UNBLOCKED) {
		alt {
			/* bogus unblock, just respond with ACK */
			[] BSCP.receive(f_BnsUdInd(t_BVC_UNBLOCK(mp_bvci), 0)) -> value udi {
				BSCP.send(f_BnsUdReq(t_BVC_UNBLOCK_ACK(mp_bvci), 0));
			}
			/* Respond to BLOCK with BLOCK-ACK + change state */
			[] BSCP.receive(f_BnsUdInd(t_BVC_BLOCK(mp_bvci, ?), 0)) -> value udi {
				BSCP.send(f_BnsUdReq(t_BVC_BLOCK_ACK(mp_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(mp_bvci), 0)) -> value udi {
				g_T1.stop;
				f_change_state(BVC_S_BLOCKED);
			}
			[] BSCP.receive(f_BnsUdInd(tr_BVC_RESET_ACK(mp_bvci, mp_cellid), 0)) -> value udi {
				g_T2.stop;
				f_change_state(BVC_S_UNBLOCKED);
			}

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

			/* BSSGP-UNITDATA PDUs from network to NS-UNITDATA.ind to user */
			[not g_sgsn_role] BSCP.receive(f_BnsUdInd(tr_BSSGP_DL_UD)) -> value udi {
				BSSGP_SP.send(udi.bssgp);
			}
			[g_sgsn_role] BSCP.receive(f_BnsUdInd(tr_BSSGP_UL_UD)) -> value udi {
				BSSGP_SP.send(udi.bssgp);
			}
			/* pass virtually any PDU from user to NS-UNITDATA PDU on network */
			[] BSSGP_SP.receive(PDU_BSSGP:?) -> value bs_pdu {
				BSCP.send(f_BnsUdReq(bs_pdu));
			}

		}
	}

	} /* while */
	//deactivate(d);
}


}
