blob: f9f4db0edc88259b96fe2953bf0a1e175fcec7e4 [file] [log] [blame]
Harald Welteb3414b22017-11-23 18:22:10 +01001module BSC_MS_ConnectionHandler {
2
Harald Welte34b5a952019-05-27 11:54:11 +02003/* (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
4 * All rights reserved.
5 *
6 * Released under the terms of GNU General Public License, Version 2 or
7 * (at your option) any later version.
8 *
9 * SPDX-License-Identifier: GPL-2.0-or-later
10 */
11
Harald Welteb3414b22017-11-23 18:22:10 +010012import from General_Types all;
13import from Osmocom_Types all;
14import from SCCPasp_Types all;
15import from BSSAP_Types all;
Harald Welte004f5fb2017-12-16 17:54:40 +010016import from BSSAP_CodecPort all;
Harald Welte6811d102019-04-14 22:23:14 +020017import from RAN_Emulation all;
Harald Welteb3414b22017-11-23 18:22:10 +010018import from BSSMAP_Templates all;
19
20import from MobileL3_Types all;
21import from MobileL3_CommonIE_Types all;
22import from L3_Templates all;
23
Harald Weltec859df52017-11-24 23:41:41 +010024import from MGCP_Types all;
25import from MGCP_Templates all;
26import from SDP_Types all;
27
Harald Welteb3414b22017-11-23 18:22:10 +010028/* this component represents a single subscriber connection at the MSC.
Harald Welte6811d102019-04-14 22:23:14 +020029 * There is a 1:1 mapping between SCCP connections and RAN_ConnHdlr components.
30 * We inherit all component variables, ports, functions, ... from RAN_ConnHdlr */
31type component BSC_MS_ConnHdlr extends RAN_ConnHdlr {
Harald Welteb3414b22017-11-23 18:22:10 +010032 /* SCCP Connecction Identifier for the underlying SCCP connection */
33 var integer g_sccp_conn_id;
Harald Weltec859df52017-11-24 23:41:41 +010034 var MgcpConnectionId g_mgcp_conn_id;
35 var SDP_Message g_sdp;
Harald Weltea34e47f2017-11-25 01:28:54 +010036 var BSC_State g_state;
Harald Welteb3414b22017-11-23 18:22:10 +010037}
38
Harald Welte6811d102019-04-14 22:23:14 +020039/* Callback function from general RAN_Emulation whenever a new incoming
Harald Welteb3414b22017-11-23 18:22:10 +010040 * SCCP connection arrivces. Must create + start a new component */
Harald Welte004f5fb2017-12-16 17:54:40 +010041private function CreateCallback(BSSAP_N_CONNECT_ind conn_ind, charstring id)
Harald Welte6811d102019-04-14 22:23:14 +020042runs on RAN_Emulation_CT return RAN_ConnHdlr {
Harald Welteb3414b22017-11-23 18:22:10 +010043 log("Incoming SCCP Connection on BSC ?!?");
44 self.stop;
45}
46
Harald Welte6811d102019-04-14 22:23:14 +020047/* Callback function from general RAN_Emulation whenever a connectionless
Harald Welteb3414b22017-11-23 18:22:10 +010048 * BSSMAP message arrives. Can retunr a PDU_BSSAP that should be sent in return */
49private function UnitdataCallback(PDU_BSSAP bssap)
Harald Welte6811d102019-04-14 22:23:14 +020050runs on RAN_Emulation_CT return template PDU_BSSAP {
Harald Welteb3414b22017-11-23 18:22:10 +010051 var template PDU_BSSAP resp := omit;
52
53 if (match(bssap, tr_BSSMAP_Reset)) {
54 resp := ts_BSSMAP_ResetAck;
55 }
56
57 return resp;
58}
59
Harald Welte6811d102019-04-14 22:23:14 +020060const RanOps BSC_MS_RanOps := {
Harald Welteb3414b22017-11-23 18:22:10 +010061 create_cb := refers(CreateCallback),
Harald Welte0b476062018-01-21 19:07:32 +010062 unitdata_cb := refers(UnitdataCallback),
63 decode_dtap := false,
Daniel Willmannaa170592018-10-24 18:33:10 +020064 role_ms := true,
Harald Welte2fce7882019-04-15 11:48:05 +020065 protocol := RAN_PROTOCOL_BSSAP,
Pau Espin Pedrolf3c12222019-05-22 15:18:42 +020066 /* Always false. We don't want to enable Osmux signalling in SCCPLite messages: */
Pau Espin Pedrolc6a53db2019-05-20 19:31:47 +020067 use_osmux := false,
Daniel Willmannaa170592018-10-24 18:33:10 +020068 sccp_addr_local := omit,
69 sccp_addr_peer := omit
Harald Welteb3414b22017-11-23 18:22:10 +010070}
71
72
73function f_gen_cl3(hexstring imsi) return PDU_BSSAP {
74 var MobileIdentityLV mi := valueof(ts_MI_IMSI_LV(imsi));
Harald Welte6ed6bf92018-01-24 21:09:15 +010075 var PDU_ML3_MS_NW l3 := valueof(ts_CM_SERV_REQ(CM_TYPE_MO_CALL, mi));
Harald Welteb3414b22017-11-23 18:22:10 +010076 var BSSMAP_IE_CellIdentifier cell_id := valueof(ts_CellID_LAC_CI(23, 42));
77 var PDU_BSSAP bssap := valueof(ts_BSSMAP_ComplL3(cell_id, enc_PDU_ML3_MS_NW(l3)));
78 return bssap;
79}
80
Harald Weltea34e47f2017-11-25 01:28:54 +010081type enumerated BSC_State {
82 BSC_STATE_NONE,
83 BSC_STATE_WAIT_ASS_REQ,
84 BSC_STATE_WAIT_CRCX,
85 BSC_STATE_WAIT_MDCX,
Daniel Willmann04541d72017-11-30 13:14:37 +010086 BSC_STATE_WAIT_MDCX2,
Harald Weltea34e47f2017-11-25 01:28:54 +010087 BSC_STATE_WAIT_CLEAR_CMD,
88 BSC_STATE_WAIT_DLCX,
89 BSC_STATE_WAIT_DISC_IND
90}
91
Harald Welteb3414b22017-11-23 18:22:10 +010092/* main function processing various incoming events */
Pau Espin Pedrolf3c12222019-05-22 15:18:42 +020093function main(SCCP_PAR_Address sccp_addr_own, SCCP_PAR_Address sccp_addr_remote, boolean use_osmux)
Harald Welteb3414b22017-11-23 18:22:10 +010094runs on BSC_MS_ConnHdlr {
95 var PDU_BSSAP bssap;
Harald Weltec859df52017-11-24 23:41:41 +010096 var MgcpCommand mgcp_cmd;
Pau Espin Pedrolf3c12222019-05-22 15:18:42 +020097 var template MgcpResponse mgcp_resp;
98 var MgcpOsmuxCID osmux_cid;
Harald Welteb3414b22017-11-23 18:22:10 +010099
100 log("Starting main of BSC_MS_ConnHdlr");
101
Harald Weltec859df52017-11-24 23:41:41 +0100102 g_mgcp_conn_id := f_mgcp_alloc_conn_id();
103
Harald Welteb3414b22017-11-23 18:22:10 +0100104 /* generate and send the Complete Layer3 Info */
105 bssap := f_gen_cl3('901770123456789'H);
Harald Welteb3414b22017-11-23 18:22:10 +0100106 var BSSAP_Conn_Req creq := {
107 addr_peer := sccp_addr_remote,
108 addr_own := sccp_addr_own,
109 bssap := bssap
110 }
Harald Weltea34e47f2017-11-25 01:28:54 +0100111 g_state := BSC_STATE_WAIT_ASS_REQ;
Harald Welteb3414b22017-11-23 18:22:10 +0100112 BSSAP.send(creq);
113
114 while (true) {
115 alt {
116 /* new SCCP-level connection indication from BSC */
Harald Weltea34e47f2017-11-25 01:28:54 +0100117 [g_state == BSC_STATE_WAIT_ASS_REQ] BSSAP.receive(tr_BSSMAP_AssignmentReq) -> value bssap {
Harald Welte8f3a9622017-11-25 01:19:13 +0100118 /* FIXME: Read CIC */
Harald Welteb3414b22017-11-23 18:22:10 +0100119 /* respond with ASSIGNMENT COMPL */
Harald Weltea34e47f2017-11-25 01:28:54 +0100120 g_state := BSC_STATE_WAIT_CRCX;
Harald Welteb3414b22017-11-23 18:22:10 +0100121 BSSAP.send(ts_BSSMAP_AssignmentComplete(bssap.pdu.bssmap.assignmentRequest.circuitIdentityCode));
122 }
Harald Weltec859df52017-11-24 23:41:41 +0100123
124 /* CRCX -> OK */
Harald Weltea34e47f2017-11-25 01:28:54 +0100125 [g_state == BSC_STATE_WAIT_CRCX] BSSAP.receive(tr_CRCX) -> value mgcp_cmd {
Harald Welte8f3a9622017-11-25 01:19:13 +0100126 /* FIXME: proper SDP parameters */
Harald Weltec859df52017-11-24 23:41:41 +0100127 g_sdp := valueof(ts_SDP("127.0.0.1", "127.0.0.1", "foo", "21", 1000, { "98" },
128 { valueof(ts_SDP_rtpmap(98, "AMR/8000")),
129 valueof(ts_SDP_ptime(20)) }));
130 /* respond with CRCX_ACK */
Harald Weltea34e47f2017-11-25 01:28:54 +0100131 g_state := BSC_STATE_WAIT_MDCX;
Pau Espin Pedrolf3c12222019-05-22 15:18:42 +0200132
133 if (use_osmux != f_MgcpCmd_contains_par(mgcp_cmd, "X-OSMUX")) {
134 setverdict(fail, log2str("Received Osmux CID presence doesn't match presence expectancy (", use_osmux, ")"));
135 self.stop;
136 }
137
138 if (use_osmux) {
139 osmux_cid := f_MgcpCmd_extract_osmux_cid(mgcp_cmd);
140 mgcp_resp := ts_CRCX_ACK_osmux(mgcp_cmd.line.trans_id, g_mgcp_conn_id, osmux_cid, g_sdp);
141 } else {
142 mgcp_resp := ts_CRCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp);
143 }
144 BSSAP.send(valueof(mgcp_resp));
Harald Weltec859df52017-11-24 23:41:41 +0100145 }
146
147 /* MDCX -> OK */
Harald Weltea34e47f2017-11-25 01:28:54 +0100148 [g_state == BSC_STATE_WAIT_MDCX] BSSAP.receive(tr_MDCX) -> value mgcp_cmd {
Harald Welte8f3a9622017-11-25 01:19:13 +0100149 /* FIXME: verify if local part of endpoint name matches CIC */
Daniel Willmann04541d72017-11-30 13:14:37 +0100150 /* respond with MDCX_ACK */
151 g_state := BSC_STATE_WAIT_MDCX2;
152 BSSAP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp));
153 }
154
155 /* MDCX -> OK */
156 [g_state == BSC_STATE_WAIT_MDCX2] BSSAP.receive(tr_MDCX) -> value mgcp_cmd {
157 /* FIXME: verify if local part of endpoint name matches CIC */
158 /* respond with MDCX_ACK */
Harald Weltea34e47f2017-11-25 01:28:54 +0100159 g_state := BSC_STATE_WAIT_CLEAR_CMD;
Harald Weltec859df52017-11-24 23:41:41 +0100160 BSSAP.send(ts_MDCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id, g_sdp));
161 }
162
Harald Welteb3414b22017-11-23 18:22:10 +0100163 /* CLEAR COMMAND from MSC; respond with CLEAR COMPLETE) */
Harald Weltea34e47f2017-11-25 01:28:54 +0100164 [g_state == BSC_STATE_WAIT_CLEAR_CMD] BSSAP.receive(tr_BSSMAP_ClearCommand) -> value bssap {
165 g_state := BSC_STATE_WAIT_DLCX;
Harald Welteb3414b22017-11-23 18:22:10 +0100166 BSSAP.send(ts_BSSMAP_ClearComplete);
Harald Welteb3414b22017-11-23 18:22:10 +0100167 }
168
Harald Weltec859df52017-11-24 23:41:41 +0100169 /* DLCX -> OK */
Harald Weltea34e47f2017-11-25 01:28:54 +0100170 [g_state == BSC_STATE_WAIT_DLCX] BSSAP.receive(tr_DLCX) -> value mgcp_cmd {
Harald Welte8f3a9622017-11-25 01:19:13 +0100171 /* FIXME: verify if local part of endpoint name matches CIC */
Harald Weltea34e47f2017-11-25 01:28:54 +0100172 g_state := BSC_STATE_WAIT_DISC_IND;
Harald Weltec859df52017-11-24 23:41:41 +0100173 BSSAP.send(ts_DLCX_ACK(mgcp_cmd.line.trans_id, g_mgcp_conn_id));
174 }
175
Harald Welteb3414b22017-11-23 18:22:10 +0100176 [] BSSAP.receive(tr_BSSAP_DTAP) -> value bssap {
Harald Welte8f3a9622017-11-25 01:19:13 +0100177 /* FIXME: verify if local part of endpoint name matches CIC */
Harald Welteb3414b22017-11-23 18:22:10 +0100178 var PDU_ML3_MS_NW l3 := dec_PDU_ML3_MS_NW(bssap.pdu.dtap);
179 log("Unhandled DTAP ", l3);
180 }
181
Harald Welte6811d102019-04-14 22:23:14 +0200182 [g_state == BSC_STATE_WAIT_DISC_IND] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
Harald Welte0a4317a2017-11-25 00:32:46 +0100183 setverdict(pass);
Harald Welteb3414b22017-11-23 18:22:10 +0100184 self.stop;
185 }
186
Harald Welte6811d102019-04-14 22:23:14 +0200187 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_CONF_IND) {
Daniel Willmannaa170592018-10-24 18:33:10 +0200188 }
189
Harald Weltea34e47f2017-11-25 01:28:54 +0100190 /* disconnect in invalid state */
Harald Welte6811d102019-04-14 22:23:14 +0200191 [] BSSAP.receive(RAN_Conn_Prim:MSC_CONN_PRIM_DISC_IND) {
Harald Weltea34e47f2017-11-25 01:28:54 +0100192 setverdict(fail);
193 self.stop;
194 }
195
196
Harald Welteb3414b22017-11-23 18:22:10 +0100197 [] BSSAP.receive(PDU_BSSAP:?) -> value bssap {
198 log("Received unhandled SCCP-CO: ", bssap);
199 }
200 }
201 }
202}
203
204}