blob: 98a30d880743c4ad243008dd07820424d43d3620 [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 Welte67089ee2018-01-17 22:19:03 +0100101 if (isvalue(ops)) {
Harald Welte624f9632017-12-16 19:26:04 +0100102 connect(vc_BSSMAP:BSSAP, vc_SCCP:SCCP_SP_PORT);
103 } else {
104 /* connect BSSNAP dispatcher to upper side of SCCP */
105 connect(self:BSSAP, vc_SCCP:SCCP_SP_PORT);
106 }
Harald Welte28d943e2017-11-25 15:00:50 +0100107
Harald Welteae026692017-12-09 01:03:01 +0100108 vc_M3UA.start(f_M3UA_Emulation(mp_sctp_addr));
109 vc_SCCP.start(SCCPStart(g_sccp_pars));
Harald Welte67089ee2018-01-17 22:19:03 +0100110 if (isvalue(ops)) {
111 vc_BSSMAP.start(BSSMAP_Emulation.main(valueof(ops), ""));
Harald Welte624f9632017-12-16 19:26:04 +0100112 }
Harald Welteae026692017-12-09 01:03:01 +0100113}
Harald Welte28d943e2017-11-25 15:00:50 +0100114
Harald Welteae026692017-12-09 01:03:01 +0100115private altstep as_reset_ack() runs on BSSAP_Adapter_CT {
116 var BSSAP_N_UNITDATA_ind ud_ind;
117 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
118 log("Respoding to inbound RESET with RESET-ACK");
119 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
120 ts_BSSMAP_ResetAck));
Harald Welte8b20f7c2017-12-22 20:39:20 +0100121 repeat;
Harald Welte28d943e2017-11-25 15:00:50 +0100122 }
123}
124
Harald Welteae026692017-12-09 01:03:01 +0100125
126function f_bssap_wait_for_reset() runs on BSSAP_Adapter_CT {
127 var BSSAP_N_UNITDATA_ind ud_ind;
128 timer T := 20.0;
129
130 T.start;
131 alt {
132 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(?, ?, tr_BSSMAP_Reset)) -> value ud_ind {
133 BSSAP.send(ts_BSSAP_UNITDATA_req(ud_ind.callingAddress, ud_ind.calledAddress,
134 ts_BSSMAP_ResetAck));
135 }
136 [] as_reset_ack();
137 [] BSSAP.receive {
138 repeat;
139 }
140 [] T.timeout {
141 setverdict(fail);
142 }
143 }
144}
145
146function f_bssap_reset() runs on BSSAP_Adapter_CT {
147 timer T := 5.0;
148
149 BSSAP.send(ts_BSSAP_UNITDATA_req(g_sccp_addr_peer, g_sccp_addr_own, ts_BSSMAP_Reset(0)));
150 T.start;
151 alt {
152 [] BSSAP.receive(tr_BSSAP_UNITDATA_ind(g_sccp_addr_own, g_sccp_addr_peer, tr_BSSMAP_ResetAck)) {
153 log("Received RESET-ACK in response to RESET, we're ready to go!");
154 }
155 [] as_reset_ack();
156 [] BSSAP.receive { repeat };
157 [] T.timeout { setverdict(fail, "Waiting for RESET-ACK after sending RESET"); }
158 }
159}
160
161
Harald Welte28d943e2017-11-25 15:00:50 +0100162}