aboutsummaryrefslogtreecommitdiffstats
path: root/bsc-nat/IPA_Test.ttcn
blob: fbff84abd54e1288bdc29752b723f9eb6ba6ee4c (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
module IPA_Test {

import from Osmocom_Types all;

import from IPL4asp_Types all;

import from IPA_Emulation all;

import from MTP3asp_Types all;

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

import from MSC_Simulation all;
import from BSC_MS_Simulation all;

const integer NUM_MSC := 1;
const integer NUM_BSC := 1;

type record BscState {
	BSC_CT BSC,
	MSC_SCCP_MTP3_parameters sccp_pars,
	SCCP_PAR_Address sccp_addr_own,
	SCCP_PAR_Address sccp_addr_peer
}

type record MscState {
	MSC_CT MSC,
	MSC_SCCP_MTP3_parameters sccp_pars,
	SCCP_PAR_Address sccp_addr_own
}

type component test_CT {
	var MscState msc[NUM_MSC];
	var BscState bsc[NUM_BSC];

	var boolean g_initialized := false;
	var octetstring g_sio := '83'O;
}

modulepar {
	PortNumber mp_bsc_port := 49999;
	charstring mp_bsc_ip := "127.0.0.1";

	PortNumber mp_msc_port := 5000;
	charstring mp_msc_ip := "127.0.0.1";

	PortNumber mp_nat_port := 5000;
	charstring mp_nat_ip := "127.0.0.1";

	charstring mp_sccp_service_type := "mtp3_itu";

	integer mp_bsc_pc := 196;
	integer mp_bsc_ssn := 254;

	integer mp_msc_pc := 185;	/* 0.23.1 */
	integer mp_msc_ssn := 254;
}

/* construct a SCCP_PAR_Address with just PC + SSN and no GT */
template (value) SCCP_PAR_Address ts_SccpAddr_PC_SSN(integer pc, integer ssn) := {
	addressIndicator := {
		pointCodeIndic := '1'B,
		ssnIndicator := '1'B,
		globalTitleIndic := '0000'B,
		routingIndicator := '1'B
	},
	signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, '83'O),
	//signPointCode := SCCP_SPC_int2bit(pc, mp_sccp_service_type, g_sio),
	subsystemNumber := ssn,
	globalTitle := omit
}

template MTP3_Field_sio ts_sio(octetstring sio_in) := {
	ni := substr(oct2bit(sio_in),0,2),
	prio := substr(oct2bit(sio_in),2,2),
	si := substr(oct2bit(sio_in),4,4)
}

template MSC_SCCP_MTP3_parameters ts_SCCP_Pars(octetstring sio, integer opc, integer dpc,
						integer local_ssn) := {
	sio := ts_sio(sio),
	opc := opc,
	dpc := dpc,
	sls := 0,
	sccp_serviceType := mp_sccp_service_type,
	ssn := local_ssn
};

function f_init_BscState(inout BscState bsc_st, integer opc, integer dpc, integer local_ssn, integer remote_ssn)
runs on test_CT {
	bsc_st.sccp_pars := valueof(ts_SCCP_Pars(g_sio, opc, dpc, local_ssn));
	bsc_st.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(opc, local_ssn));
	bsc_st.sccp_addr_peer := valueof(ts_SccpAddr_PC_SSN(dpc, remote_ssn));
}

function f_init_MscState(inout MscState msc_st, integer opc, integer dpc, integer local_ssn, integer remote_ssn)
runs on test_CT {
	msc_st.sccp_pars := valueof(ts_SCCP_Pars(g_sio, opc, dpc, local_ssn));
	msc_st.sccp_addr_own := valueof(ts_SccpAddr_PC_SSN(opc, local_ssn));
}

function f_init() runs on test_CT {
	var integer i;
	var charstring id;

	for (i := 0; i < NUM_MSC; i := i+1) {
		f_init_MscState(msc[i], mp_msc_pc +i, mp_bsc_pc, mp_msc_ssn, mp_bsc_ssn);
		msc[i].MSC := MSC_CT.create;
		id := "MSC" & int2str(i);
		msc[i].MSC.start(MSC_Simulation.main(mp_msc_ip, mp_msc_port + i, msc[i].sccp_pars, msc[i].sccp_addr_own, id));
	}

	for (i := 0; i < NUM_BSC; i := i+1) {
		f_init_BscState(bsc[i], mp_bsc_pc +i, mp_msc_pc, mp_bsc_ssn, mp_msc_ssn);
		bsc[i].BSC := BSC_CT.create;
		id := "BSC" & int2str(i);
		bsc[i].BSC.start(BSC_MS_Simulation.main(mp_nat_ip, mp_nat_port, mp_bsc_ip, mp_bsc_port+i,
							bsc[i].sccp_pars, bsc[i].sccp_addr_own,
							bsc[i].sccp_addr_peer, id));
	}

}

testcase TC_recv_dump() runs on test_CT {
	var integer i;
	timer T := 30.0;

	f_init();

	alt {
		/* wait for BSC to stop. The idea is that the BSC components terminate first */
		[] bsc[0].BSC.done { }
		[] T.timeout { setverdict(fail); }
	}

	all component.stop;
	/* terminate the MSCs */
	for (i := 0; i < NUM_MSC; i := i+1) {
		msc[i].MSC.stop;
	}
}

control {
	execute( TC_recv_dump() );
}

}