aboutsummaryrefslogtreecommitdiffstats
path: root/library/PCUIF_CodecPort.ttcn
diff options
context:
space:
mode:
Diffstat (limited to 'library/PCUIF_CodecPort.ttcn')
-rw-r--r--library/PCUIF_CodecPort.ttcn68
1 files changed, 50 insertions, 18 deletions
diff --git a/library/PCUIF_CodecPort.ttcn b/library/PCUIF_CodecPort.ttcn
index 0411c390..55d2ee7c 100644
--- a/library/PCUIF_CodecPort.ttcn
+++ b/library/PCUIF_CodecPort.ttcn
@@ -15,6 +15,7 @@ import from Osmocom_Types all;
import from PCUIF_Types all;
import from UD_PortType all;
import from UD_Types all;
+import from General_Types all;
type record PCUIF_send_data {
PCUIF_Message data,
@@ -23,7 +24,7 @@ type record PCUIF_send_data {
private function PCUIF_to_UD(in PCUIF_send_data pin, out UD_send_data pout) {
pout.id := pin.id;
- pout.data := enc_pad_PCUIF_Message(pin.data);
+ pout.data := enc_PCUIF_Message(pin.data);
} with { extension "prototype(fast)" };
private function fix_padding(inout PCUIF_data data) {
@@ -37,7 +38,6 @@ private function UD_to_PCUIF(in UD_send_data pin, out PCUIF_send_data pout) {
/* HACK: fix padding in decoded message. Due to a bug in TITAN, we
* cannot just use its 'PADDING' attribute because it breaks decoding. */
if (ischosen(pout.data.u.data_req)) { fix_padding(pout.data.u.data_req); }
- if (ischosen(pout.data.u.data_cnf)) { fix_padding(pout.data.u.data_cnf); }
if (ischosen(pout.data.u.data_ind)) { fix_padding(pout.data.u.data_ind); }
} with { extension "prototype(fast)" };
@@ -139,34 +139,66 @@ function f_pcuif_listen(PCUIF_CODEC_PT pt, charstring sock) return integer {
}
function f_PCUIF_tx_imm_ass_pch(PCUIF_CODEC_PT pt, integer conn_id, octetstring imm_ass, hexstring imsi,
- uint8_t bts_nr := 0) return uint32_t {
- var PCUIF_send_data sd;
+ uint8_t bts_nr := 0, boolean wait_for_cnf := true, OCT4 msg_id := '01020304'O) {
timer T := 3.0;
- /* append 3 last imsi digits so BTS can compute pagng group */
- var hexstring last_digits := substr(imsi, lengthof(imsi)-3, 3);
- var octetstring prefix := ''O;
- log("3 last imsi digits: ", last_digits);
- for (var integer i := 0; i < 3; i := i+1) {
- prefix := prefix & int2oct(hex2int('30'H) + hex2int(last_digits[i]), 1);
+
+ var PCUIF_pch pch := {
+ msg_id := msg_id,
+ imsi := hex2str(imsi),
+ data := imm_ass,
+ confirm := true
+ };
+ pt.send(t_SD_PCUIF(conn_id, ts_PCUIF_DATA_REQ(bts_nr, 0, 0, 0, 0, PCU_IF_SAPI_PCH_2, enc_PCUIF_pch(pch))));
+
+ /* Exit early when the caller is not interested in the confirmation message */
+ if (wait_for_cnf == false) {
+ return;
}
- pt.send(t_SD_PCUIF(conn_id,
- ts_PCUIF_DATA_REQ(bts_nr, 0, 0, 0, 0, PCU_IF_SAPI_PCH, prefix & imm_ass)));
+
T.start;
alt {
- [] pt.receive(t_SD_PCUIF(conn_id,
- tr_PCUIF_DATA_CNF(bts_nr, 0, 0, PCU_IF_SAPI_PCH))) -> value sd {
- log("IMM.ASS was sent on fn ", sd.data.u.data_cnf.fn);
- return sd.data.u.data_cnf.fn;
+ [] pt.receive(t_SD_PCUIF(conn_id, tr_PCUIF_DATA_CNF_2(bts_nr, PCU_IF_SAPI_PCH_2))) {
+ log("IMM.ASS was sent on PCH");
}
[] pt.receive { repeat; }
[] T.timeout {
- setverdict(fail, "Timeout waiting for PCU DATA.cnf");
+ setverdict(fail, "Timeout waiting for PCU DATA.cnf (PCH)");
mtc.stop;
}
}
- return 0;
}
+/* This function can be used to transmit arbitrary GSM MAC blocks via the AGCH. The BTS will only confirm those MAC
+ * blocks that contain actually a valid immediate assignment message. Otherweise no confirmation is sent back */
+function f_PCUIF_tx_mac_block_agch(PCUIF_CODEC_PT pt, integer conn_id, octetstring mac_block, boolean confirm := true,
+ uint8_t bts_nr := 0, boolean wait_for_cnf := true, OCT4 msg_id := '01020304'O) {
+ timer T := 3.0;
+
+ var PCUIF_agch agch := {
+ msg_id := msg_id,
+ data := mac_block,
+ confirm := confirm
+ };
+ pt.send(t_SD_PCUIF(conn_id, ts_PCUIF_DATA_REQ(bts_nr, 0, 0, 0, 0, PCU_IF_SAPI_AGCH_2, enc_PCUIF_agch(agch))));
+
+ /* Exit early when the caller is not interested in the confirmation message */
+ if (wait_for_cnf == false) {
+ return;
+ }
+
+ T.start;
+ alt {
+ [] pt.receive(t_SD_PCUIF(conn_id, tr_PCUIF_DATA_CNF_2(bts_nr, PCU_IF_SAPI_AGCH_2))) {
+ log("IMM.ASS was sent on AGCH");
+ }
+ [] pt.receive { repeat; }
+ [] T.timeout {
+ setverdict(fail, "Timeout waiting for PCU DATA.cnf (AGCH)");
+ mtc.stop;
+ }
+ }
+ return;
+}