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