aboutsummaryrefslogtreecommitdiffstats
path: root/library/RAN_Adapter.ttcnpp
blob: 40cf0faba4ebf4ee5f42dc15a7e62ffe8ee24eec (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
module RAN_Adapter {

/* This module implements a 'dumb' RAN adapter.  It creates the M3UA and SCCP components and stacks a
 * BSSAP/RANAP codec port on top.  As a result, it provides the ability to transceive SCCP-User-SAP primitives
 * with deoded BSSAP/RANAP payload.  Use this if you want to have full control about what you transmit or
 * receive, without any automatisms in place.  Allows you to refuse connections or other abnormal behavior. */

/* (C) 2017-2019 Harald Welte <laforge@gnumonks.org>
 * contributions by sysmocom - s.f.m.c. GmbH
 * All rights reserved.
 *
 * Released under the terms of GNU General Public License, Version 2 or
 * (at your option) any later version.
 *
 * SPDX-License-Identifier: GPL-2.0-or-later
 */

import from General_Types all;
import from Osmocom_Types all;

import from M3UA_Emulation all;
import from MTP3asp_Types all;
import from MTP3asp_PortType all;

import from IPA_Emulation all;

import from SCCP_Types all;
import from SCCPasp_Types all;
import from SCCP_Emulation all;
import from SCCP_Templates all;

import from SCTPasp_Types all;
import from SCTPasp_PortType all;

#ifdef RAN_EMULATION_BSSAP
import from BSSMAP_Templates all;
#endif
import from RAN_Emulation all;

type record RAN_Adapter {
	/* component references */
	M3UA_CT vc_M3UA,		/* only in 3GPP AoIP */
	IPA_Emulation_CT vc_IPA,	/* only in SCCPlite */
	IPA_EventWaiter_CT vc_WAIT,	/* only in SCCPlite */
	SCCP_CT vc_SCCP,

	MSC_SCCP_MTP3_parameters sccp_pars,
	SCCP_PAR_Address sccp_addr_own,
	SCCP_PAR_Address sccp_addr_peer,

	/* handler mode */
	RAN_Emulation_CT vc_RAN
}

type record RAN_Configuration {
	RAN_Transport transport,
	charstring sccp_service_type,
	SCTP_Association_Address sctp_addr,
	integer own_pc,
	integer own_ssn,
	integer peer_pc,
	integer peer_ssn,
	octetstring sio,
	integer rctx
};

private function init_pars(inout RAN_Adapter ba, in RAN_Configuration cfg) {
	ba.sccp_pars := {
		sio := {
			ni := substr(oct2bit(cfg.sio),0,2),
			prio := substr(oct2bit(cfg.sio),2,2),
			si := substr(oct2bit(cfg.sio),4,4)
		},
		opc := cfg.own_pc,
		dpc := cfg.peer_pc,
		sls := 0,
		sccp_serviceType := cfg.sccp_service_type,
		ssn := cfg.own_ssn
	};
	ba.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(cfg.own_pc, cfg.own_ssn, cfg.sio, cfg.sccp_service_type));
	ba.sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(cfg.peer_pc, cfg.peer_ssn, cfg.sio, cfg.sccp_service_type));
}


function f_ran_adapter_init(inout RAN_Adapter ba, in RAN_Configuration cfg, charstring id,
			template RanOps ops) {
	init_pars(ba, cfg);
	ops.sccp_addr_local := ba.sccp_addr_own;
	ops.sccp_addr_peer := ba.sccp_addr_peer;

	/* create components */
	ba.vc_SCCP := SCCP_CT.create(id & "-SCCP");
	if (isvalue(ops)) {
		ba.vc_RAN := RAN_Emulation_CT.create(id & "-RAN");
	}
	select (cfg.transport) {
	case (BSSAP_TRANSPORT_AoIP, RANAP_TRANSPORT_IuCS) {
		ba.vc_M3UA := M3UA_CT.create(id & "-M3UA");
		map(ba.vc_M3UA:SCTP_PORT, system:sctp);
		/* connect MTP3 service provider (M3UA) to lower side of SCCP */
		connect(ba.vc_M3UA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
		ba.vc_M3UA.start(f_M3UA_Emulation(cfg.sctp_addr, cfg.rctx));
		}
#ifdef IPA_EMULATION_SCCP
	case (BSSAP_TRANSPORT_SCCPlite_SERVER) {
		ba.vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
		map(ba.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
		/* connect MTP3 service provider (IPA) to lower side of SCCP */
		connect(ba.vc_IPA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
		/* connect waiter to general IPA port (for ASP_IPA_Event) */
		ba.vc_WAIT := IPA_EventWaiter_CT.create(id & "-IPA-WAIT");
		connect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
		ba.vc_WAIT.start(IPA_Emulation.waiter_main());
		ba.vc_IPA.start(IPA_Emulation.main_server(cfg.sctp_addr.local_ip_addr,
							cfg.sctp_addr.local_sctp_port,
							true, IPA_INIT_SEND_IPA_ID_ACK));
		/* wait until we received an IPA CCM ID_ACK */
		ba.vc_WAIT.done;
		disconnect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
		}
	case (BSSAP_TRANSPORT_SCCPlite_CLIENT) {
		ba.vc_IPA := IPA_Emulation_CT.create(id & "-IPA");
		map(ba.vc_IPA:IPA_PORT, system:IPA_CODEC_PT);
		/* connect MTP3 service provider (IPA) to lower side of SCCP */
		connect(ba.vc_IPA:MTP3_SP_PORT, ba.vc_SCCP:MTP3_SCCP_PORT);
		/* connect waiter to general IPA port (for ASP_IPA_Event) */
		ba.vc_WAIT := IPA_EventWaiter_CT.create(id & "-IPA-WAIT");
		connect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
		ba.vc_WAIT.start(IPA_Emulation.waiter_main());
		ba.vc_IPA.start(IPA_Emulation.main_client(cfg.sctp_addr.remote_ip_addr,
							cfg.sctp_addr.remote_sctp_port,
							cfg.sctp_addr.local_ip_addr,
							cfg.sctp_addr.local_sctp_port));
		/* wait until we received an IPA CCM ID_ACK */
		ba.vc_WAIT.done;
		disconnect(ba.vc_IPA:IPA_SP_PORT, ba.vc_WAIT:IPA_SP_PORT);
		}
#endif /* SCCP */
	case else {
		setverdict(fail, "Unsuppored RAN_Transport");
		mtc.stop;
		}
	}

	if (isvalue(ops)) {
		timer T := 5.0;
		T.start;
		//T.timeout;
		ops.transport := cfg.transport;
		/* connect BSSNAP component to upper side of SCCP */
		if (cfg.transport == RANAP_TRANSPORT_IuCS) {
#ifdef RAN_EMULATION_RANAP
			log("Connecting RANAP RAN_Emulation to SCCP_SP_PORT");
			ops.protocol := RAN_PROTOCOL_RANAP
			connect(ba.vc_RAN:RANAP, ba.vc_SCCP:SCCP_SP_PORT);
#endif
		} else {
#ifdef RAN_EMULATION_BSSAP
			log("Connecting BSSAP RAN_Emulation to SCCP_SP_PORT");
			connect(ba.vc_RAN:BSSAP, ba.vc_SCCP:SCCP_SP_PORT);
#endif
		}
		if (cfg.transport == BSSAP_TRANSPORT_SCCPlite_SERVER or
		    cfg.transport == BSSAP_TRANSPORT_SCCPlite_CLIENT) {
#ifdef IPA_EMULATION_MGCP
			/* connect IPA MGCP port with BSSMAP MGCP port */
			log("Connecting MGCP RAN Emulation to IPA MGCP PORT");
			connect(ba.vc_IPA:IPA_MGCP_PORT, ba.vc_RAN:MGCP);
#endif
#ifdef IPA_EMULATION_CTRL
			/* connect IPA CTRL port with BSSMAP CTRL port */
			log("Connecting CTRL RAN Emulation to IPA CTRL PORT");
			connect(ba.vc_IPA:IPA_CTRL_PORT, ba.vc_RAN:CTRL);
#endif
		}
		log("Starting RAN_Emulation");
		ba.vc_RAN.start(RAN_Emulation.main(valueof(ops), ""));
	}


}

function f_ran_adapter_start(inout RAN_Adapter ba) {
	ba.vc_SCCP.start(SCCPStart(ba.sccp_pars));
}


}