blob: 0ebcc3dc70a4e9ee9e5c31e7a33e27fd74819290 [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
Harald Welteae026692017-12-09 01:03:01 +010027type component BSSAP_Adapter_CT {
Harald Welte28d943e2017-11-25 15:00:50 +010028 /* component references */
Harald Welteae026692017-12-09 01:03:01 +010029 var M3UA_CT vc_M3UA;
Harald Welte28d943e2017-11-25 15:00:50 +010030 var SCCP_CT vc_SCCP;
Harald Welte28d943e2017-11-25 15:00:50 +010031 /* test port to SCCP emulation */
Harald Welteae026692017-12-09 01:03:01 +010032 port BSSAP_CODEC_PT BSSAP;
33
34 var octetstring g_sio;
35 var MSC_SCCP_MTP3_parameters g_sccp_pars;
36 var SCCP_PAR_Address g_sccp_addr_own, g_sccp_addr_peer;
Harald Welte624f9632017-12-16 19:26:04 +010037
38 /* handler mode */
39 var BSSMAP_Emulation_CT vc_BSSMAP;
Harald Welte28d943e2017-11-25 15:00:50 +010040}
41
42modulepar {
Harald Welteae026692017-12-09 01:03:01 +010043 charstring mp_sccp_service_type := "mtp3_itu";
44
45 SCTP_Association_Address mp_sctp_addr := { 23905, "127.0.0.1", 2905, "127.0.0.1" };
46 integer mp_own_pc := 185; /* 0.23.1 */
47 integer mp_own_ssn := 254;
48
49 integer mp_peer_pc := 187;
50 integer mp_peer_ssn := 254;
Harald Welte28d943e2017-11-25 15:00:50 +010051}
52
Harald Welteae026692017-12-09 01:03:01 +010053/* construct a SCCP_PAR_Address with just PC + SSN and no GT */
54template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn) := {
55 addressIndicator := {
56 pointCodeIndic := '1'B,
57 ssnIndicator := '1'B,
58 globalTitleIndic := '0000'B,
59 routingIndicator := '1'B
60 },
61 signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O),
62 //signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio),
63 subsystemNumber := ssn,
64 globalTitle := omit
65}
66
67private function init_pars() runs on BSSAP_Adapter_CT {
68 g_sio := '83'O;
69 g_sccp_pars := {
70 sio := {
71 ni := substr(oct2bit(g_sio),0,2),
72 prio := substr(oct2bit(g_sio),2,2),
73 si := substr(oct2bit(g_sio),4,4)
74 },
75 opc := mp_own_pc,
76 dpc := mp_peer_pc,
77 sls := 0,
78 sccp_serviceType := mp_sccp_service_type,
79 ssn := mp_own_ssn
80 };
81 g_sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(mp_own_pc, mp_own_ssn));
82 g_sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(mp_peer_pc, mp_peer_ssn));
83}
84
85
Harald Welte67089ee2018-01-17 22:19:03 +010086function f_bssap_init(charstring id, template BssmapOps ops) runs on BSSAP_Adapter_CT
Harald Welte28d943e2017-11-25 15:00:50 +010087{
Harald Welteae026692017-12-09 01:03:01 +010088 init_pars();
89
Harald Welte28d943e2017-11-25 15:00:50 +010090 /* create components */
Harald Welteae026692017-12-09 01:03:01 +010091 vc_M3UA := M3UA_CT.create(id & "-M3UA");
Harald Welte28d943e2017-11-25 15:00:50 +010092 vc_SCCP := SCCP_CT.create(id & "-SCCP");
Harald Welte67089ee2018-01-17 22:19:03 +010093 if (isvalue(ops)) {
Harald Welte624f9632017-12-16 19:26:04 +010094 vc_BSSMAP := BSSMAP_Emulation_CT.create(id & "-BSSMAP");
95 }
Harald Welte28d943e2017-11-25 15:00:50 +010096
Harald Welteae026692017-12-09 01:03:01 +010097 map(vc_M3UA:SCTP_PORT, system:sctp);
Harald Welte28d943e2017-11-25 15:00:50 +010098
Harald Welteae026692017-12-09 01:03:01 +010099 /* connect MTP3 service provider (M3UA) to lower side of SCCP */
100 connect(vc_M3UA:MTP3_SP_PORT, vc_SCCP:MTP3_SCCP_PORT);
Harald Welteb0ec4ee2018-01-21 13:53:17 +0100101 /* connect ourselves to upper side of SCCP */
102 connect(self:BSSAP, vc_SCCP:SCCP_SP_PORT);
Harald Welte28d943e2017-11-25 15:00:50 +0100103
Harald Welteae026692017-12-09 01:03:01 +0100104 vc_M3UA.start(f_M3UA_Emulation(mp_sctp_addr));
105 vc_SCCP.start(SCCPStart(g_sccp_pars));
Harald Welteb0ec4ee2018-01-21 13:53:17 +0100106
Harald Welte67089ee2018-01-17 22:19:03 +0100107 if (isvalue(ops)) {
Harald Welteb0ec4ee2018-01-21 13:53:17 +0100108 timer T := 5.0;
109 T.start;
110 T.timeout;
111 /* Perform reset procedure */
112 f_bssap_reset();
113 /* disconect ourselves */
114 disconnect(self:BSSAP, vc_SCCP:SCCP_SP_PORT);
115 /* connect BSSNAP component to upposer side of SCCP */
116 connect(vc_BSSMAP:BSSAP, vc_SCCP:SCCP_SP_PORT);
117 /* start the BSSMAP emulation */
Harald Welte67089ee2018-01-17 22:19:03 +0100118 vc_BSSMAP.start(BSSMAP_Emulation.main(valueof(ops), ""));
Harald Welte624f9632017-12-16 19:26:04 +0100119 }
Harald Welteae026692017-12-09 01:03:01 +0100120}
Harald Welte28d943e2017-11-25 15:00:50 +0100121
Harald Welteae026692017-12-09 01:03:01 +0100122private altstep as_reset_ack() runs on BSSAP_Adapter_CT {
123 var BSSAP_N_UNITDATA_ind ud_ind;
124 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
125 log("Respoding to inbound RESET with RESET-ACK");
126 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
127 ts_BSSMAP_ResetAck));
Harald Welte8b20f7c2017-12-22 20:39:20 +0100128 repeat;
Harald Welte28d943e2017-11-25 15:00:50 +0100129 }
130}
131
Harald Welteae026692017-12-09 01:03:01 +0100132
133function f_bssap_wait_for_reset() runs on BSSAP_Adapter_CT {
134 var BSSAP_N_UNITDATA_ind ud_ind;
135 timer T := 20.0;
136
137 T.start;
138 alt {
139 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
140 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
141 ts_BSSMAP_ResetAck));
142 }
143 [] as_reset_ack();
144 [] BSSAP.receive {
145 repeat;
146 }
147 [] T.timeout {
148 setverdict(fail);
149 }
150 }
151}
152
153function f_bssap_reset() runs on BSSAP_Adapter_CT {
154 timer T := 5.0;
155
156 BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, ts_BSSMAP_Reset(0)));
157 T.start;
158 alt {
159 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_sccp_addr_own, g_sccp_addr_peer, tr_BSSMAP_ResetAck)) {
160 log("Received RESET-ACK in response to RESET, we're ready to go!");
161 }
162 [] as_reset_ack();
163 [] BSSAP.receive { repeat };
164 [] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); }
165 }
166}
167
168
Harald Welte28d943e2017-11-25 15:00:50 +0100169}