blob: eb6c7978446f5af1bf13ff346bf68a6674dba14d [file] [log] [blame]
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001/* The MSC-T role, a transitional RAN connection during Handover. */
2/*
Vadim Yanitskiy999a5932023-05-18 17:22:26 +07003 * (C) 2019 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01004 * 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 <inttypes.h>
25
26#include <osmocom/gsm/gsm48_ie.h>
27
28#include <osmocom/msc/msc_t.h>
29#include <osmocom/msc/msc_a.h>
30#include <osmocom/msc/msc_a_remote.h>
31#include <osmocom/msc/ran_infra.h>
32#include <osmocom/msc/ran_peer.h>
33#include <osmocom/msc/ran_conn.h>
34#include <osmocom/msc/msub.h>
35#include <osmocom/msc/call_leg.h>
36#include <osmocom/msc/rtp_stream.h>
37#include <osmocom/msc/ran_infra.h>
38#include <osmocom/msc/vlr.h>
39#include <osmocom/msc/msc_i.h>
40#include <osmocom/msc/gsm_data.h>
Neels Hofmeyr7934e0d2022-10-31 18:13:47 +010041#include <osmocom/msc/codec_mapping.h>
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010042
43static struct osmo_fsm msc_t_fsm;
44
45static struct msc_t *msc_t_find_by_handover_number(const char *handover_number)
46{
47 struct msub *msub;
48
49 llist_for_each_entry(msub, &msub_list, entry) {
50 struct msc_t *msc_t = msub_msc_t(msub);
51 if (!msc_t)
52 continue;
53 if (!*msc_t->inter_msc.handover_number)
54 continue;
55 if (strcmp(msc_t->inter_msc.handover_number, handover_number))
56 continue;
57 /* Found the assigned Handover Number */
58 return msc_t;
59 }
60 return NULL;
61}
62
63static uint64_t net_handover_number_next(struct gsm_network *net)
64{
65 uint64_t nr;
66 if (net->handover_number.next < net->handover_number.range_start
67 || net->handover_number.next > net->handover_number.range_end)
68 net->handover_number.next = net->handover_number.range_start;
69 nr = net->handover_number.next;
70 net->handover_number.next++;
71 return nr;
72}
73
74static int msc_t_assign_handover_number(struct msc_t *msc_t)
75{
76 int rc;
77 uint64_t started_at;
78 uint64_t ho_nr;
Vadim Yanitskiy8b0737f2019-05-25 19:27:17 +070079 char ho_nr_str[GSM23003_MSISDN_MAX_DIGITS+1];
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010080 struct gsm_network *net = msc_t_net(msc_t);
81 bool usable = false;
82
83 started_at = ho_nr = net_handover_number_next(net);
84
85 if (!ho_nr) {
86 LOG_MSC_T(msc_t, LOGL_ERROR, "No Handover Number range defined in MSC config\n");
87 return -ENOENT;
88 }
89
90 do {
91 rc = snprintf(ho_nr_str, sizeof(ho_nr_str), "%"PRIu64, ho_nr);
92 if (rc <= 0 || rc >= sizeof(ho_nr_str)) {
93 LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot compose Handover Number string (rc=%d)\n", rc);
94 return -EINVAL;
95 }
96
97 if (!msc_t_find_by_handover_number(ho_nr_str)) {
98 usable = true;
99 break;
100 }
101
102 ho_nr = net_handover_number_next(net);
103 } while(ho_nr != started_at);
104
105 if (!usable) {
106 LOG_MSC_T(msc_t, LOGL_ERROR, "No Handover Number available\n");
107 return -EINVAL;
108 }
109
110 LOG_MSC_T(msc_t, LOGL_INFO, "Assigning Handover Number %s\n", ho_nr_str);
111 OSMO_STRLCPY_ARRAY(msc_t->inter_msc.handover_number, ho_nr_str);
112 return 0;
113}
114
115
116static struct msc_t *msc_t_priv(struct osmo_fsm_inst *fi)
117{
118 OSMO_ASSERT(fi);
119 OSMO_ASSERT(fi->fsm == &msc_t_fsm);
120 OSMO_ASSERT(fi->priv);
121 return fi->priv;
122}
123
124/* As a macro to log the caller's source file and line.
125 * Assumes presence of local msc_t variable. */
126#define msc_t_error(fmt, args...) do { \
127 msc_t->ho_success = false; \
128 LOG_MSC_T(msc_t, LOGL_ERROR, fmt, ##args); \
129 msc_t_clear(msc_t); \
130 } while(0)
131
132static void msc_t_send_handover_failure(struct msc_t *msc_t, enum gsm0808_cause cause)
133{
134 struct ran_msg ran_enc_msg = {
135 .msg_type = RAN_MSG_HANDOVER_FAILURE,
136 .handover_failure = {
137 .cause = cause,
138 },
139 };
140 struct an_apdu an_apdu = {
141 .an_proto = msc_t->c.ran->an_proto,
142 .msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc_msg),
143 };
144 msc_t->ho_fail_sent = true;
145 if (!an_apdu.msg)
146 return;
147
148 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, &an_apdu);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100149}
150
151static int msc_t_ho_request_decode_and_store_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
152 const struct ran_msg *ran_dec)
153{
154 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
155
156 if (ran_dec->msg_type != RAN_MSG_HANDOVER_REQUEST) {
157 LOG_MSC_T(msc_t, LOGL_DEBUG, "Expected %s in incoming inter-MSC Handover message, got %s\n",
158 ran_msg_type_name(RAN_MSG_HANDOVER_REQUEST), ran_msg_type_name(ran_dec->msg_type));
159 return -EINVAL;
160 }
161
162 msc_t->inter_msc.cell_id_target = ran_dec->handover_request.cell_id_target;
Andreas Eversberg712b28e2023-06-21 11:17:26 +0200163 msc_t->inter_msc.call_id = ran_dec->handover_request.call_id;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100164
165 /* TODO other parameters...?
166 * Global Call Reference
167 */
168 return 0;
169}
170
171/* On an icoming Handover Request from a remote MSC, we first need to set up an MGW endpoint, because the BSC needs to
172 * know our AoIP Transport Layer Address in the Handover Request message (which obviously the remote MSC doesn't send,
173 * it needs to be our local RTP address). Creating the MGW endpoint this is asynchronous, so we need to store the
174 * Handover Request data to forward to the BSC once the MGW endpoint is known.
175 */
176static int msc_t_decode_and_store_ho_request(struct msc_t *msc_t, const struct an_apdu *an_apdu)
177{
178 if (msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_ho_request_decode_and_store_cb, NULL)) {
179 msc_t_error("Failed to decode Handover Request\n");
180 return -ENOTSUP;
181 }
182 /* Ok, decoding done, and above msc_t_ho_request_decode_and_store_cb() has retrieved what info we need at this
183 * point and stored it in msc_t->inter_msc.* */
184
185 /* We're storing this for use after async events, so need to make sure that each and every bit of data is copied
186 * and no longer references some msgb that might be deallocated when this returns, nor remains in a local stack
187 * variable of some ran_decode implementation. The simplest is to store the entire msgb. */
188 msc_t->inter_msc.ho_request = (struct an_apdu) {
189 .an_proto = an_apdu->an_proto,
190 .msg = msgb_copy(an_apdu->msg, "saved inter-MSC Handover Request"),
191 /* A decoded osmo_gsup_message often still references memory of within the msgb the GSUP was received
192 * in. So, any info from an_apdu->e_info that would be needed would have to be copied separately.
193 * Omit e_info completely. */
194 };
195 return 0;
196}
197
198/* On an incoming Handover Request from a remote MSC, the target cell was transmitted in the Handover Request message.
199 * Find the RAN peer and assign from the cell id decoded above in msc_t_decode_and_store_ho_request(). */
200static int msc_t_find_ran_peer_from_ho_request(struct msc_t *msc_t)
201{
202 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
203 const struct neighbor_ident_entry *nie;
204 struct ran_peer *rp_from_neighbor_ident;
205 struct ran_peer *rp;
206
207 switch (msc_ho_find_target_cell(msc_a, &msc_t->inter_msc.cell_id_target,
208 &nie, &rp_from_neighbor_ident, &rp)) {
209 case MSC_NEIGHBOR_TYPE_REMOTE_MSC:
210 msc_t_error("Incoming Handover Request indicated target cell that belongs to a remote MSC:"
211 " Cell ID: %s; remote MSC: %s\n",
212 gsm0808_cell_id_name(&msc_t->inter_msc.cell_id_target),
213 neighbor_ident_addr_name(&nie->addr));
214 return -EINVAL;
215
216 case MSC_NEIGHBOR_TYPE_NONE:
217 msc_t_error("Incoming Handover Request for unknown cell %s\n",
218 gsm0808_cell_id_name(&msc_t->inter_msc.cell_id_target));
219 return -EINVAL;
220
221 case MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER:
222 /* That's what is expected: a local RAN peer, e.g. BSC, or a remote BSC from neighbor cfg. */
223 if (!rp)
224 rp = rp_from_neighbor_ident;
225 break;
226 }
227
228 OSMO_ASSERT(rp);
229 LOG_MSC_T(msc_t, LOGL_DEBUG, "Incoming Handover Request indicates target cell %s,"
230 " which belongs to RAN peer %s\n",
231 gsm0808_cell_id_name(&msc_t->inter_msc.cell_id_target), rp->fi->id);
232
233 /* Finally we know where to direct the Handover */
234 msc_t_set_ran_peer(msc_t, rp);
235 return 0;
236}
237
238static int msc_t_send_stored_ho_request__decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
239 const struct ran_msg *ran_dec)
240{
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100241 struct an_apdu an_apdu;
242 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
243 struct osmo_sockaddr_str *rtp_ran_local = data;
244
245 /* Copy ran_dec message to un-const so we can add the AoIP Transport Layer Address. All pointer references still
246 * remain on the same memory as ran_dec, which is fine. We're just going to encode it again right away. */
247 struct ran_msg ran_enc = *ran_dec;
248
249 if (ran_dec->msg_type != RAN_MSG_HANDOVER_REQUEST) {
250 LOG_MSC_T(msc_t, LOGL_DEBUG, "Expected %s in incoming inter-MSC Handover message, got %s\n",
251 ran_msg_type_name(RAN_MSG_HANDOVER_REQUEST), ran_msg_type_name(ran_dec->msg_type));
252 return -EINVAL;
253 }
254
255 /* Insert AoIP Transport Layer Address */
256 ran_enc.handover_request.rtp_ran_local = rtp_ran_local;
257
258 /* Finally ready to forward to BSC: encode and send out. */
259 an_apdu = (struct an_apdu){
260 .an_proto = msc_t->inter_msc.ho_request.an_proto,
261 .msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc),
262 };
263 if (!an_apdu.msg)
264 return -EIO;
Vadim Yanitskiyc44342b2021-12-07 18:32:35 +0300265 return msc_t_down_l2_co(msc_t, &an_apdu, true);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100266}
267
268/* The MGW endpoint is created, we know our AoIP Transport Layer Address and can send the Handover Request to the RAN
269 * peer. */
270static int msc_t_send_stored_ho_request(struct msc_t *msc_t)
271{
272 struct osmo_sockaddr_str *rtp_ran_local = call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_RAN);
273 if (!rtp_ran_local) {
274 msc_t_error("Local RTP address towards RAN is not set up properly, cannot send Handover Request\n");
275 return -EINVAL;
276 }
277
278 /* The Handover Request received from the remote MSC is fed through, except we need to insert our local AoIP
279 * Transport Layer Address, i.e. the RTP IP:port of the MGW towards the RAN side. So we actually need to decode,
280 * add the AoIP and re-encode. By nature of decoding, it goes through the decode callback. */
281 return msc_role_ran_decode(msc_t->c.fi, &msc_t->inter_msc.ho_request,
282 msc_t_send_stored_ho_request__decode_cb, rtp_ran_local);
283}
284
285static void msc_t_fsm_pending_first_co_initial_msg(struct osmo_fsm_inst *fi, uint32_t event, void *data)
286{
287 struct msc_t *msc_t = msc_t_priv(fi);
288 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
289 struct an_apdu *an_apdu;
290
291 OSMO_ASSERT(msc_a);
292
293 switch (event) {
294
295 case MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST:
296 /* For an inter-MSC Handover coming in from a remote MSC, we do not yet know the RAN peer and AoIP
297 * Transport Layer Address.
298 * - RAN peer is found by decoding the actual Handover Request message and looking for the Cell
299 * Identifier (Target).
300 * - To be able to tell the BSC about an AoIP Transport Layer Address, we first need to create an MGW
301 * endpoint.
302 * For mere inter-BSC Handover, we know all of the above already. Find out which one this is.
303 */
304 an_apdu = data;
305 if (!msc_a->c.remote_to) {
306 /* Inter-BSC */
307
308 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_REQUEST_ACK, 0, 0);
309 /* Inter-BSC. All should be set up, just forward the message. */
310 if (msc_t_down_l2_co(msc_t, an_apdu, true))
311 msc_t_error("Failed to send AN-APDU to RAN peer\n");
312 } else {
313 /* Inter-MSC */
314
315 if (msc_t->ran_conn) {
316 msc_t_error("Unexpected state for inter-MSC Handover: RAN peer is already set up\n");
317 return;
318 }
319
320 if (msc_t_decode_and_store_ho_request(msc_t, an_apdu))
321 return;
322
323 if (msc_t_find_ran_peer_from_ho_request(msc_t))
324 return;
325
326 /* Relying on timeout of the MGW operations, see onenter() for this state. */
327 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_LOCAL_RTP, 0, 0);
328 }
329 return;
330
331 case MSC_T_EV_CN_CLOSE:
332 msc_t_clear(msc_t);
333 return;
334
335 default:
336 OSMO_ASSERT(false);
337 }
338}
339
340void msc_t_fsm_wait_local_rtp_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
341{
342 struct msc_t *msc_t = msc_t_priv(fi);
343 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
344
345 /* This only happens on inter-MSC HO incoming from a remote MSC */
346 if (!msc_a->c.remote_to) {
347 msc_t_error("Unexpected state: this is not an inter-MSC Handover\n");
348 return;
349 }
350
351 if (msc_t->inter_msc.call_leg) {
352 msc_t_error("Unexpected state: call leg already set up\n");
353 return;
354 }
355
356 msc_t->inter_msc.call_leg = call_leg_alloc(msc_t->c.fi,
357 MSC_EV_CALL_LEG_TERM,
358 MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
Neels Hofmeyr265a4c72019-05-09 16:20:51 +0200359 MSC_EV_CALL_LEG_RTP_COMPLETE);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100360 if (!msc_t->inter_msc.call_leg
Andreas Eversberg712b28e2023-06-21 11:17:26 +0200361 || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_RAN, msc_t->inter_msc.call_id, NULL, NULL, NULL)
362 || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_CN, msc_t->inter_msc.call_id, NULL, NULL, NULL)) {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100363 msc_t_error("Failed to set up call leg\n");
364 return;
365 }
366 /* Now wait for two MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, one per RTP connection */
367}
368
369void msc_t_fsm_wait_local_rtp(struct osmo_fsm_inst *fi, uint32_t event, void *data)
370{
371 struct msc_t *msc_t = msc_t_priv(fi);
372 struct rtp_stream *rtps;
373
374 switch (event) {
375 case MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE:
376 rtps = data;
377 if (!rtps) {
378 msc_t_error("Invalid data for MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE\n");
379 return;
380 }
381 /* If both to-RAN and to-CN sides have a CI set up, we can continue. */
382 if (!call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_RAN)
383 || !call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_CN))
384 return;
385
386 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_REQUEST_ACK, 0, 0);
387 msc_t_send_stored_ho_request(msc_t);
388 return;
389
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100390 case MSC_EV_CALL_LEG_TERM:
391 msc_t->inter_msc.call_leg = NULL;
392 msc_t_error("Failed to set up MGW endpoint\n");
393 return;
394
395 case MSC_MNCC_EV_CALL_ENDED:
396 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
397 return;
398
399 case MSC_T_EV_CN_CLOSE:
400 case MSC_T_EV_MO_CLOSE:
401 msc_t_clear(msc_t);
402 return;
403
404 default:
405 OSMO_ASSERT(false);
406 }
407}
408
409static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct an_apdu *incoming_an_apdu,
410 const struct ran_msg *ran_dec)
411{
412 int rc;
413 struct rtp_stream *rtp_ran = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_RAN] : NULL;
414 struct rtp_stream *rtp_cn = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_CN] : NULL;
415 /* Since it's BCD, it needs rounded-up half the char* length of an MSISDN plus a type byte.
416 * But no need to introduce obscure math to save a few stack bytes, just have more. */
Vadim Yanitskiy8b0737f2019-05-25 19:27:17 +0700417 uint8_t msisdn_enc_buf[GSM23003_MSISDN_MAX_DIGITS+1];
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100418 /* Copy an_apdu and an_apdu->e_info in "copy-on-write" method, because they are const and we
419 * need to add the Handover Number to e_info. */
420 const struct ran_handover_request_ack *r = &ran_dec->handover_request_ack;
421 struct ran_msg ran_enc = *ran_dec;
422 struct osmo_gsup_message e_info = {};
423 struct an_apdu an_apdu = {
424 .an_proto = incoming_an_apdu->an_proto,
425 .e_info = &e_info,
426 };
427 if (incoming_an_apdu->e_info)
428 e_info = *incoming_an_apdu->e_info;
429
430 rc = msc_t_assign_handover_number(msc_t);
431 if (rc)
432 return rc;
433
434 rc = gsm48_encode_bcd_number(msisdn_enc_buf, sizeof(msisdn_enc_buf), 0,
435 msc_t->inter_msc.handover_number);
436 if (rc <= 0)
437 return -EINVAL;
438
439 e_info.msisdn_enc = msisdn_enc_buf;
440 e_info.msisdn_enc_len = rc;
441
442 /* Also need to fetch the RTP IP:port from AoIP Transport Address IE to tell the MGW about it */
443 if (rtp_ran) {
Neels Hofmeyr84ce2062019-10-05 05:15:25 +0200444 if (osmo_sockaddr_str_is_nonzero(&r->remote_rtp)) {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100445 LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got " OSMO_SOCKADDR_STR_FMT "\n",
446 OSMO_SOCKADDR_STR_FMT_ARGS(&r->remote_rtp));
447 rtp_stream_set_remote_addr(rtp_ran, &r->remote_rtp);
448 } else {
449 LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP IP:port in Handover Request Ack\n");
450 }
451 if (r->codec_present) {
Neels Hofmeyr7934e0d2022-10-31 18:13:47 +0100452 const struct codec_mapping *m = codec_mapping_by_gsm0808_speech_codec_type(r->codec.type);
453 /* TODO: use codec_mapping_by_gsm0808_speech_codec() to also match on codec.cfg */
454 if (!m) {
455 LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot resolve codec in Handover Request Ack: %s / %s\n",
456 gsm0808_speech_codec_type_name(r->codec.type),
457 m ? sdp_audio_codec_to_str(&m->sdp) : "(unknown)");
458 } else {
459 LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got codec %s / %s\n",
460 gsm0808_speech_codec_type_name(r->codec.type),
461 sdp_audio_codec_to_str(&m->sdp));
462 rtp_stream_set_one_codec(rtp_ran, &m->sdp);
463 if (rtp_cn)
464 rtp_stream_set_one_codec(rtp_cn, &m->sdp);
465 }
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100466 } else {
467 LOG_MSC_T(msc_t, LOGL_DEBUG, "No codec in Handover Request Ack\n");
468 }
469 rtp_stream_commit(rtp_ran);
470 } else {
471 LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP to RAN set up yet\n");
472 }
473
474 /* Remove that AoIP Transport Layer IE so it doesn't get sent to the remote MSC */
475 ran_enc.handover_request_ack.remote_rtp = (struct osmo_sockaddr_str){};
476
477 an_apdu.msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc);
478 if (!an_apdu.msg)
479 return -EIO;
480 /* Send to remote MSC via msc_a_remote role */
Vadim Yanitskiyc44342b2021-12-07 18:32:35 +0300481 return msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE, &an_apdu);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100482}
483
484static int msc_t_wait_ho_request_ack_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
485 const struct ran_msg *ran_dec)
486{
487 int rc;
488 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
489 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
490 const struct an_apdu *an_apdu = data;
491
492 switch (ran_dec->msg_type) {
493 case RAN_MSG_HANDOVER_REQUEST_ACK:
494 if (msc_a->c.remote_to) {
495 /* inter-MSC. Add Handover Number, remove AoIP Transport Layer Address. */
496 rc = msc_t_patch_and_send_ho_request_ack(msc_t, an_apdu, ran_dec);
497 } else {
498 /* inter-BSC. Just send as-is, with correct event. */
499 rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE,
500 an_apdu);
501 }
502 if (rc)
503 msc_t_error("Failed to send HO Request Ack\n");
504 else
505 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_COMPLETE, 0, 0);
506 return 0;
507
508 case RAN_MSG_HANDOVER_FAILURE:
509 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, an_apdu);
510 return 0;
511
512 case RAN_MSG_CLEAR_REQUEST:
513 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
514 an_apdu);
515 return 0;
516
517 default:
518 LOG_MSC_T(msc_t, LOGL_ERROR, "Unexpected message during Prepare Handover procedure: %s\n",
519 ran_msg_type_name(ran_dec->msg_type));
520 /* Let's just forward anyway. */
521 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
522 an_apdu);
523 return 0;
524 }
525}
526
527static void msc_t_fsm_wait_ho_request_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
528{
529 struct msc_t *msc_t = msc_t_priv(fi);
530 struct an_apdu *an_apdu;
531
532 switch (event) {
533
534 case MSC_EV_FROM_RAN_UP_L2:
535 an_apdu = data;
536 /* For inter-MSC Handover, we need to examine the message type. Depending on the response, we must
537 * dispatch MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE or MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, which
538 * ensures the correct E-interface message type. And we need to include the Handover Number.
539 * For mere inter-BSC Handover, we know that our osmo-msc internals don't care much about which event
540 * dispatches a Handover Failure or Handover Request Ack, so we could skip the decoding. But it is a
541 * premature optimization that complicates comparing an inter-BSC with an inter-MSC HO. */
542 msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_wait_ho_request_ack_decode_cb, an_apdu);
543 /* Action continues in msc_t_wait_ho_request_ack_decode_cb() */
544 return;
545
546 case MSC_EV_FROM_RAN_CONN_RELEASED:
547 msc_t_clear(msc_t);
548 return;
549
550 case MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST:
551 an_apdu = data;
552 msc_t_down_l2_co(msc_t, an_apdu, false);
553 return;
554
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100555 case MSC_EV_CALL_LEG_TERM:
556 msc_t->inter_msc.call_leg = NULL;
557 msc_t_error("Failed to set up MGW endpoint\n");
558 return;
559
560 case MSC_MNCC_EV_CALL_ENDED:
561 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
562 return;
563
564 case MSC_T_EV_CN_CLOSE:
565 case MSC_T_EV_MO_CLOSE:
566 msc_t_clear(msc_t);
567 return;
568
569 default:
570 OSMO_ASSERT(false);
571 }
572}
573
574static int msc_t_wait_ho_complete_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
575 const struct ran_msg *ran_dec)
576{
577 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
578 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
579 struct msc_i *msc_i;
580 const struct an_apdu *an_apdu = data;
581
582 switch (ran_dec->msg_type) {
583 case RAN_MSG_HANDOVER_COMPLETE:
584 msc_t->ho_success = true;
585
586 /* For both inter-BSC local to this MSC and inter-MSC Handover for a remote MSC-A, forward the Handover
587 * Complete message so that the MSC-A can change the MSC-T (transitional) to a proper MSC-I role. */
588 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST, an_apdu);
589
590 /* For inter-BSC Handover, the Handover Complete event has already cleaned up this msc_t, and it is
591 * already gone and deallocated. */
592 if (!msc_a->c.remote_to)
593 return 0;
594
595 /* For inter-MSC Handover, the remote MSC-A only turns its msc_t_remote into an msc_i_remote on
596 * the same GSUP link. We are here on the MSC-B side of the GSUP link and have to take care of
597 * creating an MSC-I over here to match the msc_i_remote at MSC-A. */
598 msc_i = msc_i_alloc(msc_t->c.msub, msc_t->c.ran);
599 if (!msc_i) {
600 msc_t_error("Failed to create MSC-I role\n");
601 return -1;
602 }
603
604 msc_i->inter_msc.mncc_forwarding_to_remote_cn = msc_t->inter_msc.mncc_forwarding_to_remote_cn;
605 mncc_call_reparent(msc_i->inter_msc.mncc_forwarding_to_remote_cn,
606 msc_i->c.fi, -1, MSC_MNCC_EV_CALL_ENDED, NULL, NULL);
607
608 msc_i->inter_msc.call_leg = msc_t->inter_msc.call_leg;
609 call_leg_reparent(msc_i->inter_msc.call_leg,
610 msc_i->c.fi,
611 MSC_EV_CALL_LEG_TERM,
612 MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
Neels Hofmeyr265a4c72019-05-09 16:20:51 +0200613 MSC_EV_CALL_LEG_RTP_COMPLETE);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100614
615 /* msc_i_set_ran_conn() properly "steals" the ran_conn from msc_t */
616 msc_i_set_ran_conn(msc_i, msc_t->ran_conn);
617
618 /* Nicked everything worth keeping from MSC-T, discard now. */
619 msc_t_clear(msc_t);
620 return 0;
621
622 case RAN_MSG_HANDOVER_FAILURE:
623 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, an_apdu);
624 return 0;
625
626 default:
627 LOG_MSC_T(msc_t, LOGL_ERROR, "Unexpected message during Prepare Handover procedure: %s\n",
628 ran_msg_type_name(ran_dec->msg_type));
629 /* Let's just forward anyway. Fall thru */
630 case RAN_MSG_HANDOVER_DETECT:
631 case RAN_MSG_CLEAR_REQUEST:
632 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
633 an_apdu);
634 return 0;
635 }
636}
637
638static void msc_t_fsm_wait_ho_complete(struct osmo_fsm_inst *fi, uint32_t event, void *data)
639{
640 struct msc_t *msc_t = msc_t_priv(fi);
641 struct an_apdu *an_apdu;
642
643 switch (event) {
644
645 case MSC_EV_FROM_RAN_UP_L2:
646 an_apdu = data;
647 /* We need to catch the Handover Complete message in order to send it as a SendEndSignal Request */
648 msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_wait_ho_complete_decode_cb, an_apdu);
649 return;
650
651 case MSC_EV_FROM_RAN_CONN_RELEASED:
652 msc_t_clear(msc_t);
653 return;
654
655 case MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST:
656 an_apdu = data;
657 msc_t_down_l2_co(msc_t, an_apdu, false);
658 return;
659
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100660 case MSC_EV_CALL_LEG_TERM:
661 msc_t->inter_msc.call_leg = NULL;
662 msc_t_error("Failed to set up MGW endpoint\n");
663 return;
664
665 case MSC_MNCC_EV_CALL_ENDED:
666 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
667 return;
668
669 case MSC_T_EV_CN_CLOSE:
670 case MSC_T_EV_MO_CLOSE:
671 msc_t_clear(msc_t);
672 return;
673
674 default:
675 OSMO_ASSERT(false);
676 }
677}
678
679void msc_t_mncc_cb(struct mncc_call *mncc_call, const union mncc_msg *mncc_msg, void *data)
680{
681 struct msc_t *msc_t = data;
682 struct gsm_mncc_number nr = {
683 .plan = 1,
684 };
685 OSMO_STRLCPY_ARRAY(nr.number, msc_t->inter_msc.handover_number);
686
687 switch (mncc_msg->msg_type) {
688 case MNCC_RTP_CREATE:
689 mncc_call_incoming_tx_setup_cnf(mncc_call, &nr);
690 return;
691 default:
692 return;
693 }
694}
695
696struct mncc_call *msc_t_check_call_to_handover_number(const struct gsm_mncc *msg)
697{
698 struct msc_t *msc_t;
699 const char *handover_number;
700 struct mncc_call_incoming_req req;
701 struct mncc_call *mncc_call;
702
703 if (!(msg->fields & MNCC_F_CALLED))
704 return NULL;
705
706 handover_number = msg->called.number;
707 msc_t = msc_t_find_by_handover_number(handover_number);
708
709 if (!msc_t)
710 return NULL;
711
712 if (msc_t->inter_msc.mncc_forwarding_to_remote_cn) {
713 LOG_MSC_T(msc_t, LOGL_ERROR, "Incoming call for inter-MSC call forwarding,"
714 " but this MSC-T role already has an MNCC FSM set up\n");
715 return NULL;
716 }
717
718 if (!msc_t->inter_msc.call_leg
719 || !msc_t->inter_msc.call_leg->rtp[RTP_TO_CN]) {
720 LOG_MSC_T(msc_t, LOGL_ERROR, "Incoming call for inter-MSC call forwarding,"
721 " but this MSC-T has no RTP stream ready for MNCC\n");
722 return NULL;
723 }
724
725 mncc_call = mncc_call_alloc(msc_t_vsub(msc_t),
726 msc_t->c.fi,
727 MSC_MNCC_EV_CALL_COMPLETE,
728 MSC_MNCC_EV_CALL_ENDED,
729 msc_t_mncc_cb, msc_t);
730 if (!mncc_call) {
731 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
732 return NULL;
733 }
734 msc_t->inter_msc.mncc_forwarding_to_remote_cn = mncc_call;
735
736 if (mncc_call_set_rtp_stream(mncc_call, msc_t->inter_msc.call_leg->rtp[RTP_TO_CN])) {
737 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
738 osmo_fsm_inst_term(mncc_call->fi, OSMO_FSM_TERM_REGULAR, NULL);
739 return NULL;
740 }
741
742 req = (struct mncc_call_incoming_req){
743 .setup_req_msg = *msg,
744 .bearer_cap_present = true,
745 .bearer_cap = {
746 /* TODO derive values from actual config */
747 /* FIXME are there no defines or enums for these numbers!? */
748 /* Table 10.5.102/3GPP TS 24.008: Bearer capability information element:
749 * octet 3 of bearer cap for speech says 3 = "1 1 dual rate support MS/full rate speech version
750 * 1 preferred, half rate speech version 1 also supported" */
751 .radio = 3,
752 /* Table 10.5.103/3GPP TS 24.008 Bearer capability information element:
753 * 0: FR1, 2: FR2, 4: FR3, 1: HR1, 5: HR3, actually in this order. -1 marks the end of the list. */
754 .speech_ver = { 0, 2, 4, 1, 5, -1 },
755 },
756 };
757 if (mncc_call_incoming_start(mncc_call, &req)) {
758 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
759 osmo_fsm_inst_term(mncc_call->fi, OSMO_FSM_TERM_REGULAR, NULL);
760 return NULL;
761 }
762 return mncc_call;
763}
764
765static void msc_t_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
766{
767 struct msc_t *msc_t = msc_t_priv(fi);
768
769 if (!msc_t->ho_success && !msc_t->ho_fail_sent)
770 msc_t_send_handover_failure(msc_t, GSM0808_CAUSE_EQUIPMENT_FAILURE);
771
772 if (msc_t->ran_conn)
773 ran_conn_msc_role_gone(msc_t->ran_conn, msc_t->c.fi);
774}
775
776#define S(x) (1 << (x))
777
778static const struct osmo_fsm_state msc_t_fsm_states[] = {
779 [MSC_T_ST_PENDING_FIRST_CO_INITIAL_MSG] = {
780 .name = "PENDING_FIRST_CO_INITIAL_MSG",
781 .action = msc_t_fsm_pending_first_co_initial_msg,
782 .in_event_mask = 0
783 | S(MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST)
784 | S(MSC_T_EV_CN_CLOSE)
785 ,
786 .out_state_mask = 0
787 | S(MSC_T_ST_WAIT_LOCAL_RTP)
788 | S(MSC_T_ST_WAIT_HO_REQUEST_ACK)
789 ,
790 },
791 [MSC_T_ST_WAIT_LOCAL_RTP] = {
792 .name = "WAIT_LOCAL_RTP",
793 .onenter = msc_t_fsm_wait_local_rtp_onenter,
794 .action = msc_t_fsm_wait_local_rtp,
795 .in_event_mask = 0
796 | S(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE)
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100797 | S(MSC_EV_CALL_LEG_TERM)
798 | S(MSC_MNCC_EV_CALL_ENDED)
799 | S(MSC_T_EV_CN_CLOSE)
800 ,
801 .out_state_mask = 0
802 | S(MSC_T_ST_WAIT_HO_REQUEST_ACK)
803 ,
804 },
805 [MSC_T_ST_WAIT_HO_REQUEST_ACK] = {
806 .name = "WAIT_HO_REQUEST_ACK",
807 .action = msc_t_fsm_wait_ho_request_ack,
808 .in_event_mask = 0
809 | S(MSC_EV_FROM_RAN_UP_L2)
810 | S(MSC_EV_FROM_RAN_CONN_RELEASED)
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100811 | S(MSC_EV_CALL_LEG_TERM)
812 | S(MSC_MNCC_EV_CALL_ENDED)
813 | S(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
814 | S(MSC_T_EV_CN_CLOSE)
815 | S(MSC_T_EV_MO_CLOSE)
816 ,
817 .out_state_mask = 0
818 | S(MSC_T_ST_WAIT_HO_COMPLETE)
819 ,
820 },
821 [MSC_T_ST_WAIT_HO_COMPLETE] = {
822 .name = "WAIT_HO_COMPLETE",
823 .action = msc_t_fsm_wait_ho_complete,
824 .in_event_mask = 0
825 | S(MSC_EV_FROM_RAN_UP_L2)
826 | S(MSC_EV_FROM_RAN_CONN_RELEASED)
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100827 | S(MSC_EV_CALL_LEG_TERM)
828 | S(MSC_MNCC_EV_CALL_ENDED)
829 | S(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
830 | S(MSC_T_EV_CN_CLOSE)
831 | S(MSC_T_EV_MO_CLOSE)
832 ,
833 },
834};
835
836const struct value_string msc_t_fsm_event_names[] = {
837 OSMO_VALUE_STRING(MSC_REMOTE_EV_RX_GSUP),
838 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE),
839 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_COMPLETE),
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100840 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_TERM),
841 OSMO_VALUE_STRING(MSC_MNCC_EV_NEED_LOCAL_RTP),
842 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_PROCEEDING),
843 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_COMPLETE),
844 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_ENDED),
845
846 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_COMPLETE_LAYER_3),
847 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_UP_L2),
848 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_CONN_RELEASED),
849
850 OSMO_VALUE_STRING(MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST),
851 OSMO_VALUE_STRING(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST),
852 OSMO_VALUE_STRING(MSC_T_EV_CN_CLOSE),
853 OSMO_VALUE_STRING(MSC_T_EV_MO_CLOSE),
854 OSMO_VALUE_STRING(MSC_T_EV_CLEAR_COMPLETE),
855 {}
856};
857
858static struct osmo_fsm msc_t_fsm = {
859 .name = "msc_t",
860 .states = msc_t_fsm_states,
861 .num_states = ARRAY_SIZE(msc_t_fsm_states),
862 .log_subsys = DMSC,
863 .event_names = msc_t_fsm_event_names,
864 .cleanup = msc_t_fsm_cleanup,
865};
866
867static __attribute__((constructor)) void msc_t_fsm_init(void)
868{
869 OSMO_ASSERT(osmo_fsm_register(&msc_t_fsm) == 0);
870}
871
872/* Send connection-oriented L3 message to RAN peer (MSC->[BSC|RNC]) */
873int msc_t_down_l2_co(struct msc_t *msc_t, const struct an_apdu *an_apdu, bool initial)
874{
875 int rc;
876 if (!msc_t->ran_conn) {
877 LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot Tx L2 message: no RAN conn\n");
878 return -EIO;
879 }
880
881 if (an_apdu->an_proto != msc_t->c.ran->an_proto) {
882 LOG_MSC_T(msc_t, LOGL_ERROR, "Mismatching AN-APDU proto: %s -- Dropping message\n",
883 an_proto_name(an_apdu->an_proto));
884 return -EIO;
885 }
886
887 rc = ran_conn_down_l2_co(msc_t->ran_conn, an_apdu->msg, initial);
888 if (rc)
889 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to transfer message down to new RAN peer (rc=%d)\n", rc);
890 return rc;
891}
892
893struct gsm_network *msc_t_net(const struct msc_t *msc_t)
894{
895 return msub_net(msc_t->c.msub);
896}
897
898struct vlr_subscr *msc_t_vsub(const struct msc_t *msc_t)
899{
Neels Hofmeyr911e5972019-05-09 13:28:26 +0200900 if (!msc_t)
901 return NULL;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100902 return msub_vsub(msc_t->c.msub);
903}
904
905struct msc_t *msc_t_alloc_without_ran_peer(struct msub *msub, struct ran_infra *ran)
906{
907 struct msc_t *msc_t;
908
909 msub_role_alloc(msub, MSC_ROLE_T, &msc_t_fsm, struct msc_t, ran);
910 msc_t = msub_msc_t(msub);
911 if (!msc_t)
912 return NULL;
913
914 return msc_t;
915}
916
917int msc_t_set_ran_peer(struct msc_t *msc_t, struct ran_peer *ran_peer)
918{
919 if (!ran_peer || !ran_peer->sri || !ran_peer->sri->ran) {
920 LOG_MSC_T(msc_t, LOGL_ERROR, "Invalid RAN peer: %s\n", ran_peer ? ran_peer->fi->id : "NULL");
921 return -EINVAL;
922 }
923
924 if (ran_peer->sri->ran != msc_t->c.ran) {
925 LOG_MSC_T(msc_t, LOGL_ERROR, "This MSC-T was set up for %s, cannot assign RAN peer for %s\n",
926 osmo_rat_type_name(msc_t->c.ran->type), osmo_rat_type_name(ran_peer->sri->ran->type));
927 return -EINVAL;
928 }
929
930 /* Create a new ran_conn with a fresh conn_id for the outgoing initial message. The msc_t FSM definition ensures
931 * that the first message sent or received is a Connection-Oriented Initial message. */
932 msc_t->ran_conn = ran_conn_create_outgoing(ran_peer);
933 if (!msc_t->ran_conn) {
934 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to create outgoing RAN conn\n");
935 return -EINVAL;
936 }
937 msc_t->ran_conn->msc_role = msc_t->c.fi;
938 msub_update_id(msc_t->c.msub);
939 return 0;
940}
941
942struct msc_t *msc_t_alloc(struct msub *msub, struct ran_peer *ran_peer)
943{
944 struct msc_t *msc_t = msc_t_alloc_without_ran_peer(msub, ran_peer->sri->ran);
945 if (!msc_t)
946 return NULL;
947 if (msc_t_set_ran_peer(msc_t, ran_peer)) {
948 msc_t_clear(msc_t);
949 return NULL;
950 }
951 return msc_t;
952}
953
954void msc_t_clear(struct msc_t *msc_t)
955{
956 if (!msc_t)
957 return;
958 osmo_fsm_inst_term(msc_t->c.fi, OSMO_FSM_TERM_REGULAR, msc_t->c.fi);
959}