blob: f7aab0db1c7eb02d17abf5e2ae9f02a44f448331 [file] [log] [blame]
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001/* Code to manage a subscriber's MSC-I role */
2/*
3 * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
4 * All Rights Reserved
5 *
6 * SPDX-License-Identifier: AGPL-3.0+
7 *
8 * Author: Neels Hofmeyr
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Affero General Public License as published by
12 * the Free Software Foundation; either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Affero General Public License for more details.
19 *
20 * You should have received a copy of the GNU Affero General Public License
21 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 */
23
24#include <osmocom/msc/gsm_data.h>
25#include <osmocom/msc/msc_i.h>
26#include <osmocom/msc/ran_msg.h>
27#include <osmocom/msc/ran_conn.h>
28#include <osmocom/msc/ran_peer.h>
29#include <osmocom/msc/sccp_ran.h>
30#include <osmocom/msc/msub.h>
31#include <osmocom/msc/msc_a.h>
32#include <osmocom/msc/call_leg.h>
33#include <osmocom/msc/mncc_call.h>
34
35static struct osmo_fsm msc_i_fsm;
36
37struct ran_infra *msc_i_ran(struct msc_i *msc_i)
38{
39 OSMO_ASSERT(msc_i
40 && msc_i->ran_conn
41 && msc_i->ran_conn->ran_peer
42 && msc_i->ran_conn->ran_peer->sri
43 && msc_i->ran_conn->ran_peer->sri->ran);
44 return msc_i->ran_conn->ran_peer->sri->ran;
45}
46
47static int msc_i_ran_enc(struct msc_i *msc_i, const struct ran_msg *ran_enc_msg)
48{
49 struct msgb *l3 = msc_role_ran_encode(msc_i->c.fi, ran_enc_msg);
50 if (!l3)
51 return -EIO;
52 return msc_i_down_l2(msc_i, l3);
53}
54
55struct msc_i *msc_i_priv(struct osmo_fsm_inst *fi)
56{
57 OSMO_ASSERT(fi);
58 OSMO_ASSERT(fi->fsm == &msc_i_fsm);
59 OSMO_ASSERT(fi->priv);
60 return fi->priv;
61}
62
63int msc_i_ready_decode_cb(struct osmo_fsm_inst *msc_i_fi, void *data, const struct ran_msg *msg)
64{
65 struct msc_i *msc_i = msc_i_priv(msc_i_fi);
66 struct msc_a *msc_a = msub_msc_a(msc_i->c.msub);
67 const struct an_apdu *an_apdu = data;
68 uint32_t event;
69
70 event = MSC_A_EV_FROM_I_PROCESS_ACCESS_SIGNALLING_REQUEST;
71
72 switch (msg->msg_type) {
73 case RAN_MSG_HANDOVER_REQUIRED:
74 if (msc_a->c.remote_to) {
75 /* We're already a remote MSC-B, this hence must be a "subsequent" handover.
76 * There is not much difference really from dispatching a Process Access Signalling Request,
77 * only that 3GPP TS 29.010 specifies the different message type. */
78 event = MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST;
79 }
80 break;
81 default:
82 break;
83 }
84
85 return msub_role_dispatch(msc_i->c.msub, MSC_ROLE_A, event, an_apdu);
86}
87
88void msc_i_fsm_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
89{
90 struct msc_i *msc_i = msc_i_priv(fi);
91 struct msc_a *msc_a = msub_msc_a(msc_i->c.msub);
92 struct an_apdu *an_apdu;
93
94 if (!msc_a) {
95 LOG_MSC_I(msc_i, LOGL_ERROR, "No MSC-A role\n");
96 return;
97 }
98
99 switch (event) {
100
101 case MSC_EV_FROM_RAN_COMPLETE_LAYER_3:
102 an_apdu = data;
103 msub_role_dispatch(msc_i->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_I_COMPLETE_LAYER_3, an_apdu);
104 break;
105
106 case MSC_EV_FROM_RAN_UP_L2:
107 an_apdu = data;
108 /* To send the correct event types like MSC_A_EV_FROM_I_PREPARE_SUBSEQUENT_HANDOVER_REQUEST and hence
109 * reflect the correct GSUP message type on an inter-MSC link, need to decode the message here. */
110 msc_role_ran_decode(msc_i->c.fi, an_apdu, msc_i_ready_decode_cb, an_apdu);
111 break;
112
113 case MSC_EV_FROM_RAN_CONN_RELEASED:
114 msc_i_cleared(msc_i);
115 break;
116
117 case MSC_EV_CALL_LEG_TERM:
118 msc_i->inter_msc.call_leg = NULL;
119 if (msc_i->inter_msc.mncc_forwarding_to_remote_cn)
120 msc_i->inter_msc.mncc_forwarding_to_remote_cn->rtps = NULL;
121 break;
122
123 case MSC_MNCC_EV_CALL_ENDED:
124 msc_i->inter_msc.mncc_forwarding_to_remote_cn = NULL;
125 break;
126
127 case MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST:
128 case MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_RESULT:
129 case MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_ERROR:
130 an_apdu = data;
131 if (an_apdu->an_proto != msc_i_ran(msc_i)->an_proto) {
132 LOG_MSC_I(msc_i, LOGL_ERROR, "Mismatching AN-APDU proto: %s -- Dropping message\n",
133 an_proto_name(an_apdu->an_proto));
134 msgb_free(an_apdu->msg);
135 an_apdu->msg = NULL;
136 return;
137 }
138 msc_i_down_l2(msc_i, an_apdu->msg);
139 break;
140
141 case MSC_I_EV_FROM_A_SEND_END_SIGNAL_RESPONSE:
142 msc_i_clear(msc_i);
143 break;
144
145 default:
146 OSMO_ASSERT(false);
147 }
148}
149
150void msc_i_fsm_clearing_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
151{
152 struct msc_i *msc_i = msc_i_priv(fi);
153 struct ran_msg msg = {
154 .msg_type = RAN_MSG_CLEAR_COMMAND,
155 /* Concerning CSFB (Circuit-Switched FallBack from LTE), for a final Clear Command that might indicate
156 * CSFB, the MSC-A has to send the Clear Command. This Clear Command is about detaching an MSC-I when a
157 * new MSC-I has shown up after an inter-BSC or inter-MSC Handover succeeded. So never CSFB here. */
158 };
159 msc_i_ran_enc(msc_i, &msg);
160}
161
162int msc_i_clearing_decode_cb(struct osmo_fsm_inst *msc_i_fi, void *data, const struct ran_msg *msg)
163{
164 struct msc_i *msc_i = msc_i_fi->priv;
165
166 switch (msg->msg_type) {
167
168 case RAN_MSG_CLEAR_COMPLETE:
169 switch (msc_i->c.fi->state) {
170 case MSC_I_ST_CLEARING:
171 osmo_fsm_inst_state_chg(msc_i->c.fi, MSC_I_ST_CLEARED, 0, 0);
172 return 0;
173 case MSC_I_ST_CLEARED:
174 return 0;
175 default:
176 LOG_MSC_I(msc_i, LOGL_ERROR, "Received Clear Complete, but did not send Clear Command\n");
177 {
178 struct msc_a *msc_a = msub_msc_a(msc_i->c.msub);
179 if (msc_a)
180 osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_MO_CLOSE, NULL);
181 }
182 return 0;
183 }
184
185 default:
186 LOG_MSC_I(msc_i, LOGL_ERROR, "Message not handled: %s\n", ran_msg_type_name(msg->msg_type));
187 return -ENOTSUP;
188 }
189}
190
191void msc_i_fsm_clearing(struct osmo_fsm_inst *fi, uint32_t event, void *data)
192{
193 struct msc_i *msc_i = msc_i_priv(fi);
194 struct an_apdu *an_apdu;
195
196 /* We expect a Clear Complete and nothing else. */
197 switch (event) {
198 case MSC_EV_FROM_RAN_UP_L2:
199 an_apdu = data;
200 msc_role_ran_decode(msc_i->c.fi, an_apdu, msc_i_clearing_decode_cb, NULL);
201 return;
202
203 case MSC_EV_FROM_RAN_CONN_RELEASED:
204 msc_i_cleared(msc_i);
205 return;
206
207 case MSC_EV_CALL_LEG_TERM:
208 msc_i->inter_msc.call_leg = NULL;
209 if (msc_i->inter_msc.mncc_forwarding_to_remote_cn)
210 msc_i->inter_msc.mncc_forwarding_to_remote_cn->rtps = NULL;
211 break;
212
213 case MSC_MNCC_EV_CALL_ENDED:
214 msc_i->inter_msc.mncc_forwarding_to_remote_cn = NULL;
215 break;
216 }
217}
218
219void msc_i_fsm_cleared_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
220{
221 osmo_fsm_inst_term(fi, OSMO_FSM_TERM_REGULAR, fi);
222}
223
224void msc_i_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
225{
226 struct msc_i *msc_i = msc_i_priv(fi);
227
228 call_leg_release(msc_i->inter_msc.call_leg);
229 mncc_call_release(msc_i->inter_msc.mncc_forwarding_to_remote_cn);
230
231 if (msc_i->ran_conn)
232 ran_conn_msc_role_gone(msc_i->ran_conn, msc_i->c.fi);
233}
234
235#define S(x) (1 << (x))
236
237static const struct osmo_fsm_state msc_i_fsm_states[] = {
238 [MSC_I_ST_READY] = {
239 .name = "READY",
240 .action = msc_i_fsm_ready,
241 .in_event_mask = 0
242 | S(MSC_EV_FROM_RAN_COMPLETE_LAYER_3)
243 | S(MSC_EV_FROM_RAN_UP_L2)
244 | S(MSC_EV_FROM_RAN_CONN_RELEASED)
245 | S(MSC_EV_CALL_LEG_TERM)
246 | S(MSC_MNCC_EV_CALL_ENDED)
247 | S(MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
248 | S(MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_RESULT)
249 | S(MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_ERROR)
250 | S(MSC_I_EV_FROM_A_SEND_END_SIGNAL_RESPONSE)
251 ,
252 .out_state_mask = 0
253 | S(MSC_I_ST_CLEARING)
254 | S(MSC_I_ST_CLEARED)
255 ,
256 },
257 [MSC_I_ST_CLEARING] = {
258 .name = "CLEARING",
259 .onenter = msc_i_fsm_clearing_onenter,
260 .action = msc_i_fsm_clearing,
261 .in_event_mask = 0
262 | S(MSC_EV_FROM_RAN_UP_L2)
263 | S(MSC_EV_FROM_RAN_CONN_RELEASED)
264 | S(MSC_EV_CALL_LEG_TERM)
265 | S(MSC_MNCC_EV_CALL_ENDED)
266 ,
267 .out_state_mask = 0
268 | S(MSC_I_ST_CLEARED)
269 ,
270 },
271 [MSC_I_ST_CLEARED] = {
272 .name = "CLEARED",
273 .onenter = msc_i_fsm_cleared_onenter,
274 },
275};
276
277const struct value_string msc_i_fsm_event_names[] = {
278 OSMO_VALUE_STRING(MSC_REMOTE_EV_RX_GSUP),
279 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE),
280 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_COMPLETE),
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100281 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_TERM),
282 OSMO_VALUE_STRING(MSC_MNCC_EV_NEED_LOCAL_RTP),
283 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_PROCEEDING),
284 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_COMPLETE),
285 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_ENDED),
286
287 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_COMPLETE_LAYER_3),
288 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_UP_L2),
289 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_CONN_RELEASED),
290
291 OSMO_VALUE_STRING(MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST),
292 OSMO_VALUE_STRING(MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_RESULT),
293 OSMO_VALUE_STRING(MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_ERROR),
294 OSMO_VALUE_STRING(MSC_I_EV_FROM_A_SEND_END_SIGNAL_RESPONSE),
295 {}
296};
297
298static struct osmo_fsm msc_i_fsm = {
299 .name = "msc_i",
300 .states = msc_i_fsm_states,
301 .num_states = ARRAY_SIZE(msc_i_fsm_states),
302 .log_subsys = DMSC,
303 .event_names = msc_i_fsm_event_names,
304 .cleanup = msc_i_fsm_cleanup,
305};
306
307static __attribute__((constructor)) void msc_i_fsm_init(void)
308{
309 OSMO_ASSERT(osmo_fsm_register(&msc_i_fsm) == 0);
310}
311
312/* Send connection-oriented L3 message to RAN peer (MSC->[BSC|RNC]) */
313int msc_i_down_l2(struct msc_i *msc_i, struct msgb *l3)
314{
315 int rc;
316 if (!msc_i->ran_conn) {
317 LOG_MSC_I(msc_i, LOGL_ERROR, "Cannot Tx L2 message: no RAN conn\n");
318 return -EIO;
319 }
320
321 rc = ran_conn_down_l2_co(msc_i->ran_conn, l3, false);
322 if (rc)
323 LOG_MSC_I(msc_i, LOGL_ERROR, "Failed to transfer message down to subscriber (rc=%d)\n", rc);
324 return rc;
325}
326
327struct gsm_network *msc_i_net(const struct msc_i *msc_i)
328{
329 return msub_net(msc_i->c.msub);
330}
331
332struct vlr_subscr *msc_i_vsub(const struct msc_i *msc_i)
333{
Neels Hofmeyr911e5972019-05-09 13:28:26 +0200334 if (!msc_i)
335 return NULL;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100336 return msub_vsub(msc_i->c.msub);
337}
338
339struct msc_i *msc_i_alloc(struct msub *msub, struct ran_infra *ran)
340{
341 return msub_role_alloc(msub, MSC_ROLE_I, &msc_i_fsm, struct msc_i, ran);
342}
343
344/* Send Clear Command and wait for Clear Complete autonomously. "Normally", the MSC-A handles Clear Command and receives
345 * Clear Complete, and then terminates MSC-I directly. This is useful to replace an MSC-I with another MSC-I during
346 * Handover. */
347void msc_i_clear(struct msc_i *msc_i)
348{
349 if (!msc_i)
350 return;
351 /* sanity timeout */
352 osmo_fsm_inst_state_chg(msc_i->c.fi, MSC_I_ST_CLEARING, 60, 0);
353}
354
355void msc_i_cleared(struct msc_i *msc_i)
356{
357 if (!msc_i)
358 return;
359 osmo_fsm_inst_state_chg(msc_i->c.fi, MSC_I_ST_CLEARED, 0, 0);
360}
361
362void msc_i_set_ran_conn(struct msc_i *msc_i, struct ran_conn *new_conn)
363{
364 struct ran_conn *old_conn = msc_i->ran_conn;
365
366 if (old_conn == new_conn)
367 return;
368
369 msc_i->ran_conn = NULL;
370 if (old_conn) {
371 old_conn->msc_role = NULL;
372 ran_conn_close(old_conn);
373 }
374
375 /* Taking a conn over from another MSC role? Make sure the other side forgets about it. */
376 if (new_conn->msc_role)
377 msc_role_forget_conn(new_conn->msc_role, new_conn);
378
379 msc_i->ran_conn = new_conn;
380 msc_i->ran_conn->msc_role = msc_i->c.fi;
381
382 /* Add the RAN conn info to the msub logging */
383 msub_update_id(msc_i->c.msub);
384}