blob: ec5531fc23e7af5b808a1c5682526101188c3957 [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;
78 char ho_nr_str[VLR_MSISDN_LENGTH+1];
79 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);
148 msgb_free(an_apdu.msg);
149}
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;
163 msc_t->inter_msc.callref = ran_dec->handover_request.call_id;
164
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{
241 int rc;
242 struct an_apdu an_apdu;
243 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
244 struct osmo_sockaddr_str *rtp_ran_local = data;
245
246 /* Copy ran_dec message to un-const so we can add the AoIP Transport Layer Address. All pointer references still
247 * remain on the same memory as ran_dec, which is fine. We're just going to encode it again right away. */
248 struct ran_msg ran_enc = *ran_dec;
249
250 if (ran_dec->msg_type != RAN_MSG_HANDOVER_REQUEST) {
251 LOG_MSC_T(msc_t, LOGL_DEBUG, "Expected %s in incoming inter-MSC Handover message, got %s\n",
252 ran_msg_type_name(RAN_MSG_HANDOVER_REQUEST), ran_msg_type_name(ran_dec->msg_type));
253 return -EINVAL;
254 }
255
256 /* Insert AoIP Transport Layer Address */
257 ran_enc.handover_request.rtp_ran_local = rtp_ran_local;
258
259 /* Finally ready to forward to BSC: encode and send out. */
260 an_apdu = (struct an_apdu){
261 .an_proto = msc_t->inter_msc.ho_request.an_proto,
262 .msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc),
263 };
264 if (!an_apdu.msg)
265 return -EIO;
266 rc = msc_t_down_l2_co(msc_t, &an_apdu, true);
267 msgb_free(an_apdu.msg);
268 return rc;
269}
270
271/* The MGW endpoint is created, we know our AoIP Transport Layer Address and can send the Handover Request to the RAN
272 * peer. */
273static int msc_t_send_stored_ho_request(struct msc_t *msc_t)
274{
275 struct osmo_sockaddr_str *rtp_ran_local = call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_RAN);
276 if (!rtp_ran_local) {
277 msc_t_error("Local RTP address towards RAN is not set up properly, cannot send Handover Request\n");
278 return -EINVAL;
279 }
280
281 /* The Handover Request received from the remote MSC is fed through, except we need to insert our local AoIP
282 * Transport Layer Address, i.e. the RTP IP:port of the MGW towards the RAN side. So we actually need to decode,
283 * add the AoIP and re-encode. By nature of decoding, it goes through the decode callback. */
284 return msc_role_ran_decode(msc_t->c.fi, &msc_t->inter_msc.ho_request,
285 msc_t_send_stored_ho_request__decode_cb, rtp_ran_local);
286}
287
288static void msc_t_fsm_pending_first_co_initial_msg(struct osmo_fsm_inst *fi, uint32_t event, void *data)
289{
290 struct msc_t *msc_t = msc_t_priv(fi);
291 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
292 struct an_apdu *an_apdu;
293
294 OSMO_ASSERT(msc_a);
295
296 switch (event) {
297
298 case MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST:
299 /* For an inter-MSC Handover coming in from a remote MSC, we do not yet know the RAN peer and AoIP
300 * Transport Layer Address.
301 * - RAN peer is found by decoding the actual Handover Request message and looking for the Cell
302 * Identifier (Target).
303 * - To be able to tell the BSC about an AoIP Transport Layer Address, we first need to create an MGW
304 * endpoint.
305 * For mere inter-BSC Handover, we know all of the above already. Find out which one this is.
306 */
307 an_apdu = data;
308 if (!msc_a->c.remote_to) {
309 /* Inter-BSC */
310
311 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_REQUEST_ACK, 0, 0);
312 /* Inter-BSC. All should be set up, just forward the message. */
313 if (msc_t_down_l2_co(msc_t, an_apdu, true))
314 msc_t_error("Failed to send AN-APDU to RAN peer\n");
315 } else {
316 /* Inter-MSC */
317
318 if (msc_t->ran_conn) {
319 msc_t_error("Unexpected state for inter-MSC Handover: RAN peer is already set up\n");
320 return;
321 }
322
323 if (msc_t_decode_and_store_ho_request(msc_t, an_apdu))
324 return;
325
326 if (msc_t_find_ran_peer_from_ho_request(msc_t))
327 return;
328
329 /* Relying on timeout of the MGW operations, see onenter() for this state. */
330 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_LOCAL_RTP, 0, 0);
331 }
332 return;
333
334 case MSC_T_EV_CN_CLOSE:
335 msc_t_clear(msc_t);
336 return;
337
338 default:
339 OSMO_ASSERT(false);
340 }
341}
342
343void msc_t_fsm_wait_local_rtp_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
344{
345 struct msc_t *msc_t = msc_t_priv(fi);
346 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
347
348 /* This only happens on inter-MSC HO incoming from a remote MSC */
349 if (!msc_a->c.remote_to) {
350 msc_t_error("Unexpected state: this is not an inter-MSC Handover\n");
351 return;
352 }
353
354 if (msc_t->inter_msc.call_leg) {
355 msc_t_error("Unexpected state: call leg already set up\n");
356 return;
357 }
358
359 msc_t->inter_msc.call_leg = call_leg_alloc(msc_t->c.fi,
360 MSC_EV_CALL_LEG_TERM,
361 MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
362 MSC_EV_CALL_LEG_RTP_COMPLETE,
363 MSC_EV_CALL_LEG_RTP_RELEASED);
364 if (!msc_t->inter_msc.call_leg
365 || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_RAN, msc_t->inter_msc.callref, NULL, NULL, NULL)
366 || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_CN, msc_t->inter_msc.callref, NULL, NULL, NULL)) {
367 msc_t_error("Failed to set up call leg\n");
368 return;
369 }
370 /* Now wait for two MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, one per RTP connection */
371}
372
373void msc_t_fsm_wait_local_rtp(struct osmo_fsm_inst *fi, uint32_t event, void *data)
374{
375 struct msc_t *msc_t = msc_t_priv(fi);
376 struct rtp_stream *rtps;
377
378 switch (event) {
379 case MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE:
380 rtps = data;
381 if (!rtps) {
382 msc_t_error("Invalid data for MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE\n");
383 return;
384 }
385 /* If both to-RAN and to-CN sides have a CI set up, we can continue. */
386 if (!call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_RAN)
387 || !call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_CN))
388 return;
389
390 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_REQUEST_ACK, 0, 0);
391 msc_t_send_stored_ho_request(msc_t);
392 return;
393
394 case MSC_EV_CALL_LEG_RTP_RELEASED:
395 case MSC_EV_CALL_LEG_TERM:
396 msc_t->inter_msc.call_leg = NULL;
397 msc_t_error("Failed to set up MGW endpoint\n");
398 return;
399
400 case MSC_MNCC_EV_CALL_ENDED:
401 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
402 return;
403
404 case MSC_T_EV_CN_CLOSE:
405 case MSC_T_EV_MO_CLOSE:
406 msc_t_clear(msc_t);
407 return;
408
409 default:
410 OSMO_ASSERT(false);
411 }
412}
413
414static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct an_apdu *incoming_an_apdu,
415 const struct ran_msg *ran_dec)
416{
417 int rc;
418 struct rtp_stream *rtp_ran = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_RAN] : NULL;
419 struct rtp_stream *rtp_cn = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_CN] : NULL;
420 /* Since it's BCD, it needs rounded-up half the char* length of an MSISDN plus a type byte.
421 * But no need to introduce obscure math to save a few stack bytes, just have more. */
422 uint8_t msisdn_enc_buf[VLR_MSISDN_LENGTH + 1];
423 /* Copy an_apdu and an_apdu->e_info in "copy-on-write" method, because they are const and we
424 * need to add the Handover Number to e_info. */
425 const struct ran_handover_request_ack *r = &ran_dec->handover_request_ack;
426 struct ran_msg ran_enc = *ran_dec;
427 struct osmo_gsup_message e_info = {};
428 struct an_apdu an_apdu = {
429 .an_proto = incoming_an_apdu->an_proto,
430 .e_info = &e_info,
431 };
432 if (incoming_an_apdu->e_info)
433 e_info = *incoming_an_apdu->e_info;
434
435 rc = msc_t_assign_handover_number(msc_t);
436 if (rc)
437 return rc;
438
439 rc = gsm48_encode_bcd_number(msisdn_enc_buf, sizeof(msisdn_enc_buf), 0,
440 msc_t->inter_msc.handover_number);
441 if (rc <= 0)
442 return -EINVAL;
443
444 e_info.msisdn_enc = msisdn_enc_buf;
445 e_info.msisdn_enc_len = rc;
446
447 /* Also need to fetch the RTP IP:port from AoIP Transport Address IE to tell the MGW about it */
448 if (rtp_ran) {
449 if (osmo_sockaddr_str_is_set(&r->remote_rtp)) {
450 LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got " OSMO_SOCKADDR_STR_FMT "\n",
451 OSMO_SOCKADDR_STR_FMT_ARGS(&r->remote_rtp));
452 rtp_stream_set_remote_addr(rtp_ran, &r->remote_rtp);
453 } else {
454 LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP IP:port in Handover Request Ack\n");
455 }
456 if (r->codec_present) {
457 LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got %s\n",
458 osmo_mgcpc_codec_name(r->codec));
459 rtp_stream_set_codec(rtp_ran, r->codec);
460 if (rtp_cn)
461 rtp_stream_set_codec(rtp_cn, r->codec);
462 } else {
463 LOG_MSC_T(msc_t, LOGL_DEBUG, "No codec in Handover Request Ack\n");
464 }
465 rtp_stream_commit(rtp_ran);
466 } else {
467 LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP to RAN set up yet\n");
468 }
469
470 /* Remove that AoIP Transport Layer IE so it doesn't get sent to the remote MSC */
471 ran_enc.handover_request_ack.remote_rtp = (struct osmo_sockaddr_str){};
472
473 an_apdu.msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc);
474 if (!an_apdu.msg)
475 return -EIO;
476 /* Send to remote MSC via msc_a_remote role */
477 rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE, &an_apdu);
478 msgb_free(an_apdu.msg);
479 return rc;
480}
481
482static int msc_t_wait_ho_request_ack_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
483 const struct ran_msg *ran_dec)
484{
485 int rc;
486 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
487 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
488 const struct an_apdu *an_apdu = data;
489
490 switch (ran_dec->msg_type) {
491 case RAN_MSG_HANDOVER_REQUEST_ACK:
492 if (msc_a->c.remote_to) {
493 /* inter-MSC. Add Handover Number, remove AoIP Transport Layer Address. */
494 rc = msc_t_patch_and_send_ho_request_ack(msc_t, an_apdu, ran_dec);
495 } else {
496 /* inter-BSC. Just send as-is, with correct event. */
497 rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE,
498 an_apdu);
499 }
500 if (rc)
501 msc_t_error("Failed to send HO Request Ack\n");
502 else
503 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_COMPLETE, 0, 0);
504 return 0;
505
506 case RAN_MSG_HANDOVER_FAILURE:
507 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, an_apdu);
508 return 0;
509
510 case RAN_MSG_CLEAR_REQUEST:
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 default:
516 LOG_MSC_T(msc_t, LOGL_ERROR, "Unexpected message during Prepare Handover procedure: %s\n",
517 ran_msg_type_name(ran_dec->msg_type));
518 /* Let's just forward anyway. */
519 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
520 an_apdu);
521 return 0;
522 }
523}
524
525static void msc_t_fsm_wait_ho_request_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
526{
527 struct msc_t *msc_t = msc_t_priv(fi);
528 struct an_apdu *an_apdu;
529
530 switch (event) {
531
532 case MSC_EV_FROM_RAN_UP_L2:
533 an_apdu = data;
534 /* For inter-MSC Handover, we need to examine the message type. Depending on the response, we must
535 * dispatch MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE or MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, which
536 * ensures the correct E-interface message type. And we need to include the Handover Number.
537 * For mere inter-BSC Handover, we know that our osmo-msc internals don't care much about which event
538 * dispatches a Handover Failure or Handover Request Ack, so we could skip the decoding. But it is a
539 * premature optimization that complicates comparing an inter-BSC with an inter-MSC HO. */
540 msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_wait_ho_request_ack_decode_cb, an_apdu);
541 /* Action continues in msc_t_wait_ho_request_ack_decode_cb() */
542 return;
543
544 case MSC_EV_FROM_RAN_CONN_RELEASED:
545 msc_t_clear(msc_t);
546 return;
547
548 case MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST:
549 an_apdu = data;
550 msc_t_down_l2_co(msc_t, an_apdu, false);
551 return;
552
553 case MSC_EV_CALL_LEG_RTP_RELEASED:
554 case MSC_EV_CALL_LEG_TERM:
555 msc_t->inter_msc.call_leg = NULL;
556 msc_t_error("Failed to set up MGW endpoint\n");
557 return;
558
559 case MSC_MNCC_EV_CALL_ENDED:
560 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
561 return;
562
563 case MSC_T_EV_CN_CLOSE:
564 case MSC_T_EV_MO_CLOSE:
565 msc_t_clear(msc_t);
566 return;
567
568 default:
569 OSMO_ASSERT(false);
570 }
571}
572
573static int msc_t_wait_ho_complete_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
574 const struct ran_msg *ran_dec)
575{
576 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
577 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
578 struct msc_i *msc_i;
579 const struct an_apdu *an_apdu = data;
580
581 switch (ran_dec->msg_type) {
582 case RAN_MSG_HANDOVER_COMPLETE:
583 msc_t->ho_success = true;
584
585 /* For both inter-BSC local to this MSC and inter-MSC Handover for a remote MSC-A, forward the Handover
586 * Complete message so that the MSC-A can change the MSC-T (transitional) to a proper MSC-I role. */
587 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST, an_apdu);
588
589 /* For inter-BSC Handover, the Handover Complete event has already cleaned up this msc_t, and it is
590 * already gone and deallocated. */
591 if (!msc_a->c.remote_to)
592 return 0;
593
594 /* For inter-MSC Handover, the remote MSC-A only turns its msc_t_remote into an msc_i_remote on
595 * the same GSUP link. We are here on the MSC-B side of the GSUP link and have to take care of
596 * creating an MSC-I over here to match the msc_i_remote at MSC-A. */
597 msc_i = msc_i_alloc(msc_t->c.msub, msc_t->c.ran);
598 if (!msc_i) {
599 msc_t_error("Failed to create MSC-I role\n");
600 return -1;
601 }
602
603 msc_i->inter_msc.mncc_forwarding_to_remote_cn = msc_t->inter_msc.mncc_forwarding_to_remote_cn;
604 mncc_call_reparent(msc_i->inter_msc.mncc_forwarding_to_remote_cn,
605 msc_i->c.fi, -1, MSC_MNCC_EV_CALL_ENDED, NULL, NULL);
606
607 msc_i->inter_msc.call_leg = msc_t->inter_msc.call_leg;
608 call_leg_reparent(msc_i->inter_msc.call_leg,
609 msc_i->c.fi,
610 MSC_EV_CALL_LEG_TERM,
611 MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
612 MSC_EV_CALL_LEG_RTP_COMPLETE,
613 MSC_EV_CALL_LEG_RTP_RELEASED);
614
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
660 case MSC_EV_CALL_LEG_RTP_RELEASED:
661 case MSC_EV_CALL_LEG_TERM:
662 msc_t->inter_msc.call_leg = NULL;
663 msc_t_error("Failed to set up MGW endpoint\n");
664 return;
665
666 case MSC_MNCC_EV_CALL_ENDED:
667 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
668 return;
669
670 case MSC_T_EV_CN_CLOSE:
671 case MSC_T_EV_MO_CLOSE:
672 msc_t_clear(msc_t);
673 return;
674
675 default:
676 OSMO_ASSERT(false);
677 }
678}
679
680void msc_t_mncc_cb(struct mncc_call *mncc_call, const union mncc_msg *mncc_msg, void *data)
681{
682 struct msc_t *msc_t = data;
683 struct gsm_mncc_number nr = {
684 .plan = 1,
685 };
686 OSMO_STRLCPY_ARRAY(nr.number, msc_t->inter_msc.handover_number);
687
688 switch (mncc_msg->msg_type) {
689 case MNCC_RTP_CREATE:
690 mncc_call_incoming_tx_setup_cnf(mncc_call, &nr);
691 return;
692 default:
693 return;
694 }
695}
696
697struct mncc_call *msc_t_check_call_to_handover_number(const struct gsm_mncc *msg)
698{
699 struct msc_t *msc_t;
700 const char *handover_number;
701 struct mncc_call_incoming_req req;
702 struct mncc_call *mncc_call;
703
704 if (!(msg->fields & MNCC_F_CALLED))
705 return NULL;
706
707 handover_number = msg->called.number;
708 msc_t = msc_t_find_by_handover_number(handover_number);
709
710 if (!msc_t)
711 return NULL;
712
713 if (msc_t->inter_msc.mncc_forwarding_to_remote_cn) {
714 LOG_MSC_T(msc_t, LOGL_ERROR, "Incoming call for inter-MSC call forwarding,"
715 " but this MSC-T role already has an MNCC FSM set up\n");
716 return NULL;
717 }
718
719 if (!msc_t->inter_msc.call_leg
720 || !msc_t->inter_msc.call_leg->rtp[RTP_TO_CN]) {
721 LOG_MSC_T(msc_t, LOGL_ERROR, "Incoming call for inter-MSC call forwarding,"
722 " but this MSC-T has no RTP stream ready for MNCC\n");
723 return NULL;
724 }
725
726 mncc_call = mncc_call_alloc(msc_t_vsub(msc_t),
727 msc_t->c.fi,
728 MSC_MNCC_EV_CALL_COMPLETE,
729 MSC_MNCC_EV_CALL_ENDED,
730 msc_t_mncc_cb, msc_t);
731 if (!mncc_call) {
732 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
733 return NULL;
734 }
735 msc_t->inter_msc.mncc_forwarding_to_remote_cn = mncc_call;
736
737 if (mncc_call_set_rtp_stream(mncc_call, msc_t->inter_msc.call_leg->rtp[RTP_TO_CN])) {
738 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
739 osmo_fsm_inst_term(mncc_call->fi, OSMO_FSM_TERM_REGULAR, NULL);
740 return NULL;
741 }
742
743 req = (struct mncc_call_incoming_req){
744 .setup_req_msg = *msg,
745 .bearer_cap_present = true,
746 .bearer_cap = {
747 /* TODO derive values from actual config */
748 /* FIXME are there no defines or enums for these numbers!? */
749 /* Table 10.5.102/3GPP TS 24.008: Bearer capability information element:
750 * octet 3 of bearer cap for speech says 3 = "1 1 dual rate support MS/full rate speech version
751 * 1 preferred, half rate speech version 1 also supported" */
752 .radio = 3,
753 /* Table 10.5.103/3GPP TS 24.008 Bearer capability information element:
754 * 0: FR1, 2: FR2, 4: FR3, 1: HR1, 5: HR3, actually in this order. -1 marks the end of the list. */
755 .speech_ver = { 0, 2, 4, 1, 5, -1 },
756 },
757 };
758 if (mncc_call_incoming_start(mncc_call, &req)) {
759 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
760 osmo_fsm_inst_term(mncc_call->fi, OSMO_FSM_TERM_REGULAR, NULL);
761 return NULL;
762 }
763 return mncc_call;
764}
765
766static void msc_t_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
767{
768 struct msc_t *msc_t = msc_t_priv(fi);
769
770 if (!msc_t->ho_success && !msc_t->ho_fail_sent)
771 msc_t_send_handover_failure(msc_t, GSM0808_CAUSE_EQUIPMENT_FAILURE);
772
773 if (msc_t->ran_conn)
774 ran_conn_msc_role_gone(msc_t->ran_conn, msc_t->c.fi);
775}
776
777#define S(x) (1 << (x))
778
779static const struct osmo_fsm_state msc_t_fsm_states[] = {
780 [MSC_T_ST_PENDING_FIRST_CO_INITIAL_MSG] = {
781 .name = "PENDING_FIRST_CO_INITIAL_MSG",
782 .action = msc_t_fsm_pending_first_co_initial_msg,
783 .in_event_mask = 0
784 | S(MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST)
785 | S(MSC_T_EV_CN_CLOSE)
786 ,
787 .out_state_mask = 0
788 | S(MSC_T_ST_WAIT_LOCAL_RTP)
789 | S(MSC_T_ST_WAIT_HO_REQUEST_ACK)
790 ,
791 },
792 [MSC_T_ST_WAIT_LOCAL_RTP] = {
793 .name = "WAIT_LOCAL_RTP",
794 .onenter = msc_t_fsm_wait_local_rtp_onenter,
795 .action = msc_t_fsm_wait_local_rtp,
796 .in_event_mask = 0
797 | S(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE)
798 | S(MSC_EV_CALL_LEG_RTP_RELEASED)
799 | S(MSC_EV_CALL_LEG_TERM)
800 | S(MSC_MNCC_EV_CALL_ENDED)
801 | S(MSC_T_EV_CN_CLOSE)
802 ,
803 .out_state_mask = 0
804 | S(MSC_T_ST_WAIT_HO_REQUEST_ACK)
805 ,
806 },
807 [MSC_T_ST_WAIT_HO_REQUEST_ACK] = {
808 .name = "WAIT_HO_REQUEST_ACK",
809 .action = msc_t_fsm_wait_ho_request_ack,
810 .in_event_mask = 0
811 | S(MSC_EV_FROM_RAN_UP_L2)
812 | S(MSC_EV_FROM_RAN_CONN_RELEASED)
813 | S(MSC_EV_CALL_LEG_RTP_RELEASED)
814 | S(MSC_EV_CALL_LEG_TERM)
815 | S(MSC_MNCC_EV_CALL_ENDED)
816 | S(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
817 | S(MSC_T_EV_CN_CLOSE)
818 | S(MSC_T_EV_MO_CLOSE)
819 ,
820 .out_state_mask = 0
821 | S(MSC_T_ST_WAIT_HO_COMPLETE)
822 ,
823 },
824 [MSC_T_ST_WAIT_HO_COMPLETE] = {
825 .name = "WAIT_HO_COMPLETE",
826 .action = msc_t_fsm_wait_ho_complete,
827 .in_event_mask = 0
828 | S(MSC_EV_FROM_RAN_UP_L2)
829 | S(MSC_EV_FROM_RAN_CONN_RELEASED)
830 | S(MSC_EV_CALL_LEG_RTP_RELEASED)
831 | S(MSC_EV_CALL_LEG_TERM)
832 | S(MSC_MNCC_EV_CALL_ENDED)
833 | S(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
834 | S(MSC_T_EV_CN_CLOSE)
835 | S(MSC_T_EV_MO_CLOSE)
836 ,
837 },
838};
839
840const struct value_string msc_t_fsm_event_names[] = {
841 OSMO_VALUE_STRING(MSC_REMOTE_EV_RX_GSUP),
842 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE),
843 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_COMPLETE),
844 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_RELEASED),
845 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_TERM),
846 OSMO_VALUE_STRING(MSC_MNCC_EV_NEED_LOCAL_RTP),
847 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_PROCEEDING),
848 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_COMPLETE),
849 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_ENDED),
850
851 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_COMPLETE_LAYER_3),
852 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_UP_L2),
853 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_CONN_RELEASED),
854
855 OSMO_VALUE_STRING(MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST),
856 OSMO_VALUE_STRING(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST),
857 OSMO_VALUE_STRING(MSC_T_EV_CN_CLOSE),
858 OSMO_VALUE_STRING(MSC_T_EV_MO_CLOSE),
859 OSMO_VALUE_STRING(MSC_T_EV_CLEAR_COMPLETE),
860 {}
861};
862
863static struct osmo_fsm msc_t_fsm = {
864 .name = "msc_t",
865 .states = msc_t_fsm_states,
866 .num_states = ARRAY_SIZE(msc_t_fsm_states),
867 .log_subsys = DMSC,
868 .event_names = msc_t_fsm_event_names,
869 .cleanup = msc_t_fsm_cleanup,
870};
871
872static __attribute__((constructor)) void msc_t_fsm_init(void)
873{
874 OSMO_ASSERT(osmo_fsm_register(&msc_t_fsm) == 0);
875}
876
877/* Send connection-oriented L3 message to RAN peer (MSC->[BSC|RNC]) */
878int msc_t_down_l2_co(struct msc_t *msc_t, const struct an_apdu *an_apdu, bool initial)
879{
880 int rc;
881 if (!msc_t->ran_conn) {
882 LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot Tx L2 message: no RAN conn\n");
883 return -EIO;
884 }
885
886 if (an_apdu->an_proto != msc_t->c.ran->an_proto) {
887 LOG_MSC_T(msc_t, LOGL_ERROR, "Mismatching AN-APDU proto: %s -- Dropping message\n",
888 an_proto_name(an_apdu->an_proto));
889 return -EIO;
890 }
891
892 rc = ran_conn_down_l2_co(msc_t->ran_conn, an_apdu->msg, initial);
893 if (rc)
894 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to transfer message down to new RAN peer (rc=%d)\n", rc);
895 return rc;
896}
897
898struct gsm_network *msc_t_net(const struct msc_t *msc_t)
899{
900 return msub_net(msc_t->c.msub);
901}
902
903struct vlr_subscr *msc_t_vsub(const struct msc_t *msc_t)
904{
905 return msub_vsub(msc_t->c.msub);
906}
907
908struct msc_t *msc_t_alloc_without_ran_peer(struct msub *msub, struct ran_infra *ran)
909{
910 struct msc_t *msc_t;
911
912 msub_role_alloc(msub, MSC_ROLE_T, &msc_t_fsm, struct msc_t, ran);
913 msc_t = msub_msc_t(msub);
914 if (!msc_t)
915 return NULL;
916
917 return msc_t;
918}
919
920int msc_t_set_ran_peer(struct msc_t *msc_t, struct ran_peer *ran_peer)
921{
922 if (!ran_peer || !ran_peer->sri || !ran_peer->sri->ran) {
923 LOG_MSC_T(msc_t, LOGL_ERROR, "Invalid RAN peer: %s\n", ran_peer ? ran_peer->fi->id : "NULL");
924 return -EINVAL;
925 }
926
927 if (ran_peer->sri->ran != msc_t->c.ran) {
928 LOG_MSC_T(msc_t, LOGL_ERROR, "This MSC-T was set up for %s, cannot assign RAN peer for %s\n",
929 osmo_rat_type_name(msc_t->c.ran->type), osmo_rat_type_name(ran_peer->sri->ran->type));
930 return -EINVAL;
931 }
932
933 /* Create a new ran_conn with a fresh conn_id for the outgoing initial message. The msc_t FSM definition ensures
934 * that the first message sent or received is a Connection-Oriented Initial message. */
935 msc_t->ran_conn = ran_conn_create_outgoing(ran_peer);
936 if (!msc_t->ran_conn) {
937 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to create outgoing RAN conn\n");
938 return -EINVAL;
939 }
940 msc_t->ran_conn->msc_role = msc_t->c.fi;
941 msub_update_id(msc_t->c.msub);
942 return 0;
943}
944
945struct msc_t *msc_t_alloc(struct msub *msub, struct ran_peer *ran_peer)
946{
947 struct msc_t *msc_t = msc_t_alloc_without_ran_peer(msub, ran_peer->sri->ran);
948 if (!msc_t)
949 return NULL;
950 if (msc_t_set_ran_peer(msc_t, ran_peer)) {
951 msc_t_clear(msc_t);
952 return NULL;
953 }
954 return msc_t;
955}
956
957void msc_t_clear(struct msc_t *msc_t)
958{
959 if (!msc_t)
960 return;
961 osmo_fsm_inst_term(msc_t->c.fi, OSMO_FSM_TERM_REGULAR, msc_t->c.fi);
962}