aboutsummaryrefslogtreecommitdiffstats
path: root/library/RAN_Adapter.ttcnpp
blob: ae7934e6f2255feae685a59d4cadb26c7690dc45 (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
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. */

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 enumerated RAN_Transport {
	BSSAP_TRANSPORT_AoIP,	/* 3GPP AoIP: SCCP over M3UA over SCTP */
	BSSAP_TRANSPORT_SCCPlite_SERVER, /* SCCPlite: SCCP over IPA over TCP */
	BSSAP_TRANSPORT_SCCPlite_CLIENT  /* SCCPlite: SCCP over IPA over TCP */
};

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) {
#ifdef RAN_EMULATION_BSSAP
	case (BSSAP_TRANSPORT_AoIP) {
		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 */
#endif /* BSSAP */
	case else {
		setverdict(fail, "Unsuppored RAN_Transport");
		mtc.stop;
		}
	}

	if (isvalue(ops)) {
		timer T := 5.0;
		T.start;
		//T.timeout;
		log("Connecting BSSMAP Emulation to SCCP_SP_PORT and starting emulation");
#if RAN_EMULATION_BSSAP
		/* connect BSSNAP component to upper side of SCCP */
		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 */
			connect(ba.vc_IPA:IPA_MGCP_PORT, ba.vc_RAN:MGCP);
#endif
		}
		/* start the BSSMAP 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));
}


}