blob: f1ff5b6b998b3398674fe80ad2fa9b0850718fec [file] [log] [blame]
Harald Welteae026692017-12-09 01:03:01 +01001module BSSAP_Adapter {
Harald Welte28d943e2017-11-25 15:00:50 +01002
Harald Welteae026692017-12-09 01:03:01 +01003/* This module implements a 'dumb' BSSAP adapter. It creates the M3UA and SCCP components and stacks a BSSAP
4 * codec port on top. As a result, it provides the ability to transceive SCCP-User-SAP primitives with
5 * deoded BSSAP payload. Use this if you want to have full control about what you transmit or receive,
6 * without any automatisms in place. Allows you to refuse connections or other abnormal behavior. */
Harald Welte28d943e2017-11-25 15:00:50 +01007
Harald Welteae026692017-12-09 01:03:01 +01008import from General_Types all;
9import from Osmocom_Types all;
10
11import from M3UA_Types all;
12import from M3UA_Emulation all;
13import from MTP3asp_Types all;
14import from MTP3asp_PortType all;
Harald Welte28d943e2017-11-25 15:00:50 +010015
16import from SCCP_Types all;
17import from SCCPasp_Types all;
18import from SCCP_Emulation all;
19
Harald Welteae026692017-12-09 01:03:01 +010020import from SCTPasp_Types all;
21import from SCTPasp_PortType all;
Harald Welte28d943e2017-11-25 15:00:50 +010022
Harald Welteae026692017-12-09 01:03:01 +010023import from BSSAP_CodecPort all;
Harald Welte28d943e2017-11-25 15:00:50 +010024import from BSSMAP_Templates all;
Harald Welte624f9632017-12-16 19:26:04 +010025import from BSSMAP_Emulation all;
26
27import from MSC_ConnectionHandler all;
Harald Welte28d943e2017-11-25 15:00:50 +010028
Harald Welteae026692017-12-09 01:03:01 +010029type component BSSAP_Adapter_CT {
Harald Welte28d943e2017-11-25 15:00:50 +010030 /* component references */
Harald Welteae026692017-12-09 01:03:01 +010031 var M3UA_CT vc_M3UA;
Harald Welte28d943e2017-11-25 15:00:50 +010032 var SCCP_CT vc_SCCP;
Harald Welte28d943e2017-11-25 15:00:50 +010033 /* test port to SCCP emulation */
Harald Welteae026692017-12-09 01:03:01 +010034 port BSSAP_CODEC_PT BSSAP;
35
36 var octetstring g_sio;
37 var MSC_SCCP_MTP3_parameters g_sccp_pars;
38 var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer;
Harald Welte624f9632017-12-16 19:26:04 +010039
40 /* handler mode */
41 var BSSMAP_Emulation_CT vc_BSSMAP;
Harald Welte28d943e2017-11-25 15:00:50 +010042}
43
44modulepar {
Harald Welteae026692017-12-09 01:03:01 +010045 charstring mp_sccp_service_type := "mtp3_itu";
46
47 SCTP_Association_Address mp_sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" };
48 integer mp_own_pc := 185; /* 0.23.1 */
49 integer mp_own_ssn := 254;
50
51 integer mp_peer_pc := 187;
52 integer mp_peer_ssn := 254;
Harald Welte28d943e2017-11-25 15:00:50 +010053}
54
Harald Welteae026692017-12-09 01:03:01 +010055/* construct a SCCP_PAR_Address with just PC + SSN and no GT */
56template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn) := {
57 addressIndicator := {
58 pointCodeIndic := '1'B,
59 ssnIndicator := '1'B,
60 globalTitleIndic := '0000'B,
61 routingIndicator := '1'B
62 },
63 signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O),
64 //signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio),
65 subsystemNumber := ssn,
66 globalTitle := omit
67}
68
69private function init_pars() runs on BSSAP_Adapter_CT {
70 g_sio := '83'O;
71 g_sccp_pars := {
72 sio := {
73 ni := substr(oct2bit(g_sio),0,2),
74 prio := substr(oct2bit(g_sio),2,2),
75 si := substr(oct2bit(g_sio),4,4)
76 },
77 opc := mp_own_pc,
78 dpc := mp_peer_pc,
79 sls := 0,
80 sccp_serviceType := mp_sccp_service_type,
81 ssn := mp_own_ssn
82 };
83 g_sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(mp_own_pc, mp_own_ssn));
84 g_sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(mp_peer_pc, mp_peer_ssn));
85}
86
87
Harald Welte624f9632017-12-16 19:26:04 +010088function f_bssap_init(charstring id, boolean handler_mode := false) runs on BSSAP_Adapter_CT
Harald Welte28d943e2017-11-25 15:00:50 +010089{
Harald Welteae026692017-12-09 01:03:01 +010090 init_pars();
91
Harald Welte28d943e2017-11-25 15:00:50 +010092 /* create components */
Harald Welteae026692017-12-09 01:03:01 +010093 vc_M3UA := M3UA_CT.create(id & "-M3UA");
Harald Welte28d943e2017-11-25 15:00:50 +010094 vc_SCCP := SCCP_CT.create(id & "-SCCP");
Harald Welte624f9632017-12-16 19:26:04 +010095 if (handler_mode) {
96 vc_BSSMAP := BSSMAP_Emulation_CT.create(id & "-BSSMAP");
97 }
Harald Welte28d943e2017-11-25 15:00:50 +010098
Harald Welteae026692017-12-09 01:03:01 +010099 map(vc_M3UA:SCTP_PORT, system:sctp);
Harald Welte28d943e2017-11-25 15:00:50 +0100100
Harald Welteae026692017-12-09 01:03:01 +0100101 /* connect MTP3 service provider (M3UA) to lower side of SCCP */
102 connect(vc_M3UA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT);
Harald Welte624f9632017-12-16 19:26:04 +0100103 if (handler_mode) {
104 connect(vc_BSSMAP:BSSAP, vc_SCCP:SCCP_SP_PORT);
105 } else {
106 /* connect BSSNAP dispatcher to upper side of SCCP */
107 connect(self:BSSAP, vc_SCCP:SCCP_SP_PORT);
108 }
Harald Welte28d943e2017-11-25 15:00:50 +0100109
Harald Welteae026692017-12-09 01:03:01 +0100110 vc_M3UA.start(f_M3UA_Emulation(mp_sctp_addr));
111 vc_SCCP.start(SCCPStart(g_sccp_pars));
Harald Welte624f9632017-12-16 19:26:04 +0100112 if (handler_mode) {
113 vc_BSSMAP.start(BSSMAP_Emulation.main(MSC_BssmapOps, ""));
114 }
Harald Welteae026692017-12-09 01:03:01 +0100115}
Harald Welte28d943e2017-11-25 15:00:50 +0100116
Harald Welteae026692017-12-09 01:03:01 +0100117private altstep as_reset_ack() runs on BSSAP_Adapter_CT {
118 var BSSAP_N_UNITDATA_ind ud_ind;
119 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
120 log("Respoding to inbound RESET with RESET-ACK");
121 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
122 ts_BSSMAP_ResetAck));
Harald Welte28d943e2017-11-25 15:00:50 +0100123 }
124}
125
Harald Welteae026692017-12-09 01:03:01 +0100126
127function f_bssap_wait_for_reset() runs on BSSAP_Adapter_CT {
128 var BSSAP_N_UNITDATA_ind ud_ind;
129 timer T := 20.0;
130
131 T.start;
132 alt {
133 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
134 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
135 ts_BSSMAP_ResetAck));
136 }
137 [] as_reset_ack();
138 [] BSSAP.receive {
139 repeat;
140 }
141 [] T.timeout {
142 setverdict(fail);
143 }
144 }
145}
146
147function f_bssap_reset() runs on BSSAP_Adapter_CT {
148 timer T := 5.0;
149
150 BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, ts_BSSMAP_Reset(0)));
151 T.start;
152 alt {
153 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_sccp_addr_own, g_sccp_addr_peer, tr_BSSMAP_ResetAck)) {
154 log("Received RESET-ACK in response to RESET, we're ready to go!");
155 }
156 [] as_reset_ack();
157 [] BSSAP.receive { repeat };
158 [] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); }
159 }
160}
161
162
Harald Welte28d943e2017-11-25 15:00:50 +0100163}