From e613f96593f9a511001f27ad2ef4766ba34fb77b Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Wed, 18 Apr 2018 22:38:16 +0200 Subject: [PATCH] bts: ciphering tests Change-Id: If450e36cfd8cde713f304e57ec09bc1239bdf7ea --- bsc/MSC_ConnectionHandler.ttcn | 22 +-- bts/BTS_Tests.ttcn | 263 +++++++++++++++++++++++++++++++-- library/L1CTL_PortType.ttcn | 4 + library/L1CTL_Types.ttcn | 27 ++++ library/L3_Templates.ttcn | 22 +++ library/LAPDm_Types.ttcn | 63 +++++++- library/RSL_Types.ttcn | 22 ++- 7 files changed, 387 insertions(+), 36 deletions(-) diff --git a/bsc/MSC_ConnectionHandler.ttcn b/bsc/MSC_ConnectionHandler.ttcn index e64842760..efd68a342 100644 --- a/bsc/MSC_ConnectionHandler.ttcn +++ b/bsc/MSC_ConnectionHandler.ttcn @@ -395,42 +395,42 @@ function f_rsl_reply(template PDU_ML3_MS_NW l3, RSL_Message orig) runs on MSC_Co } /* Convert the chipher representation on BSSMAP to the representation used on RSL */ -function f_chipher_mode_bssmap_to_rsl(OCT1 alg_bssmap) return OCT1 +function f_chipher_mode_bssmap_to_rsl(OCT1 alg_bssmap) return RSL_AlgId { /* A5 0 */ if (alg_bssmap == '01'O) { - return '01'O; + return RSL_ALG_ID_A5_0; } /* A5 1 */ else if (alg_bssmap == '02'O) { - return '02'O; + return RSL_ALG_ID_A5_1; } /* A5 2 */ else if (alg_bssmap == '04'O) { - return '03'O; + return RSL_ALG_ID_A5_2; } /* A5 3 */ else if (alg_bssmap == '08'O) { - return '04'O; + return RSL_ALG_ID_A5_3; } /* A5 4 */ else if (alg_bssmap == '10'O) { - return '05'O; + return RSL_ALG_ID_A5_4; } /* A5 5 */ else if (alg_bssmap == '20'O) { - return '06'O; + return RSL_ALG_ID_A5_5; } /* A5 6 */ else if (alg_bssmap == '40'O) { - return '07'O; + return RSL_ALG_ID_A5_6; } /* A5 7 */ else if (alg_bssmap == '80'O) { - return '08'O; + return RSL_ALG_ID_A5_7; } else { setverdict(fail, "Unexpected Encryption Algorithm"); - return '00'O; + return RSL_ALG_ID_A5_0; } } @@ -438,7 +438,7 @@ function f_cipher_mode(OCT1 alg, OCT8 key, template OCT16 kc128 := omit, boolean runs on MSC_ConnHdlr { var PDU_BSSAP bssap; var RSL_Message rsl; - var OCT1 alg_rsl; + var RSL_AlgId alg_rsl; if (isvalue(kc128)) { BSSAP.send(ts_BSSMAP_CipherModeCmdKc128(alg, key, valueof(kc128))); diff --git a/bts/BTS_Tests.ttcn b/bts/BTS_Tests.ttcn index c7064374c..69f7b575e 100644 --- a/bts/BTS_Tests.ttcn +++ b/bts/BTS_Tests.ttcn @@ -143,7 +143,8 @@ type record ConnHdlrPars { RSL_IE_ChannelMode chan_mode, float t_guard, ConnL1Pars l1_pars, - TestSpecUnion spec optional + TestSpecUnion spec optional, + RSL_IE_EncryptionInfo encr optional } /* Test-specific parameters */ @@ -464,9 +465,17 @@ runs on ConnHdlr { var RSL_Message rx := f_rsl_transceive_ret(tx, exp_rx, id, ignore_other); } -function f_rsl_chan_act(RSL_IE_ChannelMode mode) runs on ConnHdlr { - f_rsl_transceive(ts_RSL_CHAN_ACT(g_chan_nr, mode), tr_RSL_CHAN_ACT_ACK(g_chan_nr), - "RSL CHAN ACT"); +function f_rsl_chan_act(RSL_IE_ChannelMode mode, boolean encr_enable := false) +runs on ConnHdlr { + var RSL_Message ch_act := valueof(ts_RSL_CHAN_ACT(g_chan_nr, mode)); + if (encr_enable) { + /* append encryption related IEs, if requested */ + var RSL_IE_EncryptionInfo encr_info; + encr_info := valueof(ts_RSL_IE_EncrInfo(g_pars.encr.alg_id, g_pars.encr.key)); + ch_act.ies := ch_act.ies & { valueof(t_RSL_IE(RSL_IE_ENCR_INFO, RSL_IE_Body:{encr_info := +encr_info})) }; + } + f_rsl_transceive(ch_act, tr_RSL_CHAN_ACT_ACK(g_chan_nr), "RSL CHAN ACT"); } function f_rsl_chan_deact() runs on ConnHdlr { @@ -498,7 +507,8 @@ private template ConnHdlrPars t_Pars(template RslChannelNr chan_nr, ms_power_level := 0, ms_actual_ta := 0 }, - spec := omit + spec := omit, + encr := omit } /*********************************************************************** @@ -620,6 +630,23 @@ testcase TC_chan_act_wrong_nr() runs on test_CT { f_shutdown(); } +/* execute the same callback function on a variety of logical channels */ +private function f_testmatrix_each_chan(ConnHdlrPars pars, void_fn fn) runs on test_CT { + var ConnHdlr vc_conn; + f_init(testcasename()); + + /* test on each of the channels we have */ + for (var integer i := 0; i < sizeof(g_AllChanTypes); i := i+1) { + pars.chan_nr := valueof(g_AllChanTypes[i]); + + log(testcasename(), ": XXX Starting on ", g_AllChanTypes[i]); + vc_conn := f_start_handler(fn, pars); + vc_conn.done; + } + + f_shutdown(); +} + /*********************************************************************** * SACCH handling ***********************************************************************/ @@ -1254,8 +1281,42 @@ altstep as_meas_res() runs on ConnHdlr { } } +private function f_alg_id_to_l1ctl(RSL_AlgId rsl_alg_id) return uint8_t { + select (rsl_alg_id) { + case (RSL_ALG_ID_A5_0) { return 0; } + case (RSL_ALG_ID_A5_1) { return 1; } + case (RSL_ALG_ID_A5_2) { return 2; } + case (RSL_ALG_ID_A5_3) { return 3; } + case (RSL_ALG_ID_A5_4) { return 4; } + case (RSL_ALG_ID_A5_5) { return 5; } + case (RSL_ALG_ID_A5_6) { return 6; } + case (RSL_ALG_ID_A5_7) { return 7; } + case else { + setverdict(fail, "Unknwon Algorithm ID"); + self.stop; + } + } +} + +private function f_alg_id_to_l3(RSL_AlgId rsl_alg_id) return BIT3 { + select (rsl_alg_id) { + case (RSL_ALG_ID_A5_1) { return '000'B; } + case (RSL_ALG_ID_A5_2) { return '001'B; } + case (RSL_ALG_ID_A5_3) { return '010'B; } + case (RSL_ALG_ID_A5_4) { return '011'B; } + case (RSL_ALG_ID_A5_5) { return '100'B; } + case (RSL_ALG_ID_A5_6) { return '101'B; } + case (RSL_ALG_ID_A5_7) { return '110'B; } + case else { + setverdict(fail, "Unknwon Algorithm ID"); + self.stop; + } + } +} + + /* Establish dedicated channel: L1CTL + RSL side */ -private function f_est_dchan() runs on ConnHdlr { +private function f_est_dchan(boolean encr_enable := false) runs on ConnHdlr { var GsmFrameNumber fn; var ImmediateAssignment imm_ass; var integer ra := 23; @@ -1265,7 +1326,7 @@ private function f_est_dchan() runs on ConnHdlr { //RSL.receive(tr_RSL_CHAN_RQD(int2oct(23,1))); /* Activate channel on BTS side */ - f_rsl_chan_act(g_pars.chan_mode); + f_rsl_chan_act(g_pars.chan_mode, encr_enable); /* Send IMM.ASS via CCHAN */ var ChannelDescription ch_desc := { @@ -1287,6 +1348,11 @@ private function f_est_dchan() runs on ConnHdlr { ia_um := f_L1CTL_WAIT_IMM_ASS(L1CTL, ra, fn); /* enable dedicated mode */ f_L1CTL_DM_EST_REQ_IA(L1CTL, ia_um); + /* enable encryption, if requested */ + if (encr_enable) { + var uint8_t alg_id := f_alg_id_to_l1ctl(g_pars.encr.alg_id); + f_L1CTL_CRYPTO_REQ(L1CTL, g_pars.chan_nr, alg_id, g_pars.encr.key); + } g_first_meas_res := true; } @@ -3349,9 +3415,9 @@ private function f_TC_rll_ud_req(charstring id) runs on ConnHdlr { RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, tc.link_id, tc.l3)); /* Expect it to arrive on the other side */ if (tc.link_id.c == SACCH) { - f_l1_exp_lapdm(tr_LAPDm_B4_UI(tc.sapi, cr_MT_CMD, false, tc.l3)); + f_l1_exp_lapdm(tr_LAPDm_B4_UI(tc.sapi, cr_MT_CMD, tc.l3)); } else { - f_l1_exp_lapdm(tr_LAPDm_UI(tc.sapi, cr_MT_CMD, false, tc.l3)); + f_l1_exp_lapdm(tr_LAPDm_UI(tc.sapi, cr_MT_CMD, tc.l3)); } /* release the channel */ @@ -3387,7 +3453,7 @@ private function f_TC_rll_ud_ind(charstring id) runs on ConnHdlr { L1CTL.clear; /* Send LAPDm UI frame. There is no B4 format in uplink! */ - f_tx_lapdm(ts_LAPDm_UI(tc.sapi, cr_MO_CMD, false, tc.l3), tc.link_id); + f_tx_lapdm(ts_LAPDm_UI(tc.sapi, cr_MO_CMD, tc.l3), tc.link_id); /* Expdct RLL UNITDATA IND on RSL side */ alt { [] RSL.receive(tr_RSL_UNITDATA_IND(g_chan_nr, tc.link_id, tc.l3)) { @@ -3418,6 +3484,172 @@ testcase TC_rll_unit_data_ind_ACCH() runs on test_CT { f_rll_testmatrix(tcs, refers(f_TC_rll_ud_ind)); } +/*********************************************************************** + * Encryption Related + ***********************************************************************/ + +/* send UNITDATA_REQ from BTS to MS and expect it to arrive */ +function f_unitdata_mt(RslLinkId link_id, octetstring l3) runs on ConnHdlr { + RSL.send(ts_RSL_UNITDATA_REQ(g_chan_nr, link_id, l3)); + if (link_id.c == SACCH) { + f_l1_exp_lapdm(tr_LAPDm_B4_UI(link_id.sapi, cr_MT_CMD, l3)); + } else { + f_l1_exp_lapdm(tr_LAPDm_UI(link_id.sapi, cr_MT_CMD, l3)); + } +} + +/* Send UI frame from MS and expect it to arrive as RLL UNITDATA IND on Abis */ +function f_unitdata_mo(RslLinkId link_id, octetstring l3) runs on ConnHdlr { + timer T := 3.0; + f_tx_lapdm(ts_LAPDm_UI(link_id.sapi, cr_MO_CMD, l3), link_id); + T.start; + /* Expect RLL UNITDATA IND on RSL side */ + alt { + [] RSL.receive(tr_RSL_UNITDATA_IND(g_chan_nr, link_id, l3)) { + setverdict(pass); + } + [] T.timeout { + setverdict(fail, "Timeout waiting for UNIT_DATA_IND"); + } + [] RSL.receive { repeat; } + } +} + +/* Test channel activation with A5/n right from the beginning (like in assignment + hand-over) */ +function f_TC_chan_act_encr(charstring id) runs on ConnHdlr { + f_l1_tune(L1CTL); + f_est_dchan(true); + + /* now we actually need to transmit some data both ways to check if the encryption works */ + var L1ctlDlMessage dl; + + var octetstring l3 := f_rnd_octstring(16); + var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0)); + + /* send UNITDATA_REQ from BTS to MS and expect it to arrive */ + f_unitdata_mt(link_id, l3); + + /* Send UI frame from MS and expect it to arrive as RLL UNITDATA IND on Abis */ + f_unitdata_mo(link_id, l3); + + /* release the channel */ + f_rsl_chan_deact(); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_chan_act_a51() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_1, f_rnd_octstring(8))); + f_testmatrix_each_chan(pars, refers(f_TC_chan_act_encr)); +} +testcase TC_chan_act_a52() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_2, f_rnd_octstring(8))); + f_testmatrix_each_chan(pars, refers(f_TC_chan_act_encr)); +} +testcase TC_chan_act_a53() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_3, f_rnd_octstring(8))); + f_testmatrix_each_chan(pars, refers(f_TC_chan_act_encr)); +} + + +/* Test unencrypted channel activation followed by explicit ENCR CMD later */ +function f_TC_encr_cmd(charstring id) runs on ConnHdlr { + /* L3 payload doesn't matter, as it is passed transparently */ + var BIT3 l3_alg_id := f_alg_id_to_l3(g_pars.encr.alg_id); + var octetstring l3 := enc_PDU_ML3_NW_MS(valueof(ts_RRM_CiphModeCmd(l3_alg_id))); + var RslLinkId link_id := valueof(ts_RslLinkID_DCCH(0)); + + f_l1_tune(L1CTL); + + /* first establish a dedicated channel in the clear */ + f_est_dchan(false); + + /* Establish ABM */ + f_est_rll_mo(link_id.sapi, link_id, '23420815'O); + + /* then send the RSL ENCR CMD with an actual RR CIPH MOD CMD inside */ + RSL.send(ts_RSL_ENCR_CMD(g_chan_nr, link_id, g_pars.encr.alg_id, g_pars.encr.key, l3)); + /* expect the L3 to arrive still unencrypted on the MS side */ + f_l1_exp_lapdm(tr_LAPDm_I(link_id.sapi, cr_MT_CMD, ?, ?, ?, l3)); + + /* configure L1 to apply ciphering */ + var uint8_t alg_id := f_alg_id_to_l1ctl(g_pars.encr.alg_id); + f_L1CTL_CRYPTO_REQ(L1CTL, g_pars.chan_nr, alg_id, g_pars.encr.key); + + /* send first ciphered I-frame in response */ + l3 := '0a0b0c0d'O; + f_tx_lapdm(ts_LAPDm_I(link_id.sapi, cr_MO_CMD, true, 1, 0, l3), link_id); + RSL.receive(tr_RSL_DATA_IND(g_chan_nr, link_id, l3)); + + /* now the BTS code should have detected the first properly encrypted uplink I-frame, + * and hence enable encryption also on the downlink */ + + /* expect bi-directional communication work in encrypted mode */ + f_unitdata_mo(link_id, f_rnd_octstring(15)); + f_unitdata_mt(link_id, f_rnd_octstring(15)); + + /* release the channel */ + f_rsl_chan_deact(); + f_L1CTL_DM_REL_REQ(L1CTL, g_chan_nr); + f_rslem_unregister(0, g_chan_nr); +} +testcase TC_encr_cmd_a51() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_1, f_rnd_octstring(8))); + f_testmatrix_each_chan(pars, refers(f_TC_encr_cmd)); +} +testcase TC_encr_cmd_a52() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_2, f_rnd_octstring(8))); + f_testmatrix_each_chan(pars, refers(f_TC_encr_cmd)); +} +testcase TC_encr_cmd_a53() runs on test_CT { + var ConnHdlrPars pars := valueof(t_Pars(t_RslChanNr_Bm(1), ts_RSL_ChanMode_SIGN)); + pars.encr := valueof(ts_RSL_IE_EncrInfo(RSL_ALG_ID_A5_3, f_rnd_octstring(8))); + f_testmatrix_each_chan(pars, refers(f_TC_encr_cmd)); +} + +private function f_assert_lapdm(octetstring enc, template LapdmFrame exp_match, charstring name := "") { + var LapdmFrame lf; + var octetstring reenc; + + /* decode the LAPDm frame */ + if (ischosen(exp_match.ab)) { + lf.ab := dec_LapdmFrameAB(enc); + } else { + setverdict(fail, "unsupported frame type"); + self.stop; + } + + /* check if decoder result matches expectation */ + if (not match(lf, exp_match)) { + setverdict(fail, name, ": decoded LAPDm doesn't match"); + } else { + log(name, ": matched"); + setverdict(pass); + } + + /* test if re-encoded frame equals original input */ + reenc := enc_LapdmFrame(lf); + if (enc != reenc) { + setverdict(fail, name, ": re-encoded LAPDm frame doesn't match"); + } else { + setverdict(pass); + } +} + +testcase TC_lapdm_selftest() runs on test_CT { + f_assert_lapdm('030301'O, tr_LAPDm_UI(0, true, ''O), "ui_s0_empty"); + f_assert_lapdm('0F0301'O, tr_LAPDm_UI(3, true, ''O), "ui_s3_empty"); + f_assert_lapdm('013F01'O, tr_LAPDm_SABM(0, false, true, ''O), "sabm_s0_empty"); + f_assert_lapdm('013F1123420815'O, tr_LAPDm_SABM(0, false, true, '23420815'O), "sabm_s0_l3"); + f_assert_lapdm('03E101'O, tr_LAPDm_RR(0, true, false, 7), "rr_s0_7"); + f_assert_lapdm('03000d063505'O, tr_LAPDm_I(0, true, false, 0, 0, '063505'O), "I/0/0"); + f_assert_lapdm('03e00d063505'O, tr_LAPDm_I(0, true, false, 7, 0, '063505'O), "I/7/0"); +} + /* test generation of RLL ERR IND based on Um errors (TS 48.058 3.9) */ /* protocol error as per 44.006 */ @@ -3434,13 +3666,11 @@ testcase TC_rll_unit_data_ind_ACCH() runs on test_CT { * channel activation ** with BS_Power / MS_Power, bypassing power control loop ** on primary vs. secondary TRX -** with encryption from initial activation on ** with timing advance from initial activation on * mode modify ** encryption ** multirate * check DEACTIVATE SACCH -* encryption command / intricate logic about tx-only/tx+rx/... ** unsupported algorithm * handover detection * MS Power Control @@ -3543,6 +3773,15 @@ control { execute( TC_rll_unit_data_req_ACCH() ); execute( TC_rll_unit_data_ind_DCCH() ); execute( TC_rll_unit_data_ind_ACCH() ); + + execute( TC_chan_act_a51() ); + execute( TC_chan_act_a52() ); + execute( TC_chan_act_a53() ); + execute( TC_encr_cmd_a51() ); + execute( TC_encr_cmd_a52() ); + execute( TC_encr_cmd_a53() ); + + execute( TC_lapdm_selftest() ); } diff --git a/library/L1CTL_PortType.ttcn b/library/L1CTL_PortType.ttcn index f8bc67035..51a39360e 100644 --- a/library/L1CTL_PortType.ttcn +++ b/library/L1CTL_PortType.ttcn @@ -4,6 +4,7 @@ module L1CTL_PortType { import from UD_PortType all; import from UD_Types all; import from Osmocom_Types all; + import from Osmocom_Types all; import from GSM_Types all; import from GSM_RR_Types all; import from L1CTL_PortType_CtrlFunct all; @@ -176,7 +177,10 @@ module L1CTL_PortType { self.stop; } } + } + function f_L1CTL_CRYPTO_REQ(L1CTL_PT pt, RslChannelNr chan_nr, uint8_t algo, octetstring key) { + pt.send(ts_L1CTL_CRYPTO_REQ(chan_nr, algo, key)); } function f_connect_reset(L1CTL_PT pt, charstring l1ctl_sock_path := m_l1ctl_sock_path) { diff --git a/library/L1CTL_Types.ttcn b/library/L1CTL_Types.ttcn index 4c0e14d6d..656f292d2 100644 --- a/library/L1CTL_Types.ttcn +++ b/library/L1CTL_Types.ttcn @@ -286,6 +286,12 @@ module L1CTL_Types { OCT3 padding } with { variant "" }; + type record L1CtlCryptoReq { + uint8_t algo, + uint8_t key_len, + octetstring key + } with { variant (key_len) "LENGTHTO(key)" }; + type record L1ctlTrafficReq { octetstring data length(TRAFFIC_DATA_LEN) @@ -311,6 +317,7 @@ module L1CTL_Types { L1ctlDmEstReq dm_est_req, L1ctlReset reset_req, //L1ctlNeighPmReq neigh_pm_req, + L1CtlCryptoReq crypto_req, L1ctlTrafficReq traffic_req, L1ctlTbfCfgReq tbf_cfg_req, octetstring other @@ -341,6 +348,7 @@ module L1CTL_Types { par_req, header.msg_type = L1CTL_PARAM_REQ; dm_est_req, header.msg_type = L1CTL_DM_EST_REQ; reset_req, header.msg_type = L1CTL_RESET_REQ; + crypto_req, header.msg_type = L1CTL_CRYPTO_REQ; traffic_req, header.msg_type = L1CTL_TRAFFIC_REQ; tbf_cfg_req, header.msg_type = L1CTL_TBF_CFG_REQ; other, OTHERWISE; @@ -631,6 +639,25 @@ module L1CTL_Types { } }; + template (value) L1ctlUlMessage ts_L1CTL_CRYPTO_REQ(RslChannelNr chan_nr, uint8_t algo, + octetstring key) := { + header := ts_L1ctlHeader(L1CTL_CRYPTO_REQ), + ul_info := { + chan_nr := chan_nr, + link_id := ts_RslLinkID_DCCH(0), + padding := '0000'O + }, + ul_info_tbf := omit, + ul_info_abs := omit, + payload := { + crypto_req := { + algo := algo, + key_len := 0, /* overwritten */ + key := key + } + } + }; + template ImmediateAssignment t_IMM_ASS(uint8_t ra, GsmFrameNumber fn) := { ded_or_tbf := ?, page_mode := ?, diff --git a/library/L3_Templates.ttcn b/library/L3_Templates.ttcn index 330466223..5acd2bf3a 100644 --- a/library/L3_Templates.ttcn +++ b/library/L3_Templates.ttcn @@ -388,6 +388,28 @@ template (value) PDU_ML3_MS_NW ts_RRM_ModeModifyAck(ChannelDescription2_V desc, } } +template (value) PDU_ML3_NW_MS ts_RRM_CiphModeCmd(BIT3 alg_id) := { + discriminator := '0000'B, /* overwritten */ + tiOrSkip := { + skipIndicator := '0000'B + }, + msgs := { + rrm := { + cipheringModeCommand := { + messageType := '00110101'B, + cipherModeSetting := { + sC := '1'B, + algorithmIdentifier := alg_id + }, + cipherModeResponse := { + cR := '0'B, + spare := '000'B + } + } + } + } +} + template (value) PDU_ML3_MS_NW ts_RRM_CiphModeCompl := { discriminator := '0000'B, /* overwritten */ tiOrSkip := { diff --git a/library/LAPDm_Types.ttcn b/library/LAPDm_Types.ttcn index 2e008e5b0..32e1ba6ec 100644 --- a/library/LAPDm_Types.ttcn +++ b/library/LAPDm_Types.ttcn @@ -275,10 +275,10 @@ module LAPDm_Types { } } - template LapdmFrame ts_LAPDm_UI(LapdmSapi sapi, boolean c_r, boolean p, octetstring l3) := { + template LapdmFrame ts_LAPDm_UI(LapdmSapi sapi, boolean c_r, octetstring l3) := { ab := { addr := ts_LapdmAddr(sapi, c_r), - ctrl := ts_LapdmCtrlUI(p), + ctrl := ts_LapdmCtrlUI, len := 0, m := false, el := 1, @@ -286,10 +286,10 @@ module LAPDm_Types { } } template LapdmFrame tr_LAPDm_UI(template LapdmSapi sapi, template boolean c_r, - template boolean p, template octetstring l3) := { + template octetstring l3) := { ab := { addr := tr_LapdmAddr(sapi, c_r), - ctrl := tr_LapdmCtrlUI(p), + ctrl := tr_LapdmCtrlUI, len := ?, m := false, el := 1, @@ -297,22 +297,69 @@ module LAPDm_Types { } } - template LapdmFrame ts_LAPDm_B4_UI(LapdmSapi sapi, boolean c_r, boolean p, octetstring l3) := { + template LapdmFrame ts_LAPDm_B4_UI(LapdmSapi sapi, boolean c_r, octetstring l3) := { b4 := { addr := ts_LapdmAddr(sapi, c_r), - ctrl := ts_LapdmCtrlUI(p), + ctrl := ts_LapdmCtrlUI, payload := l3 } } template LapdmFrame tr_LAPDm_B4_UI(template LapdmSapi sapi, template boolean c_r, - template boolean p, template octetstring l3) := { + template octetstring l3) := { b4 := { addr := tr_LapdmAddr(sapi, c_r), - ctrl := tr_LapdmCtrlUI(p), + ctrl := tr_LapdmCtrlUI, payload := l3 } } + template LapdmFrame tr_LAPDm_I(template LapdmSapi sapi, template boolean c_r, + template boolean p, template uint3_t nr, + template uint3_t ns, template octetstring l3) := { + ab := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlI(nr, ns, p), + len := ?, + m := false, + el := 1, + payload := l3 + } + } + template (value) LapdmFrame ts_LAPDm_I(LapdmSapi sapi, boolean c_r, boolean p, uint3_t nr, + uint3_t ns, octetstring l3) := { + ab := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlI(nr, ns, p), + len := 0, + m := false, + el := 1, + payload := l3 + } + } + + template LapdmFrame tr_LAPDm_RR(template LapdmSapi sapi, template boolean c_r, + template boolean p, template uint3_t nr) := { + ab := { + addr := tr_LapdmAddr(sapi, c_r), + ctrl := tr_LapdmCtrlRR(nr, p), + len := 0, + m := false, + el := 1, + payload := ''O + } + } + template (value) LapdmFrame ts_LAPDm_RR(LapdmSapi sapi, boolean c_r, + boolean p, uint3_t nr) := { + ab := { + addr := ts_LapdmAddr(sapi, c_r), + ctrl := ts_LapdmCtrlRR(nr, p), + len := 0, + m := false, + el := 1, + payload := ''O + } + } + } with { encode "RAW"; /*variant "FIELDORDER(msb)" */} diff --git a/library/RSL_Types.ttcn b/library/RSL_Types.ttcn index 2d9c92ecc..b81bbbd94 100644 --- a/library/RSL_Types.ttcn +++ b/library/RSL_Types.ttcn @@ -364,18 +364,30 @@ module RSL_Types { } /* 9.3.7 */ + type enumerated RSL_AlgId { + RSL_ALG_ID_A5_0 ('00000001'B), + RSL_ALG_ID_A5_1 ('00000010'B), + RSL_ALG_ID_A5_2 ('00000011'B), + RSL_ALG_ID_A5_3 ('00000100'B), + RSL_ALG_ID_A5_4 ('00000101'B), + RSL_ALG_ID_A5_5 ('00000110'B), + RSL_ALG_ID_A5_6 ('00000111'B), + RSL_ALG_ID_A5_7 ('00001000'B) + } with { variant "FIELDLENGTH(8)" }; type record RSL_IE_EncryptionInfo { uint8_t len, - OCT1 alg_id, + RSL_AlgId alg_id, octetstring key } with { variant (len) "LENGTHTO(alg_id,key)" }; - template RSL_IE_EncryptionInfo tr_RSL_IE_EncrInfo(template OCT1 alg, template octetstring key) := { + template RSL_IE_EncryptionInfo tr_RSL_IE_EncrInfo(template RSL_AlgId alg, + template octetstring key) := { len := ?, alg_id := alg, key := key } - template (value) RSL_IE_EncryptionInfo ts_RSL_IE_EncrInfo(OCT1 alg, octetstring key) := { + template (value) RSL_IE_EncryptionInfo ts_RSL_IE_EncrInfo(template (value) RSL_AlgId alg, + octetstring key) := { len := 0, /* overwritten */ alg_id := alg, key := key @@ -1154,7 +1166,7 @@ template RSL_Message tr_RSL_MsgTypeDR(template RSL_MessageType msg_type) modifie /* 8.4.6 BSC ->BTS */ template RSL_Message tr_RSL_ENCR_CMD(template RslChannelNr chan_nr, template RslLinkId link_id := ?, - template OCT1 alg := ?, + template RSL_AlgId alg := ?, template octetstring key := ?, template octetstring l3_info := ?) := { msg_disc := tr_RSL_MsgDisc(RSL_MDISC_DCHAN, false), @@ -1168,7 +1180,7 @@ template RSL_Message tr_RSL_MsgTypeDR(template RSL_MessageType msg_type) modifie } template (value) RSL_Message ts_RSL_ENCR_CMD(template (value) RslChannelNr chan_nr, template (value) RslLinkId link_id, - OCT1 alg, octetstring key, + template (value) RSL_AlgId alg, octetstring key, octetstring l3_info) := { msg_disc := ts_RSL_MsgDisc(RSL_MDISC_DCHAN, false), msg_type := RSL_MT_ENCR_CMD,