blob: d615497663c5a8eb88f6a43c269f9acd9d64760e [file] [log] [blame]
Harald Welte28d943e2017-11-25 15:00:50 +01001module MSC_ConnectionHandler {
2
3import from General_Types all;
4import from Osmocom_Types all;
Harald Weltec1a2fff2017-12-17 11:06:19 +01005import from GSM_Types all;
Harald Welte28d943e2017-11-25 15:00:50 +01006import from SCCPasp_Types all;
7import from BSSAP_Types all;
8import from BSSMAP_Emulation all;
9import from BSSMAP_Templates all;
10
11import from MGCP_Types all;
12import from MGCP_Templates all;
13import from SDP_Types all;
14
Harald Weltec1a2fff2017-12-17 11:06:19 +010015import from RSL_Emulation all;
16import from RSL_Types all;
17
18import from MobileL3_Types all;
19import from MobileL3_CommonIE_Types all;
20//import from MobileL3_RRM_Types all;
21import from L3_Templates all;
22
23
Harald Welte28d943e2017-11-25 15:00:50 +010024/* this component represents a single subscriber connection at the MSC.
25 * There is a 1:1 mapping between SCCP connections and BSSAP_ConnHdlr components.
26 * We inherit all component variables, ports, functions, ... from BSSAP_ConnHdlr */
Harald Weltec1a2fff2017-12-17 11:06:19 +010027type component MSC_ConnHdlr extends BSSAP_ConnHdlr, RSL_DchanHdlr {
Harald Welte28d943e2017-11-25 15:00:50 +010028 /* SCCP Connecction Identifier for the underlying SCCP connection */
29 var integer g_sccp_conn_id;
30
Harald Weltec1a2fff2017-12-17 11:06:19 +010031 /* procedure port back to our parent (BSSMAP_Emulation_CT) for control */
32 port BSSMAPEM_PROC_PT BSSMAPEM;
Harald Welte28d943e2017-11-25 15:00:50 +010033
Harald Weltec1a2fff2017-12-17 11:06:19 +010034 var MSC_State g_state := MSC_STATE_NONE;
Harald Welte28d943e2017-11-25 15:00:50 +010035}
36
37/* Callback function from general BSSMAP_Emulation whenever a connectionless
38 * BSSMAP message arrives. Can retunr a PDU_BSSAP that should be sent in return */
39private function UnitdataCallback(PDU_BSSAP bssap)
40runs on BSSMAP_Emulation_CT return template PDU_BSSAP {
41 var template PDU_BSSAP resp := omit;
42
Harald Weltec1a2fff2017-12-17 11:06:19 +010043 /* answer all RESET with a RESET ACK */
Harald Welte28d943e2017-11-25 15:00:50 +010044 if (match(bssap, tr_BSSMAP_Reset)) {
45 resp := ts_BSSMAP_ResetAck;
46 }
47
48 return resp;
49}
50
51const BssmapOps MSC_BssmapOps := {
Harald Weltec1a2fff2017-12-17 11:06:19 +010052 create_cb := refers(BSSMAP_Emulation.ExpectedCreateCallback),
Harald Welte28d943e2017-11-25 15:00:50 +010053 unitdata_cb := refers(UnitdataCallback)
54}
55
56type enumerated MSC_State {
57 MSC_STATE_NONE,
58 MSC_STATE_WAIT_ASS_COMPL,
59 MSC_STATE_WAIT_CRCX_ACK,
60 MSC_STATE_WAIT_MDCX_ACK,
61 MSC_STATE_WAIT_CLEAR_COMPL,
62 MSC_STATE_WAIT_DLCX_ACK
63}
64
Harald Weltec1a2fff2017-12-17 11:06:19 +010065/* register an expect with the BSSMAP core */
66private function f_create_exp(octetstring l3_enc) runs on MSC_ConnHdlr {
67 BSSMAPEM.call(BSSMAPEM_register:{l3_enc, self}) {
68 [] BSSMAPEM.getreply(BSSMAPEM_register:{?, ?}) {};
Harald Welte28d943e2017-11-25 15:00:50 +010069 }
70}
71
Harald Weltec1a2fff2017-12-17 11:06:19 +010072type record TestHdlrParams {
73 OCT1 ra,
74 GsmFrameNumber fn,
75 hexstring imsi,
76 RslLinkId link_id
77};
78
79template (value) TestHdlrParams t_def_TestHdlrPars := {
80 ra := '23'O,
81 fn := 23,
82 imsi := '001019876543210'H,
83 link_id := valueof(ts_RslLinkID_DCCH(0))
84}
85
86function f_create_chan_and_exp(TestHdlrParams pars) runs on MSC_ConnHdlr {
87 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(pars.imsi));
88 var PDU_ML3_MS_NW l3_info := valueof(ts_CM_SERV_REQ('0001'B, mi));
89 var octetstring l3_enc := enc_PDU_ML3_MS_NW(l3_info);
90
91 /* call helper function for CHAN_RQD -> IMM ASS ->EST_IND */
92 RSL_Emulation.f_chan_est(pars.ra, l3_enc, pars.link_id, pars.fn);
93 f_create_exp(l3_enc);
94}
95
96function f_rsl_reply(template PDU_ML3_MS_NW l3, RSL_Message orig) runs on MSC_ConnHdlr {
97 var RslChannelNr chan_nr := orig.ies[0].body.chan_nr;
98 var RslLinkId link_id := orig.ies[1].body.link_id;
99 RSL.send(ts_RSL_DATA_IND(chan_nr, link_id, enc_PDU_ML3_MS_NW(valueof(l3))));
100}
101
102/* establish a channel fully, expecting an assignment matching 'exp' */
103function f_establish_fully(TestHdlrParams pars, PDU_BSSAP ass_cmd, template PDU_BSSAP exp_ass_cpl)
104runs on MSC_ConnHdlr return PDU_BSSAP {
105 var PDU_BSSAP bssap;
106 var RSL_Message rsl;
107 timer T := 10.0;
108 var boolean exp_compl := ischosen(exp_ass_cpl.pdu.bssmap.assignmentComplete);
Harald Welte82d2b872017-12-16 23:36:23 +0100109 var boolean crcx_seen := false;
110 var boolean rr_modify_seen := false;
Harald Weltec1a2fff2017-12-17 11:06:19 +0100111
112 f_create_chan_and_exp(pars);
113 /* we should now have a COMPL_L3 at the MSC */
114
115 BSSAP.receive(tr_BSSMAP_ComplL3);
116 BSSAP.send(ass_cmd);
117 alt {
118 /* if we receive exactly what we expected, always return + pass */
119 [] BSSAP.receive(exp_ass_cpl) -> value bssap {
120 setverdict(pass);
121 return bssap;
122 }
Harald Welte82d2b872017-12-16 23:36:23 +0100123 [rr_modify_seen == false] RSL.receive(tr_RSL_DATA_REQ(g_chan_nr)) -> value rsl {
Harald Weltec1a2fff2017-12-17 11:06:19 +0100124 var PDU_ML3_NW_MS l3 := dec_PDU_ML3_NW_MS(rsl.ies[2].body.l3_info.payload);
125 log("Rx L3 from net: ", l3);
126 if (ischosen(l3.msgs.rrm.channelModeModify)) {
127 f_rsl_reply(ts_RRM_ModeModifyAck(l3.msgs.rrm.channelModeModify.channelDescription,
128 l3.msgs.rrm.channelModeModify.channelMode), rsl);
Harald Welte82d2b872017-12-16 23:36:23 +0100129 rr_modify_seen := true;
Harald Weltec1a2fff2017-12-17 11:06:19 +0100130 }
131 repeat;
132 }
Harald Welte82d2b872017-12-16 23:36:23 +0100133 [rr_modify_seen] RSL.receive(tr_RSL_MsgTypeD(RSL_MT_MODE_MODIFY_REQ)) -> value rsl {
Harald Weltec1a2fff2017-12-17 11:06:19 +0100134 RSL.send(ts_RSL_MODE_MODIFY_ACK(g_chan_nr));
135 repeat;
136 }
Harald Welte82d2b872017-12-16 23:36:23 +0100137 [crcx_seen == false] RSL.receive(tr_RSL_IPA_CRCX(g_chan_nr)) -> value rsl {
Harald Weltec1a2fff2017-12-17 11:06:19 +0100138 RSL.send(ts_RSL_IPA_CRCX_ACK(g_chan_nr, 1, 1, 1, 1));
Harald Welte82d2b872017-12-16 23:36:23 +0100139 crcx_seen := true;
Harald Weltec1a2fff2017-12-17 11:06:19 +0100140 repeat;
141 }
Harald Welte82d2b872017-12-16 23:36:23 +0100142 [crcx_seen] RSL.receive(tr_RSL_IPA_MDCX(g_chan_nr, ?)) -> value rsl{
Harald Weltec1a2fff2017-12-17 11:06:19 +0100143 RSL.send(ts_RSL_IPA_MDCX_ACK(g_chan_nr, 1, 1, 1, 1));
144 repeat;
145 }
146 [exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentComplete) {
147 setverdict(fail, "Received non-matching ASSIGNMENT COMPLETE");
148 }
149 [exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentFail) {
150 setverdict(fail, "Received unexpected ASSIGNMENT FAIL");
151 }
152 [not exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentComplete) {
153 setverdict(fail, "Received unexpected ASSIGNMENT COMPLETE");
154 }
155 [not exp_compl] BSSAP.receive(tr_BSSMAP_AssignmentFail) {
156 setverdict(fail, "Received non-matching ASSIGNMENT FAIL");
157 }
158 [] T.timeout {
159 setverdict(inconc, "Timeout waiting for ASSIGNMENT COMPLETE");
160 }
161 }
162
163 self.stop;
164}
165
166
Harald Welte28d943e2017-11-25 15:00:50 +0100167}