blob: 170bcd22a7baa84409a50eb6ced7c1a30d4b8c8e [file] [log] [blame]
Harald Weltef9d449e2018-06-24 22:27:47 +02001/* Simple / General implementation of an External USSD Entity using OsmoHLR's GSUP Protocol
2 *
3 * The idea is that a test case can simply start an instance of this component in parallel to its
4 * normal test components. HLR_EUSE_CT will then connect via GSUP to the HLR as the specified EUSE
5 * name. Any USSD related GSUP message received will be passed to a user-provided call-back
6 * function, which will return whatever PDU to send in response back to the HLR.
7 */
8
Harald Welte34b5a952019-05-27 11:54:11 +02009
10/* (C) 2018 Harald Welte <laforge@gnumonks.org>
11 * All rights reserved.
12 *
13 * Released under the terms of GNU General Public License, Version 2 or
14 * (at your option) any later version.
15 *
16 * SPDX-License-Identifier: GPL-2.0-or-later
17 */
Harald Weltef9d449e2018-06-24 22:27:47 +020018
19module HLR_EUSE {
20
21import from GSUP_Types all;
Pau Espin Pedrol8f1403a2024-01-18 20:08:43 +010022import from GSUP_Templates all;
Harald Weltef9d449e2018-06-24 22:27:47 +020023import from IPA_Emulation all;
24
25import from General_Types all;
26import from Osmocom_Types all;
27import from SS_Types all;
28import from SS_Templates all;
29
30/* emulating an external USSD Entity towards OsmoHLR */
31type component HLR_EUSE_CT {
32 /* Component reference + config of underlying IPA emulation */
33 var IPA_Emulation_CT vc_IPA_EUSE;
34 var IPA_CCM_Parameters ccm_pars;
35 /* port towards the underlying IPA emulation */
36 port IPA_GSUP_PT EUSE;
37}
38
39private function f_init(charstring hlr_ip, uint16_t hlr_gsup_port, charstring name) runs on HLR_EUSE_CT {
40 var charstring id := "EUSE-" & name;
41 ccm_pars := c_IPA_default_ccm_pars;
42 ccm_pars.name := "Osmocom TTCN-3 EUSE Simulator";
43 ccm_pars.ser_nr := id;
44
45 vc_IPA_EUSE := IPA_Emulation_CT.create("IPA-" & id);
46 map(vc_IPA_EUSE:IPA_PORT, system:IPA_CODEC_PT);
47 connect(vc_IPA_EUSE:IPA_GSUP_PORT, self:EUSE);
48 vc_IPA_EUSE.start(IPA_Emulation.main_client(hlr_ip, hlr_gsup_port, "", 0, ccm_pars));
49
50 timer T := 10.0;
51 T.start;
52 alt {
Vadim Yanitskiya2afacc2020-05-18 21:16:19 +070053 [] EUSE.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)) { repeat; }
54 [] EUSE.receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)) { }
Harald Weltef9d449e2018-06-24 22:27:47 +020055 [] T.timeout {
56 setverdict(fail, "EUSE: Timeout waiting for GSUP IPA Link to come up");
57 self.stop;
58 }
59 }
60}
61
Vadim Yanitskiyd686a8a2018-11-02 02:42:32 +070062type function f_euse_cb(GSUP_PDU rx_pdu) return GSUP_PDU;
Harald Weltef9d449e2018-06-24 22:27:47 +020063
Vadim Yanitskiyd686a8a2018-11-02 02:42:32 +070064function f_ss_echo_continue(GSUP_PDU rx_pdu) return GSUP_PDU {
Harald Weltef9d449e2018-06-24 22:27:47 +020065 var GSUP_SessionState ss_next_state;
Vadim Yanitskiyd686a8a2018-11-02 02:42:32 +070066 var GSUP_IeValue ss_ie, state_ie;
Harald Weltef9d449e2018-06-24 22:27:47 +020067 var SS_FacilityInformation dec_fac, rsp_fac;
68 var octetstring ss_rsp;
69
Daniel Willmanne2bd04a2018-11-06 16:31:27 +010070 f_gsup_find_ie(rx_pdu, OSMO_GSUP_SESSION_STATE_IE, state_ie);
Vadim Yanitskiyd686a8a2018-11-02 02:42:32 +070071 var GSUP_SessionState ss_state := state_ie.session_state;
72
Harald Weltef9d449e2018-06-24 22:27:47 +020073 f_gsup_find_ie(rx_pdu, OSMO_GSUP_SS_INFO_IE, ss_ie);
74 dec_fac := dec_SS_FacilityInformation(ss_ie.ss_info);
75 log("dec_fac: ", dec_fac);
76 rsp_fac := valueof(ts_SS_USSD_FACILITY_RETURN_RESULT(dec_fac[0].invoke.invokeId.present_,
77 SS_OP_CODE_PROCESS_USS_REQ,
78 dec_fac[0].invoke.argument.uSSD_Arg.ussd_DataCodingScheme,
79 dec_fac[0].invoke.argument.uSSD_Arg.ussd_String));
80 ss_rsp := enc_SS_FacilityInformation(rsp_fac);
81 select (ss_state) {
82 case (OSMO_GSUP_SESSION_STATE_BEGIN) { ss_next_state := OSMO_GSUP_SESSION_STATE_CONTINUE; }
83 case (OSMO_GSUP_SESSION_STATE_CONTINUE) { ss_next_state := OSMO_GSUP_SESSION_STATE_END; }
84 }
85 return valueof(ts_GSUP_PROC_SS_RES(rx_pdu.ies[0].val.imsi, rx_pdu.ies[1].val.session_id,
86 ss_next_state, ss_rsp));
87}
88
Vadim Yanitskiyd686a8a2018-11-02 02:42:32 +070089function f_ss_echo(GSUP_PDU rx_pdu) return GSUP_PDU {
Harald Weltef9d449e2018-06-24 22:27:47 +020090 var GSUP_IeValue ss_ie;
91 var SS_FacilityInformation dec_fac, rsp_fac;
92 var octetstring ss_rsp;
93
94 f_gsup_find_ie(rx_pdu, OSMO_GSUP_SS_INFO_IE, ss_ie);
95 dec_fac := dec_SS_FacilityInformation(ss_ie.ss_info);
96 log("dec_fac: ", dec_fac);
97 rsp_fac := valueof(ts_SS_USSD_FACILITY_RETURN_RESULT(dec_fac[0].invoke.invokeId.present_,
98 SS_OP_CODE_PROCESS_USS_REQ,
99 dec_fac[0].invoke.argument.uSSD_Arg.ussd_DataCodingScheme,
100 dec_fac[0].invoke.argument.uSSD_Arg.ussd_String));
101 ss_rsp := enc_SS_FacilityInformation(rsp_fac);
102 return valueof(ts_GSUP_PROC_SS_RES(rx_pdu.ies[0].val.imsi, rx_pdu.ies[1].val.session_id,
103 OSMO_GSUP_SESSION_STATE_END, ss_rsp));
104}
105
106/* main function for handling mobile-originated USSD via GSUP */
107function f_main_mo(charstring hlr_ip, uint16_t hlr_gsup_port, charstring name, f_euse_cb cb_fn)
108runs on HLR_EUSE_CT {
109 var GSUP_PDU rx_pdu, tx_pdu;
110
111 f_init(hlr_ip, hlr_gsup_port, name);
112
113 while (true) {
114 alt {
Vadim Yanitskiyd686a8a2018-11-02 02:42:32 +0700115 [] EUSE.receive(tr_GSUP_PROC_SS_REQ(?, ?, ?)) -> value rx_pdu {
116 EUSE.send(cb_fn.apply(rx_pdu));
Harald Weltef9d449e2018-06-24 22:27:47 +0200117 }
118
119
120 [] EUSE.receive {
121 setverdict(fail, "EUSE: Unexpected Rx from HLR");
122 self.stop;
123 }
124 }
125 }
126}
127
128
129}