module BTS_Tests_LAPDm {

import from GSM_Types all;
import from Osmocom_Types all;
import from LAPDm_RAW_PT all;
import from LAPDm_Types all;
import from BTS_Tests all;

/* test that use exclusively only LAPDm over L1CTL */
type component lapdm_test_CT {
	port LAPDm_PT LAPDM;
	var lapdm_CT lapdm_component;
};

/* contrary to BTS_Tests.ttcn, we use LAPDm_PT here, a convenience wrapper
 * around L1CTL to perform encode/decode of abstract LAPDm frames */
type component lapdm_bts_CT extends lapdm_test_CT, test_CT {
}

/*********************************************************************************
 * Test using only L1CTL/LAPDm
 *********************************************************************************/

function f_lapdm_init() runs on lapdm_test_CT {
	/* create the LAPDm component */
	lapdm_component := lapdm_CT.create;
	/* connect our own LAPDM port to the LAPDM Service Provider of the LAPDm component */
	connect(self:LAPDM, lapdm_component:LAPDM_SP);
	/* connect the LAPDm compoent's lower-side port to the system L1CTL port (which is internally
	 * connected to the Unix Domain Socket test port */
	map(lapdm_component:L1CTL, system:L1CTL);

	/* start the LAPDm parallel component calling it's local function LAPDmStart */
	lapdm_component.start(LAPDmStart());
}

/* master function establishing a dedicated radio channel (takes care of RACH/IMM.ASS handling) */
function f_establish_dcch() runs on lapdm_test_CT {
	var BCCH_tune_req tune_req := { arfcn := { false, 871 }, combined_ccch := true };
	var DCCH_establish_req est_req := { ra := 23 };

	LAPDM.send(tune_req);
	LAPDM.send(est_req);
	LAPDM.receive(DCCH_establish_res:?);
}

/* helper function releasing dedicated radio channel physically (no Um signaling!) */
function f_release_dcch() runs on lapdm_test_CT {
	var DCCH_release_req rel_req := {};
	LAPDM.send(rel_req);
}

template LAPDm_ph_data t_PH_DATA(template GsmSapi sapi, template boolean sacch, template LapdmFrame frame) := {
	sacch := sacch,
	sapi := sapi,
	lapdm := frame
}
/* template for a valid SABM frame */
template LapdmFrame LAPDm_B_SABM(template GsmSapi sapi, octetstring payload)  := {
	ab := {
		addr := tr_LapdmAddr(sapi, false),
		ctrl := tr_LapdmCtrlSABM(true),
		len := lengthof(payload),
		m := false,
		el := 1,
		payload := payload
	}
}

/* template for a valid UA frame */
template LapdmFrame tr_LAPDm_B_UA(template GsmSapi sapi, template octetstring payload)  := {
	ab := {
		addr := tr_LapdmAddr(sapi, false),
		ctrl := tr_LapdmCtrlUA(true),
		len := ?,
		m := false,
		el := 1,
		payload := payload
	}
}

/* template for a valid UA frame */
template LapdmFrame LAPDm_B_UA(template GsmSapi sapi, octetstring payload)  := {
	ab := {
		addr := tr_LapdmAddr(sapi, false),
		ctrl := tr_LapdmCtrlUA(true),
		len := lengthof(payload),
		m := false,
		el := 1,
		payload := payload
	}
}

/* template for a valid UI frame */
template LapdmFrame LAPDm_B_UI(template GsmSapi sapi, octetstring payload)  := {
	ab := {
		addr := tr_LapdmAddr(sapi, true),
		ctrl := tr_LapdmCtrlUI(false),
		len := lengthof(payload),
		m := false,
		el := 1,
		payload := payload
	}
}

template LapdmFrame t_nopayload(template GsmSapi sapi) := {
	ab := {
		addr := tr_LapdmAddr(sapi, true),
		ctrl := ?,
		len := 0,
		m := false,
		el := 1,
		payload := ''O
	}
}

template LapdmFrame LAPDm_B_DISC(template GsmSapi sapi) modifies t_nopayload := {
	ab := {
		ctrl := tr_LapdmCtrlDISC(true)
	}
}

template LapdmFrame LAPDm_B_RR(template GsmSapi sapi, template uint3_t nr) modifies t_nopayload := {
	ab := {
		ctrl := tr_LapdmCtrlRR(nr, false)
	}
}


function f_test_sabm_results_in_ua(uint8_t sapi, boolean use_sacch, octetstring payload) runs on lapdm_test_CT return boolean {
	var LAPDm_ph_data phd;
	var boolean result := false;
	timer T := 5.0;

	f_establish_dcch();
	LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload)));
	log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload)));
	T.start
	alt {
		[] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { result := true; }
		[] LAPDM.receive(t_PH_DATA(?, use_sacch, ?)) -> value phd { log("Other msg on DCH: ", phd); repeat; }
		[] LAPDM.receive(t_PH_DATA(?, ?, ?)) -> value phd { log("Other PH-DATA: ", phd); repeat; }
		[] T.timeout { }
	}
	LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_RR(sapi, 0)));
	f_release_dcch();
	return result;
}

testcase TC_sabm_ua_dcch_sapi0() runs on lapdm_test_CT {
	f_lapdm_init();
	if (not f_test_sabm_results_in_ua(0, false, 'FEFE'O)) {
		setverdict(fail);
	}
	setverdict(pass);
}

testcase TC_sabm_ua_dcch_sapi0_nopayload() runs on lapdm_test_CT {
	f_lapdm_init();
	if (f_test_sabm_results_in_ua(0, false, ''O)) {
		setverdict(fail, "Initial SABM/UA must contain L3 payload but BTS accepts without");
	}
	setverdict(pass);
}

testcase TC_sabm_ua_dcch_sapi3() runs on lapdm_test_CT {
	f_lapdm_init();
	if (f_test_sabm_results_in_ua(3, false, 'FEFE'O)) {
		setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=3");
	}
	setverdict(pass);
}

testcase TC_sabm_ua_dcch_sapi4() runs on lapdm_test_CT {
	f_lapdm_init();
	if (f_test_sabm_results_in_ua(4, false, 'FEFE'O)) {
		setverdict(fail, "Initial SABM/UA must be on SAPI0, but BTS accepts SAPI=4");
	}
	setverdict(pass);
}

testcase TC_sabm_contention() runs on lapdm_test_CT {
	var LAPDm_ph_data phd;
	const octetstring payload := '0102030405'O;
	const GsmSapi sapi := 0;
	const boolean use_sacch := false;
	timer T := 5.0;

	f_lapdm_init();

	f_establish_dcch();
	/* first frame is our real SABM */
	LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, payload)));
	/* second frame is a SABM with different payload, which BTS has to ignore according to 8.4.1.4 */
	LAPDM.send(t_PH_DATA(sapi, use_sacch, LAPDm_B_SABM(sapi, 'ABCDEF'O)));
	log("====> expecting ", t_PH_DATA(sapi, use_sacch, LAPDm_B_UA(sapi, payload)));
	T.start
	alt {
		[] LAPDM.receive(t_PH_DATA(?, use_sacch, LAPDm_B_UA(sapi, payload))) { setverdict(pass); repeat; }
		[] LAPDM.receive(t_PH_DATA(?, use_sacch, tr_LAPDm_B_UA(sapi, ?))) {
			setverdict(fail, "Second SABM was responded to during contention resolution");
		}
		[] LAPDM.receive { repeat };
		[] T.timeout { }
	}
	f_release_dcch();
}

/* we test that a re-transmitted SABM with identical payload will result in the retransmission of a
  * UA. This is required during the contention resolution procedure as specified in 8.4.1.4 */
testcase TC_sabm_retransmit() runs on lapdm_test_CT {
	const octetstring payload := '00FEFEDEADBEEF'O;
	f_lapdm_init();
	if (not f_test_sabm_results_in_ua(0, false, payload)) {
		setverdict(fail, "UA not received for first SABM");
	}
	if (not f_test_sabm_results_in_ua(0, false, payload)) {
		setverdict(fail, "UA not received for second SABM");
	}
	setverdict(pass);
}

testcase TC_foo() runs on lapdm_test_CT {
	var LapdmFrame lf;
/*
	var LapdmFrame lf := valueof(LAPDm_B_UA(0, ''O));
	log("ENC UA: ", enc_LapdmFrame(lf));
	lf := valueof(LAPDm_B_UI(0, ''O));
	log("ENC UI B: ", enc_LapdmFrame(lf));
	log("ENC UI B: ", enc_LapdmFrameB(lf.b));

	log("DEC UI AF: ", dec_LapdmAddressField('03'O));
*/

	lf := valueof(LAPDm_B_RR(0, 0));
	log("ENC RR: ", enc_LapdmFrame(lf));

	lf := valueof(LAPDm_B_UA(0, ''O));
	log("ENC UA: ", enc_LapdmFrame(lf));

	lf := valueof(LAPDm_B_UI(0, ''O));
	log("ENC UI: ", enc_LapdmFrame(lf));

	log("DEC UI CU: ", dec_LapdmCtrlU('03'O));
	log("DEC UI CT: ", dec_LapdmCtrl('03'O));

	log("DEC UA: ", dec_LapdmFrameAB('017301'O));
	log("DEC UI: ", dec_LapdmFrameAB('030301'O));
	log("DEC I: ", dec_LapdmFrameAB('030001'O));
	log("DEC S: ", dec_LapdmFrameAB('030101'O));
	log("DEC: ", dec_LapdmFrameAB('030301'O));
	log("DEC: ", dec_LapdmFrameAB('0303012B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B2B'O));
}

control {
	execute(TC_foo());
	execute(TC_sabm_ua_dcch_sapi0());
	execute(TC_sabm_ua_dcch_sapi0_nopayload());
	execute(TC_sabm_ua_dcch_sapi3());
	execute(TC_sabm_ua_dcch_sapi4());
	execute(TC_sabm_contention());
	execute(TC_sabm_retransmit());
}

}
