blob: 8eefccc71467dde76220c8598e45c09140c58cc5 [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,
Neels Hofmeyr265a4c72019-05-09 16:20:51 +0200362 MSC_EV_CALL_LEG_RTP_COMPLETE);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100363 if (!msc_t->inter_msc.call_leg
364 || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_RAN, msc_t->inter_msc.callref, NULL, NULL, NULL)
365 || call_leg_ensure_ci(msc_t->inter_msc.call_leg, RTP_TO_CN, msc_t->inter_msc.callref, NULL, NULL, NULL)) {
366 msc_t_error("Failed to set up call leg\n");
367 return;
368 }
369 /* Now wait for two MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE, one per RTP connection */
370}
371
372void msc_t_fsm_wait_local_rtp(struct osmo_fsm_inst *fi, uint32_t event, void *data)
373{
374 struct msc_t *msc_t = msc_t_priv(fi);
375 struct rtp_stream *rtps;
376
377 switch (event) {
378 case MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE:
379 rtps = data;
380 if (!rtps) {
381 msc_t_error("Invalid data for MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE\n");
382 return;
383 }
384 /* If both to-RAN and to-CN sides have a CI set up, we can continue. */
385 if (!call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_RAN)
386 || !call_leg_local_ip(msc_t->inter_msc.call_leg, RTP_TO_CN))
387 return;
388
389 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_REQUEST_ACK, 0, 0);
390 msc_t_send_stored_ho_request(msc_t);
391 return;
392
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100393 case MSC_EV_CALL_LEG_TERM:
394 msc_t->inter_msc.call_leg = NULL;
395 msc_t_error("Failed to set up MGW endpoint\n");
396 return;
397
398 case MSC_MNCC_EV_CALL_ENDED:
399 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
400 return;
401
402 case MSC_T_EV_CN_CLOSE:
403 case MSC_T_EV_MO_CLOSE:
404 msc_t_clear(msc_t);
405 return;
406
407 default:
408 OSMO_ASSERT(false);
409 }
410}
411
412static int msc_t_patch_and_send_ho_request_ack(struct msc_t *msc_t, const struct an_apdu *incoming_an_apdu,
413 const struct ran_msg *ran_dec)
414{
415 int rc;
416 struct rtp_stream *rtp_ran = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_RAN] : NULL;
417 struct rtp_stream *rtp_cn = msc_t->inter_msc.call_leg? msc_t->inter_msc.call_leg->rtp[RTP_TO_CN] : NULL;
418 /* Since it's BCD, it needs rounded-up half the char* length of an MSISDN plus a type byte.
419 * But no need to introduce obscure math to save a few stack bytes, just have more. */
420 uint8_t msisdn_enc_buf[VLR_MSISDN_LENGTH + 1];
421 /* Copy an_apdu and an_apdu->e_info in "copy-on-write" method, because they are const and we
422 * need to add the Handover Number to e_info. */
423 const struct ran_handover_request_ack *r = &ran_dec->handover_request_ack;
424 struct ran_msg ran_enc = *ran_dec;
425 struct osmo_gsup_message e_info = {};
426 struct an_apdu an_apdu = {
427 .an_proto = incoming_an_apdu->an_proto,
428 .e_info = &e_info,
429 };
430 if (incoming_an_apdu->e_info)
431 e_info = *incoming_an_apdu->e_info;
432
433 rc = msc_t_assign_handover_number(msc_t);
434 if (rc)
435 return rc;
436
437 rc = gsm48_encode_bcd_number(msisdn_enc_buf, sizeof(msisdn_enc_buf), 0,
438 msc_t->inter_msc.handover_number);
439 if (rc <= 0)
440 return -EINVAL;
441
442 e_info.msisdn_enc = msisdn_enc_buf;
443 e_info.msisdn_enc_len = rc;
444
445 /* Also need to fetch the RTP IP:port from AoIP Transport Address IE to tell the MGW about it */
446 if (rtp_ran) {
447 if (osmo_sockaddr_str_is_set(&r->remote_rtp)) {
448 LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got " OSMO_SOCKADDR_STR_FMT "\n",
449 OSMO_SOCKADDR_STR_FMT_ARGS(&r->remote_rtp));
450 rtp_stream_set_remote_addr(rtp_ran, &r->remote_rtp);
451 } else {
452 LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP IP:port in Handover Request Ack\n");
453 }
454 if (r->codec_present) {
455 LOG_MSC_T(msc_t, LOGL_DEBUG, "From Handover Request Ack, got %s\n",
456 osmo_mgcpc_codec_name(r->codec));
457 rtp_stream_set_codec(rtp_ran, r->codec);
458 if (rtp_cn)
459 rtp_stream_set_codec(rtp_cn, r->codec);
460 } else {
461 LOG_MSC_T(msc_t, LOGL_DEBUG, "No codec in Handover Request Ack\n");
462 }
463 rtp_stream_commit(rtp_ran);
464 } else {
465 LOG_MSC_T(msc_t, LOGL_DEBUG, "No RTP to RAN set up yet\n");
466 }
467
468 /* Remove that AoIP Transport Layer IE so it doesn't get sent to the remote MSC */
469 ran_enc.handover_request_ack.remote_rtp = (struct osmo_sockaddr_str){};
470
471 an_apdu.msg = msc_role_ran_encode(msc_t->c.fi, &ran_enc);
472 if (!an_apdu.msg)
473 return -EIO;
474 /* Send to remote MSC via msc_a_remote role */
475 rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE, &an_apdu);
476 msgb_free(an_apdu.msg);
477 return rc;
478}
479
480static int msc_t_wait_ho_request_ack_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
481 const struct ran_msg *ran_dec)
482{
483 int rc;
484 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
485 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
486 const struct an_apdu *an_apdu = data;
487
488 switch (ran_dec->msg_type) {
489 case RAN_MSG_HANDOVER_REQUEST_ACK:
490 if (msc_a->c.remote_to) {
491 /* inter-MSC. Add Handover Number, remove AoIP Transport Layer Address. */
492 rc = msc_t_patch_and_send_ho_request_ack(msc_t, an_apdu, ran_dec);
493 } else {
494 /* inter-BSC. Just send as-is, with correct event. */
495 rc = msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE,
496 an_apdu);
497 }
498 if (rc)
499 msc_t_error("Failed to send HO Request Ack\n");
500 else
501 osmo_fsm_inst_state_chg(msc_t->c.fi, MSC_T_ST_WAIT_HO_COMPLETE, 0, 0);
502 return 0;
503
504 case RAN_MSG_HANDOVER_FAILURE:
505 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, an_apdu);
506 return 0;
507
508 case RAN_MSG_CLEAR_REQUEST:
509 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
510 an_apdu);
511 return 0;
512
513 default:
514 LOG_MSC_T(msc_t, LOGL_ERROR, "Unexpected message during Prepare Handover procedure: %s\n",
515 ran_msg_type_name(ran_dec->msg_type));
516 /* Let's just forward anyway. */
517 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
518 an_apdu);
519 return 0;
520 }
521}
522
523static void msc_t_fsm_wait_ho_request_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
524{
525 struct msc_t *msc_t = msc_t_priv(fi);
526 struct an_apdu *an_apdu;
527
528 switch (event) {
529
530 case MSC_EV_FROM_RAN_UP_L2:
531 an_apdu = data;
532 /* For inter-MSC Handover, we need to examine the message type. Depending on the response, we must
533 * dispatch MSC_A_EV_FROM_T_PREPARE_HANDOVER_RESPONSE or MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, which
534 * ensures the correct E-interface message type. And we need to include the Handover Number.
535 * For mere inter-BSC Handover, we know that our osmo-msc internals don't care much about which event
536 * dispatches a Handover Failure or Handover Request Ack, so we could skip the decoding. But it is a
537 * premature optimization that complicates comparing an inter-BSC with an inter-MSC HO. */
538 msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_wait_ho_request_ack_decode_cb, an_apdu);
539 /* Action continues in msc_t_wait_ho_request_ack_decode_cb() */
540 return;
541
542 case MSC_EV_FROM_RAN_CONN_RELEASED:
543 msc_t_clear(msc_t);
544 return;
545
546 case MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST:
547 an_apdu = data;
548 msc_t_down_l2_co(msc_t, an_apdu, false);
549 return;
550
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100551 case MSC_EV_CALL_LEG_TERM:
552 msc_t->inter_msc.call_leg = NULL;
553 msc_t_error("Failed to set up MGW endpoint\n");
554 return;
555
556 case MSC_MNCC_EV_CALL_ENDED:
557 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
558 return;
559
560 case MSC_T_EV_CN_CLOSE:
561 case MSC_T_EV_MO_CLOSE:
562 msc_t_clear(msc_t);
563 return;
564
565 default:
566 OSMO_ASSERT(false);
567 }
568}
569
570static int msc_t_wait_ho_complete_decode_cb(struct osmo_fsm_inst *msc_t_fi, void *data,
571 const struct ran_msg *ran_dec)
572{
573 struct msc_t *msc_t = msc_t_priv(msc_t_fi);
574 struct msc_a *msc_a = msub_msc_a(msc_t->c.msub);
575 struct msc_i *msc_i;
576 const struct an_apdu *an_apdu = data;
577
578 switch (ran_dec->msg_type) {
579 case RAN_MSG_HANDOVER_COMPLETE:
580 msc_t->ho_success = true;
581
582 /* For both inter-BSC local to this MSC and inter-MSC Handover for a remote MSC-A, forward the Handover
583 * Complete message so that the MSC-A can change the MSC-T (transitional) to a proper MSC-I role. */
584 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_SEND_END_SIGNAL_REQUEST, an_apdu);
585
586 /* For inter-BSC Handover, the Handover Complete event has already cleaned up this msc_t, and it is
587 * already gone and deallocated. */
588 if (!msc_a->c.remote_to)
589 return 0;
590
591 /* For inter-MSC Handover, the remote MSC-A only turns its msc_t_remote into an msc_i_remote on
592 * the same GSUP link. We are here on the MSC-B side of the GSUP link and have to take care of
593 * creating an MSC-I over here to match the msc_i_remote at MSC-A. */
594 msc_i = msc_i_alloc(msc_t->c.msub, msc_t->c.ran);
595 if (!msc_i) {
596 msc_t_error("Failed to create MSC-I role\n");
597 return -1;
598 }
599
600 msc_i->inter_msc.mncc_forwarding_to_remote_cn = msc_t->inter_msc.mncc_forwarding_to_remote_cn;
601 mncc_call_reparent(msc_i->inter_msc.mncc_forwarding_to_remote_cn,
602 msc_i->c.fi, -1, MSC_MNCC_EV_CALL_ENDED, NULL, NULL);
603
604 msc_i->inter_msc.call_leg = msc_t->inter_msc.call_leg;
605 call_leg_reparent(msc_i->inter_msc.call_leg,
606 msc_i->c.fi,
607 MSC_EV_CALL_LEG_TERM,
608 MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE,
Neels Hofmeyr265a4c72019-05-09 16:20:51 +0200609 MSC_EV_CALL_LEG_RTP_COMPLETE);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100610
611 /* msc_i_set_ran_conn() properly "steals" the ran_conn from msc_t */
612 msc_i_set_ran_conn(msc_i, msc_t->ran_conn);
613
614 /* Nicked everything worth keeping from MSC-T, discard now. */
615 msc_t_clear(msc_t);
616 return 0;
617
618 case RAN_MSG_HANDOVER_FAILURE:
619 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PREPARE_HANDOVER_FAILURE, an_apdu);
620 return 0;
621
622 default:
623 LOG_MSC_T(msc_t, LOGL_ERROR, "Unexpected message during Prepare Handover procedure: %s\n",
624 ran_msg_type_name(ran_dec->msg_type));
625 /* Let's just forward anyway. Fall thru */
626 case RAN_MSG_HANDOVER_DETECT:
627 case RAN_MSG_CLEAR_REQUEST:
628 msub_role_dispatch(msc_t->c.msub, MSC_ROLE_A, MSC_A_EV_FROM_T_PROCESS_ACCESS_SIGNALLING_REQUEST,
629 an_apdu);
630 return 0;
631 }
632}
633
634static void msc_t_fsm_wait_ho_complete(struct osmo_fsm_inst *fi, uint32_t event, void *data)
635{
636 struct msc_t *msc_t = msc_t_priv(fi);
637 struct an_apdu *an_apdu;
638
639 switch (event) {
640
641 case MSC_EV_FROM_RAN_UP_L2:
642 an_apdu = data;
643 /* We need to catch the Handover Complete message in order to send it as a SendEndSignal Request */
644 msc_role_ran_decode(msc_t->c.fi, an_apdu, msc_t_wait_ho_complete_decode_cb, an_apdu);
645 return;
646
647 case MSC_EV_FROM_RAN_CONN_RELEASED:
648 msc_t_clear(msc_t);
649 return;
650
651 case MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST:
652 an_apdu = data;
653 msc_t_down_l2_co(msc_t, an_apdu, false);
654 return;
655
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100656 case MSC_EV_CALL_LEG_TERM:
657 msc_t->inter_msc.call_leg = NULL;
658 msc_t_error("Failed to set up MGW endpoint\n");
659 return;
660
661 case MSC_MNCC_EV_CALL_ENDED:
662 msc_t->inter_msc.mncc_forwarding_to_remote_cn = NULL;
663 return;
664
665 case MSC_T_EV_CN_CLOSE:
666 case MSC_T_EV_MO_CLOSE:
667 msc_t_clear(msc_t);
668 return;
669
670 default:
671 OSMO_ASSERT(false);
672 }
673}
674
675void msc_t_mncc_cb(struct mncc_call *mncc_call, const union mncc_msg *mncc_msg, void *data)
676{
677 struct msc_t *msc_t = data;
678 struct gsm_mncc_number nr = {
679 .plan = 1,
680 };
681 OSMO_STRLCPY_ARRAY(nr.number, msc_t->inter_msc.handover_number);
682
683 switch (mncc_msg->msg_type) {
684 case MNCC_RTP_CREATE:
685 mncc_call_incoming_tx_setup_cnf(mncc_call, &nr);
686 return;
687 default:
688 return;
689 }
690}
691
692struct mncc_call *msc_t_check_call_to_handover_number(const struct gsm_mncc *msg)
693{
694 struct msc_t *msc_t;
695 const char *handover_number;
696 struct mncc_call_incoming_req req;
697 struct mncc_call *mncc_call;
698
699 if (!(msg->fields & MNCC_F_CALLED))
700 return NULL;
701
702 handover_number = msg->called.number;
703 msc_t = msc_t_find_by_handover_number(handover_number);
704
705 if (!msc_t)
706 return NULL;
707
708 if (msc_t->inter_msc.mncc_forwarding_to_remote_cn) {
709 LOG_MSC_T(msc_t, LOGL_ERROR, "Incoming call for inter-MSC call forwarding,"
710 " but this MSC-T role already has an MNCC FSM set up\n");
711 return NULL;
712 }
713
714 if (!msc_t->inter_msc.call_leg
715 || !msc_t->inter_msc.call_leg->rtp[RTP_TO_CN]) {
716 LOG_MSC_T(msc_t, LOGL_ERROR, "Incoming call for inter-MSC call forwarding,"
717 " but this MSC-T has no RTP stream ready for MNCC\n");
718 return NULL;
719 }
720
721 mncc_call = mncc_call_alloc(msc_t_vsub(msc_t),
722 msc_t->c.fi,
723 MSC_MNCC_EV_CALL_COMPLETE,
724 MSC_MNCC_EV_CALL_ENDED,
725 msc_t_mncc_cb, msc_t);
726 if (!mncc_call) {
727 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
728 return NULL;
729 }
730 msc_t->inter_msc.mncc_forwarding_to_remote_cn = mncc_call;
731
732 if (mncc_call_set_rtp_stream(mncc_call, msc_t->inter_msc.call_leg->rtp[RTP_TO_CN])) {
733 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
734 osmo_fsm_inst_term(mncc_call->fi, OSMO_FSM_TERM_REGULAR, NULL);
735 return NULL;
736 }
737
738 req = (struct mncc_call_incoming_req){
739 .setup_req_msg = *msg,
740 .bearer_cap_present = true,
741 .bearer_cap = {
742 /* TODO derive values from actual config */
743 /* FIXME are there no defines or enums for these numbers!? */
744 /* Table 10.5.102/3GPP TS 24.008: Bearer capability information element:
745 * octet 3 of bearer cap for speech says 3 = "1 1 dual rate support MS/full rate speech version
746 * 1 preferred, half rate speech version 1 also supported" */
747 .radio = 3,
748 /* Table 10.5.103/3GPP TS 24.008 Bearer capability information element:
749 * 0: FR1, 2: FR2, 4: FR3, 1: HR1, 5: HR3, actually in this order. -1 marks the end of the list. */
750 .speech_ver = { 0, 2, 4, 1, 5, -1 },
751 },
752 };
753 if (mncc_call_incoming_start(mncc_call, &req)) {
754 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to set up call forwarding from remote MSC\n");
755 osmo_fsm_inst_term(mncc_call->fi, OSMO_FSM_TERM_REGULAR, NULL);
756 return NULL;
757 }
758 return mncc_call;
759}
760
761static void msc_t_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
762{
763 struct msc_t *msc_t = msc_t_priv(fi);
764
765 if (!msc_t->ho_success && !msc_t->ho_fail_sent)
766 msc_t_send_handover_failure(msc_t, GSM0808_CAUSE_EQUIPMENT_FAILURE);
767
768 if (msc_t->ran_conn)
769 ran_conn_msc_role_gone(msc_t->ran_conn, msc_t->c.fi);
770}
771
772#define S(x) (1 << (x))
773
774static const struct osmo_fsm_state msc_t_fsm_states[] = {
775 [MSC_T_ST_PENDING_FIRST_CO_INITIAL_MSG] = {
776 .name = "PENDING_FIRST_CO_INITIAL_MSG",
777 .action = msc_t_fsm_pending_first_co_initial_msg,
778 .in_event_mask = 0
779 | S(MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST)
780 | S(MSC_T_EV_CN_CLOSE)
781 ,
782 .out_state_mask = 0
783 | S(MSC_T_ST_WAIT_LOCAL_RTP)
784 | S(MSC_T_ST_WAIT_HO_REQUEST_ACK)
785 ,
786 },
787 [MSC_T_ST_WAIT_LOCAL_RTP] = {
788 .name = "WAIT_LOCAL_RTP",
789 .onenter = msc_t_fsm_wait_local_rtp_onenter,
790 .action = msc_t_fsm_wait_local_rtp,
791 .in_event_mask = 0
792 | S(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE)
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100793 | S(MSC_EV_CALL_LEG_TERM)
794 | S(MSC_MNCC_EV_CALL_ENDED)
795 | S(MSC_T_EV_CN_CLOSE)
796 ,
797 .out_state_mask = 0
798 | S(MSC_T_ST_WAIT_HO_REQUEST_ACK)
799 ,
800 },
801 [MSC_T_ST_WAIT_HO_REQUEST_ACK] = {
802 .name = "WAIT_HO_REQUEST_ACK",
803 .action = msc_t_fsm_wait_ho_request_ack,
804 .in_event_mask = 0
805 | S(MSC_EV_FROM_RAN_UP_L2)
806 | S(MSC_EV_FROM_RAN_CONN_RELEASED)
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100807 | S(MSC_EV_CALL_LEG_TERM)
808 | S(MSC_MNCC_EV_CALL_ENDED)
809 | S(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
810 | S(MSC_T_EV_CN_CLOSE)
811 | S(MSC_T_EV_MO_CLOSE)
812 ,
813 .out_state_mask = 0
814 | S(MSC_T_ST_WAIT_HO_COMPLETE)
815 ,
816 },
817 [MSC_T_ST_WAIT_HO_COMPLETE] = {
818 .name = "WAIT_HO_COMPLETE",
819 .action = msc_t_fsm_wait_ho_complete,
820 .in_event_mask = 0
821 | S(MSC_EV_FROM_RAN_UP_L2)
822 | S(MSC_EV_FROM_RAN_CONN_RELEASED)
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100823 | S(MSC_EV_CALL_LEG_TERM)
824 | S(MSC_MNCC_EV_CALL_ENDED)
825 | S(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST)
826 | S(MSC_T_EV_CN_CLOSE)
827 | S(MSC_T_EV_MO_CLOSE)
828 ,
829 },
830};
831
832const struct value_string msc_t_fsm_event_names[] = {
833 OSMO_VALUE_STRING(MSC_REMOTE_EV_RX_GSUP),
834 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_LOCAL_ADDR_AVAILABLE),
835 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_RTP_COMPLETE),
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100836 OSMO_VALUE_STRING(MSC_EV_CALL_LEG_TERM),
837 OSMO_VALUE_STRING(MSC_MNCC_EV_NEED_LOCAL_RTP),
838 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_PROCEEDING),
839 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_COMPLETE),
840 OSMO_VALUE_STRING(MSC_MNCC_EV_CALL_ENDED),
841
842 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_COMPLETE_LAYER_3),
843 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_UP_L2),
844 OSMO_VALUE_STRING(MSC_EV_FROM_RAN_CONN_RELEASED),
845
846 OSMO_VALUE_STRING(MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST),
847 OSMO_VALUE_STRING(MSC_T_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST),
848 OSMO_VALUE_STRING(MSC_T_EV_CN_CLOSE),
849 OSMO_VALUE_STRING(MSC_T_EV_MO_CLOSE),
850 OSMO_VALUE_STRING(MSC_T_EV_CLEAR_COMPLETE),
851 {}
852};
853
854static struct osmo_fsm msc_t_fsm = {
855 .name = "msc_t",
856 .states = msc_t_fsm_states,
857 .num_states = ARRAY_SIZE(msc_t_fsm_states),
858 .log_subsys = DMSC,
859 .event_names = msc_t_fsm_event_names,
860 .cleanup = msc_t_fsm_cleanup,
861};
862
863static __attribute__((constructor)) void msc_t_fsm_init(void)
864{
865 OSMO_ASSERT(osmo_fsm_register(&msc_t_fsm) == 0);
866}
867
868/* Send connection-oriented L3 message to RAN peer (MSC->[BSC|RNC]) */
869int msc_t_down_l2_co(struct msc_t *msc_t, const struct an_apdu *an_apdu, bool initial)
870{
871 int rc;
872 if (!msc_t->ran_conn) {
873 LOG_MSC_T(msc_t, LOGL_ERROR, "Cannot Tx L2 message: no RAN conn\n");
874 return -EIO;
875 }
876
877 if (an_apdu->an_proto != msc_t->c.ran->an_proto) {
878 LOG_MSC_T(msc_t, LOGL_ERROR, "Mismatching AN-APDU proto: %s -- Dropping message\n",
879 an_proto_name(an_apdu->an_proto));
880 return -EIO;
881 }
882
883 rc = ran_conn_down_l2_co(msc_t->ran_conn, an_apdu->msg, initial);
884 if (rc)
885 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to transfer message down to new RAN peer (rc=%d)\n", rc);
886 return rc;
887}
888
889struct gsm_network *msc_t_net(const struct msc_t *msc_t)
890{
891 return msub_net(msc_t->c.msub);
892}
893
894struct vlr_subscr *msc_t_vsub(const struct msc_t *msc_t)
895{
Neels Hofmeyr911e5972019-05-09 13:28:26 +0200896 if (!msc_t)
897 return NULL;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100898 return msub_vsub(msc_t->c.msub);
899}
900
901struct msc_t *msc_t_alloc_without_ran_peer(struct msub *msub, struct ran_infra *ran)
902{
903 struct msc_t *msc_t;
904
905 msub_role_alloc(msub, MSC_ROLE_T, &msc_t_fsm, struct msc_t, ran);
906 msc_t = msub_msc_t(msub);
907 if (!msc_t)
908 return NULL;
909
910 return msc_t;
911}
912
913int msc_t_set_ran_peer(struct msc_t *msc_t, struct ran_peer *ran_peer)
914{
915 if (!ran_peer || !ran_peer->sri || !ran_peer->sri->ran) {
916 LOG_MSC_T(msc_t, LOGL_ERROR, "Invalid RAN peer: %s\n", ran_peer ? ran_peer->fi->id : "NULL");
917 return -EINVAL;
918 }
919
920 if (ran_peer->sri->ran != msc_t->c.ran) {
921 LOG_MSC_T(msc_t, LOGL_ERROR, "This MSC-T was set up for %s, cannot assign RAN peer for %s\n",
922 osmo_rat_type_name(msc_t->c.ran->type), osmo_rat_type_name(ran_peer->sri->ran->type));
923 return -EINVAL;
924 }
925
926 /* Create a new ran_conn with a fresh conn_id for the outgoing initial message. The msc_t FSM definition ensures
927 * that the first message sent or received is a Connection-Oriented Initial message. */
928 msc_t->ran_conn = ran_conn_create_outgoing(ran_peer);
929 if (!msc_t->ran_conn) {
930 LOG_MSC_T(msc_t, LOGL_ERROR, "Failed to create outgoing RAN conn\n");
931 return -EINVAL;
932 }
933 msc_t->ran_conn->msc_role = msc_t->c.fi;
934 msub_update_id(msc_t->c.msub);
935 return 0;
936}
937
938struct msc_t *msc_t_alloc(struct msub *msub, struct ran_peer *ran_peer)
939{
940 struct msc_t *msc_t = msc_t_alloc_without_ran_peer(msub, ran_peer->sri->ran);
941 if (!msc_t)
942 return NULL;
943 if (msc_t_set_ran_peer(msc_t, ran_peer)) {
944 msc_t_clear(msc_t);
945 return NULL;
946 }
947 return msc_t;
948}
949
950void msc_t_clear(struct msc_t *msc_t)
951{
952 if (!msc_t)
953 return;
954 osmo_fsm_inst_term(msc_t->c.fi, OSMO_FSM_TERM_REGULAR, msc_t->c.fi);
955}