blob: 05df9cb5dc7cf68df3c21ea0046cd15cdc6f9d3b [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),
281 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_RELEASED),
282 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_TERM),
283 OSMO_VALUE_STRING(MSC_MNCC_EV_NEED_LOCAL_RTP),
284 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_PROCEEDING),
285 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_COMPLETE),
286 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_ENDED),
287
288 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_COMPLETE_LAYER_3),
289 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_UP_L2),
290 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_CONN_RELEASED),
291
292 OSMO_VALUE_STRING(MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST),
293 OSMO_VALUE_STRING(MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_RESULT),
294 OSMO_VALUE_STRING(MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_ERROR),
295 OSMO_VALUE_STRING(MSC_I_EV_FROM_A_SEND_END_SIGNAL_RESPONSE),
296 {}
297};
298
299static struct osmo_fsm msc_i_fsm = {
300 .name = "msc_i",
301 .states = msc_i_fsm_states,
302 .num_states = ARRAY_SIZE(msc_i_fsm_states),
303 .log_subsys = DMSC,
304 .event_names = msc_i_fsm_event_names,
305 .cleanup = msc_i_fsm_cleanup,
306};
307
308static __attribute__((constructor)) void msc_i_fsm_init(void)
309{
310 OSMO_ASSERT(osmo_fsm_register(&msc_i_fsm) == 0);
311}
312
313/* Send connection-oriented L3 message to RAN peer (MSC->[BSC|RNC]) */
314int msc_i_down_l2(struct msc_i *msc_i, struct msgb *l3)
315{
316 int rc;
317 if (!msc_i->ran_conn) {
318 LOG_MSC_I(msc_i, LOGL_ERROR, "Cannot Tx L2 message: no RAN conn\n");
319 return -EIO;
320 }
321
322 rc = ran_conn_down_l2_co(msc_i->ran_conn, l3, false);
323 if (rc)
324 LOG_MSC_I(msc_i, LOGL_ERROR, "Failed to transfer message down to subscriber (rc=%d)\n", rc);
325 return rc;
326}
327
328struct gsm_network *msc_i_net(const struct msc_i *msc_i)
329{
330 return msub_net(msc_i->c.msub);
331}
332
333struct vlr_subscr *msc_i_vsub(const struct msc_i *msc_i)
334{
Neels Hofmeyr911e5972019-05-09 13:28:26 +0200335 if (!msc_i)
336 return NULL;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100337 return msub_vsub(msc_i->c.msub);
338}
339
340struct msc_i *msc_i_alloc(struct msub *msub, struct ran_infra *ran)
341{
342 return msub_role_alloc(msub, MSC_ROLE_I, &msc_i_fsm, struct msc_i, ran);
343}
344
345/* Send Clear Command and wait for Clear Complete autonomously. "Normally", the MSC-A handles Clear Command and receives
346 * Clear Complete, and then terminates MSC-I directly. This is useful to replace an MSC-I with another MSC-I during
347 * Handover. */
348void msc_i_clear(struct msc_i *msc_i)
349{
350 if (!msc_i)
351 return;
352 /* sanity timeout */
353 osmo_fsm_inst_state_chg(msc_i->c.fi, MSC_I_ST_CLEARING, 60, 0);
354}
355
356void msc_i_cleared(struct msc_i *msc_i)
357{
358 if (!msc_i)
359 return;
360 osmo_fsm_inst_state_chg(msc_i->c.fi, MSC_I_ST_CLEARED, 0, 0);
361}
362
363void msc_i_set_ran_conn(struct msc_i *msc_i, struct ran_conn *new_conn)
364{
365 struct ran_conn *old_conn = msc_i->ran_conn;
366
367 if (old_conn == new_conn)
368 return;
369
370 msc_i->ran_conn = NULL;
371 if (old_conn) {
372 old_conn->msc_role = NULL;
373 ran_conn_close(old_conn);
374 }
375
376 /* Taking a conn over from another MSC role? Make sure the other side forgets about it. */
377 if (new_conn->msc_role)
378 msc_role_forget_conn(new_conn->msc_role, new_conn);
379
380 msc_i->ran_conn = new_conn;
381 msc_i->ran_conn->msc_role = msc_i->c.fi;
382
383 /* Add the RAN conn info to the msub logging */
384 msub_update_id(msc_i->c.msub);
385}