blob: 7e7905bb7d3859775ca010b5333bbb0dc7db4b44 [file] [log] [blame]
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001/* MSC Handover implementation */
2/*
3 * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
4 * All Rights Reserved
5 *
6 * Author: Neels Hofmeyr
7 *
8 * SPDX-License-Identifier: GPL-2.0+
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 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 General Public License for more details.
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010019 */
20
21#include <osmocom/core/fsm.h>
22#include <osmocom/gsm/protocol/gsm_08_08.h>
23#include <osmocom/sigtran/sccp_helpers.h>
24
25#include <osmocom/msc/msc_ho.h>
26#include <osmocom/msc/ran_msg.h>
27#include <osmocom/msc/msc_a.h>
28#include <osmocom/msc/msc_i.h>
29#include <osmocom/msc/msc_t.h>
30#include <osmocom/msc/e_link.h>
31#include <osmocom/msc/msc_i_remote.h>
32#include <osmocom/msc/msc_t_remote.h>
33#include <osmocom/msc/neighbor_ident.h>
34#include <osmocom/msc/gsm_data.h>
35#include <osmocom/msc/ran_peer.h>
36#include <osmocom/msc/vlr.h>
37#include <osmocom/msc/transaction.h>
38#include <osmocom/msc/gsm_04_08.h>
39#include <osmocom/msc/call_leg.h>
40#include <osmocom/msc/rtp_stream.h>
41#include <osmocom/msc/mncc_call.h>
42
43struct osmo_fsm msc_ho_fsm;
44
45#define MSC_A_USE_HANDOVER "Handover"
46
47static const struct osmo_tdef_state_timeout msc_ho_fsm_timeouts[32] = {
48 [MSC_HO_ST_REQUIRED] = { .keep_timer = true, .T = -3 },
49 [MSC_HO_ST_WAIT_REQUEST_ACK] = { .keep_timer = true },
50 [MSC_HO_ST_WAIT_COMPLETE] = { .T = -3 },
51};
52
53/* Transition to a state, using the T timer defined in msc_a_fsm_timeouts.
54 * The actual timeout value is in turn obtained from network->T_defs.
55 * Assumes local variable fi exists. */
56#define msc_ho_fsm_state_chg(msc_a, state) \
57 osmo_tdef_fsm_inst_state_chg((msc_a)->ho.fi, state, msc_ho_fsm_timeouts, (msc_a)->c.ran->tdefs, 5)
58
59static __attribute__((constructor)) void msc_ho_fsm_init()
60{
Harald Welte34a8cc32019-12-01 15:32:09 +010061 OSMO_ASSERT(osmo_fsm_register(&msc_ho_fsm) == 0);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010062}
63
64void msc_ho_down_required_reject(struct msc_a *msc_a, enum gsm0808_cause cause)
65{
Vadim Yanitskiydb4839c2019-12-01 18:52:58 +070066 struct msc_i *msc_i;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010067 uint32_t event;
68
Vadim Yanitskiydb4839c2019-12-01 18:52:58 +070069 msc_i = msc_a_msc_i(msc_a);
70 OSMO_ASSERT(msc_i);
71
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010072 struct ran_msg ran_enc_msg = {
73 .msg_type = RAN_MSG_HANDOVER_REQUIRED_REJECT,
74 .handover_required_reject = {
75 .cause = cause,
76 },
77 };
78
79 if (msc_i->c.remote_to)
80 event = MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_ERROR;
81 else
82 event = MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST;
83
84 msc_a_msg_down(msc_a, MSC_ROLE_I, event, &ran_enc_msg);
85}
86
87/* Even though this is using the 3GPP TS 48.008 definitions and naming, the intention is to be RAN implementation agnostic.
88 * For other RAN types, the 48.008 items shall be translated to their respective counterparts. */
89void msc_ho_start(struct msc_a *msc_a, const struct ran_handover_required *ho_req)
90{
91 if (msc_a->ho.fi) {
92 LOG_HO(msc_a, LOGL_ERROR, "Rx Handover Required, but Handover is still ongoing\n");
93 msc_ho_down_required_reject(msc_a, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
94 return;
95 }
96
97 if (!ho_req->cil.id_list_len) {
98 LOG_HO(msc_a, LOGL_ERROR, "Rx Handover Required without a Cell Identifier List\n");
99 msc_ho_down_required_reject(msc_a, GSM0808_CAUSE_INFORMATION_ELEMENT_OR_FIELD_MISSING);
100 return;
101 }
102
103 if (msc_a_msc_t(msc_a)) {
104 LOG_HO(msc_a, LOGL_ERROR,
105 "Rx Handover Required, but this subscriber still has an active MSC-T role: %s\n",
106 msc_a_msc_t(msc_a)->c.fi->id);
107 /* Protocol error because the BSS is not supposed to send another Handover Required before the previous
108 * attempt has concluded. */
109 msc_ho_down_required_reject(msc_a, GSM0808_CAUSE_PROTOCOL_ERROR_BETWEEN_BSS_AND_MSC);
110 return;
111 }
112
113 /* Paranoia: make sure we start with clean state */
114 msc_a->ho = (struct msc_ho_state){};
115
116 msc_a->ho.fi = osmo_fsm_inst_alloc_child(&msc_ho_fsm, msc_a->c.fi, MSC_A_EV_HANDOVER_END);
117 OSMO_ASSERT(msc_a->ho.fi);
118
119 msc_a->ho.fi->priv = msc_a;
120 msc_a->ho.info = *ho_req;
121 msc_a->ho.next_cil_idx = 0;
122
123 /* Start the timeout */
124 msc_ho_fsm_state_chg(msc_a, MSC_HO_ST_REQUIRED);
125}
126
127static void msc_ho_rtp_rollback_to_old_cell(struct msc_a *msc_a);
128
129static void msc_ho_end(struct msc_a *msc_a, bool success, enum gsm0808_cause cause)
130{
131 struct msc_i *msc_i;
132 struct msc_t *msc_t = msc_a_msc_t(msc_a);
133
134 if (!success) {
135 msc_ho_rtp_rollback_to_old_cell(msc_a);
136 msc_ho_down_required_reject(msc_a, cause);
137 }
138
139 if (success) {
140 /* Any previous call forwarding to a remote MSC becomes obsolete. */
141 if (msc_a->cc.mncc_forwarding_to_remote_ran) {
142 mncc_call_release(msc_a->cc.mncc_forwarding_to_remote_ran);
143 msc_a->cc.mncc_forwarding_to_remote_ran = NULL;
144 }
145
146 /* Replace MSC-I with new MSC-T */
147 if (msc_t->c.remote_to) {
148 /* Inter-MSC Handover. */
149
150 /* The MNCC forwarding set up for inter-MSC handover, so far transitional in msc_a->ho now
151 * becomes the "officially" active MNCC forwarding for this call. */
152 msc_a->cc.mncc_forwarding_to_remote_ran = msc_a->ho.new_cell.mncc_forwarding_to_remote_ran;
153 msc_a->ho.new_cell.mncc_forwarding_to_remote_ran = NULL;
154 mncc_call_reparent(msc_a->cc.mncc_forwarding_to_remote_ran,
155 msc_a->c.fi, -1, MSC_MNCC_EV_CALL_ENDED, NULL, NULL);
156
157 /* inter-MSC link. msc_i_remote_alloc() properly "steals" the e_link from msc_t. */
158 msc_i = msc_i_remote_alloc(msc_a->c.msub, msc_t->c.ran, msc_t->c.remote_to);
159 OSMO_ASSERT(msc_t->c.remote_to == NULL);
160 } else {
161 /* local BSS */
162 msc_i = msc_i_alloc(msc_a->c.msub, msc_t->c.ran);
163 /* msc_i_set_ran_conn() properly "steals" the ran_conn from msc_t */
164 msc_i_set_ran_conn(msc_i, msc_t->ran_conn);
165 }
166 }
167
168 osmo_fsm_inst_term(msc_a->ho.fi, OSMO_FSM_TERM_REGULAR, NULL);
169}
170
171#define msc_ho_failed(msc_a, cause, fmt, args...) do { \
172 LOG_HO(msc_a, LOGL_ERROR, fmt, ##args); \
173 msc_ho_end(msc_a, false, cause); \
174 } while(0)
175#define msc_ho_try_next_cell(msc_a, fmt, args...) do {\
176 LOG_HO(msc_a, LOGL_ERROR, fmt, ##args); \
177 msc_ho_fsm_state_chg(msc_a, MSC_HO_ST_REQUIRED); \
178 } while(0)
179#define msc_ho_success(msc_a) msc_ho_end(msc_a, true, 0)
180
181enum msc_neighbor_type msc_ho_find_target_cell(struct msc_a *msc_a, const struct gsm0808_cell_id *cid,
182 const struct neighbor_ident_entry **remote_msc,
183 struct ran_peer **ran_peer_from_neighbor_ident,
184 struct ran_peer **ran_peer_from_seen_cells)
185{
186 struct gsm_network *net = msc_a_net(msc_a);
187 const struct neighbor_ident_entry *e;
188 struct sccp_ran_inst *sri;
189 struct ran_peer *rp_from_neighbor_ident = NULL;
190 struct ran_peer *rp_from_cell_id = NULL;
191 struct ran_peer *rp;
192 int i;
193
194 OSMO_ASSERT(remote_msc);
195 OSMO_ASSERT(ran_peer_from_neighbor_ident);
196 OSMO_ASSERT(ran_peer_from_seen_cells);
197
198 e = neighbor_ident_find_by_cell(&net->neighbor_ident_list, msc_a->c.ran->type, cid);
199
200 if (e && e->addr.type == MSC_NEIGHBOR_TYPE_REMOTE_MSC) {
201 *remote_msc = e;
202 return MSC_NEIGHBOR_TYPE_REMOTE_MSC;
203 }
204
205 /* It is not a remote MSC target. Figure out local RAN peers. */
206
207 if (e && e->addr.type == MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER) {
208 /* Find local RAN peer in neighbor config. If anything is wrong with that, just keep
209 * rp_from_neighbor_ident == NULL. */
210
211 struct sccp_ran_inst *sri_from_neighbor_ident = NULL;
212 struct osmo_ss7_instance *ss7 = NULL;
213
214 /* Get the sccp_ran_inst with sanity checkin. If anything is fishy, just keep
215 * sri_from_neighbor_ident == NULL and below code will notice the error. */
216 if (e->addr.ran_type < msc_ran_infra_len) {
217 sri_from_neighbor_ident = msc_ran_infra[e->addr.ran_type].sri;
218 ss7 = osmo_sccp_get_ss7(sri_from_neighbor_ident->sccp);
219 if (!ss7)
220 sri_from_neighbor_ident = NULL;
221 }
222
223 if (!sri_from_neighbor_ident) {
224 LOG_HO(msc_a, LOGL_ERROR, "Cannot handover to RAN type %s\n", osmo_rat_type_name(e->addr.ran_type));
225 } else {
226 /* Interpret the point-code string placed in the neighbors config. */
227 int pc = osmo_ss7_pointcode_parse(ss7, e->addr.local_ran_peer_pc_str);
228
229 if (pc < 0) {
230 LOG_HO(msc_a, LOGL_ERROR, "Invalid point code string: %s\n",
231 osmo_quote_str(e->addr.local_ran_peer_pc_str, -1));
232 } else {
233 struct osmo_sccp_addr addr = {};
234 osmo_sccp_make_addr_pc_ssn(&addr, pc, sri_from_neighbor_ident->ran->ssn);
235 rp_from_neighbor_ident = ran_peer_find_by_addr(sri_from_neighbor_ident, &addr);
236 }
237 }
238
239 if (!rp_from_neighbor_ident) {
240 LOG_HO(msc_a, LOGL_ERROR, "Target RAN peer from neighbor config is not connected:"
241 " Cell ID %s resolves to target address %s\n",
242 gsm0808_cell_id_name(cid), e->addr.local_ran_peer_pc_str);
243 } else if (rp_from_neighbor_ident->fi->state != RAN_PEER_ST_READY) {
244 LOG_HO(msc_a, LOGL_ERROR, "Target RAN peer in invalid state: %s (%s)\n",
245 osmo_fsm_inst_state_name(rp_from_neighbor_ident->fi),
246 rp_from_neighbor_ident->fi->id);
247 rp_from_neighbor_ident = NULL;
248 }
249 }
250
251 /* Figure out actually connected RAN peers for this cell ID.
252 * If no cell has been found yet at all, this might determine a Handover target,
253 * otherwise this is for sanity checking. If none is found, just keep rp_from_cell_id == NULL. */
254
255 /* Iterate all connected RAN peers. Possibly, more than one RAN peer has advertised a match for this Cell ID.
256 * For example, if the handover target is identified as LAC=23 but there are multiple cells with distinct CIs
257 * serving in LAC=23, we have an ambiguity. It's up to the user to configure correctly, help with logging. */
258 for (i = 0; i < msc_ran_infra_len; i++) {
259 sri = msc_ran_infra[i].sri;
260 if (!sri)
261 continue;
262
263 rp = ran_peer_find_by_cell_id(sri, cid, true);
264 if (rp && rp->fi && rp->fi->state == RAN_PEER_ST_READY) {
265 if (rp_from_cell_id) {
266 LOG_HO(msc_a, LOGL_ERROR,
267 "Ambiguous match for cell ID %s: more than one RAN type is serving this cell"
268 " ID: %s and %s\n",
269 gsm0808_cell_id_name(cid),
270 rp_from_cell_id->fi->id,
271 rp->fi->id);
272 /* But logging is all we're going to do about it. */
273 }
274
275 /* Use the first found RAN peer, but if multiple matches are found, favor the one that matches
276 * the current RAN type. */
277 if (!rp_from_cell_id || rp->sri == msc_a->c.ran->sri)
278 rp_from_cell_id = rp;
279 }
280 }
281
282 /* Did we find mismatching targets from neighbor config and from connected cells? */
283 if (rp_from_neighbor_ident && rp_from_cell_id
284 && rp_from_neighbor_ident != rp_from_cell_id) {
285 LOG_HO(msc_a, LOGL_ERROR, "Ambiguous match for cell ID %s:"
286 " neighbor config points at %s; a matching cell is also served by connected RAN peer %s\n",
287 gsm0808_cell_id_name(cid), rp_from_neighbor_ident->fi->id, rp_from_cell_id->fi->id);
288 /* But logging is all we're going to do about it. */
289 }
290
291 if (rp_from_neighbor_ident && rp_from_neighbor_ident->sri != msc_a->c.ran->sri) {
292 LOG_HO(msc_a, LOGL_ERROR,
293 "Neighbor config indicates inter-RAT Handover, which is not implemented. Ignoring target %s\n",
294 rp_from_neighbor_ident->fi->id);
295 rp_from_neighbor_ident = NULL;
296 }
297
298 if (rp_from_cell_id && rp_from_cell_id->sri != msc_a->c.ran->sri) {
299 LOG_HO(msc_a, LOGL_ERROR,
300 "Target RAN peer indicates inter-RAT Handover, which is not implemented. Ignoring target %s\n",
301 rp_from_cell_id->fi->id);
302 rp_from_cell_id = NULL;
303 }
304
305 *ran_peer_from_neighbor_ident = rp_from_neighbor_ident;
306 *ran_peer_from_seen_cells = rp_from_cell_id;
307
308 return rp_from_neighbor_ident || rp_from_cell_id ? MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER : MSC_NEIGHBOR_TYPE_NONE;
309}
310
311static bool msc_ho_find_next_target_cell(struct msc_a *msc_a)
312{
313 struct vlr_subscr *vsub = msc_a_vsub(msc_a);
314 struct ran_handover_required *info = &msc_a->ho.info;
315 struct gsm0808_cell_id *cid = &msc_a->ho.new_cell.cid;
316 const struct neighbor_ident_entry *e;
317 struct ran_peer *rp_from_neighbor_ident = NULL;
318 struct ran_peer *rp_from_cell_id = NULL;
319 struct ran_peer *rp;
320
321 unsigned int cil_idx = msc_a->ho.next_cil_idx;
322 msc_a->ho.next_cil_idx++;
323
324 msc_a->ho.new_cell.type = MSC_NEIGHBOR_TYPE_NONE;
325
326 if (cil_idx >= info->cil.id_list_len)
327 return false;
328
329 *cid = (struct gsm0808_cell_id){
330 .id_discr = info->cil.id_discr,
331 .id = info->cil.id_list[cil_idx],
332 };
333
334 msc_a->ho.new_cell.cgi = (struct osmo_cell_global_id){
335 .lai = vsub->cgi.lai,
336 };
337 gsm0808_cell_id_to_cgi(&msc_a->ho.new_cell.cgi, cid);
338
339 switch (msc_ho_find_target_cell(msc_a, cid, &e, &rp_from_neighbor_ident, &rp_from_cell_id)) {
340 case MSC_NEIGHBOR_TYPE_REMOTE_MSC:
341 OSMO_ASSERT(e);
342 msc_a->ho.new_cell.ran_type = e->addr.ran_type;
343 msc_a->ho.new_cell.type = MSC_NEIGHBOR_TYPE_REMOTE_MSC;
344 msc_a->ho.new_cell.msc_ipa_name = e->addr.remote_msc_ipa_name.buf;
345 return true;
346
347 case MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER:
348 rp = rp_from_neighbor_ident ? : rp_from_cell_id;
349 OSMO_ASSERT(rp);
350 msc_a->ho.new_cell.type = MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER;
351 msc_a->ho.new_cell.ran_peer = rp;
352 return true;
353
354 default:
355 break;
356 }
357
358 LOG_HO(msc_a, LOGL_DEBUG, "Cannot find target peer for cell ID %s\n", gsm0808_cell_id_name(cid));
359 /* Try the next cell id, if any. */
360 return msc_ho_find_next_target_cell(msc_a);
361}
362
363static void msc_ho_fsm_required_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
364{
365 struct msc_a *msc_a = fi->priv;
366
367 if (!msc_ho_find_next_target_cell(msc_a)) {
368 int tried = msc_a->ho.next_cil_idx - 1;
369 msc_ho_failed(msc_a, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE,
370 "Attempted Handover to %u cells without success\n", tried);
371 return;
372 }
373
374 msc_ho_fsm_state_chg(msc_a, MSC_HO_ST_WAIT_REQUEST_ACK);
375}
376
377static void msc_ho_send_handover_request(struct msc_a *msc_a)
378{
379 struct vlr_subscr *vsub = msc_a_vsub(msc_a);
380 struct gsm_network *net = msc_a_net(msc_a);
381 struct gsm0808_channel_type channel_type;
Philipp Maier7da956e2020-06-09 14:34:40 +0200382 struct gsm_trans *cc_trans = msc_a->cc.active_trans;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100383 struct ran_msg ran_enc_msg = {
384 .msg_type = RAN_MSG_HANDOVER_REQUEST,
385 .handover_request = {
386 .imsi = vsub->imsi,
387 .classmark = &vsub->classmark,
388 .geran = {
389 .chosen_encryption = &msc_a->geran_encr,
390 .a5_encryption_mask = net->a5_encryption_mask,
391 },
392 .bssap_cause = GSM0808_CAUSE_BETTER_CELL,
393 .current_channel_type_1_present = msc_a->ho.info.current_channel_type_1_present,
394 .current_channel_type_1 = msc_a->ho.info.current_channel_type_1,
395 .speech_version_used = msc_a->ho.info.speech_version_used,
396 .old_bss_to_new_bss_info_raw = msc_a->ho.info.old_bss_to_new_bss_info_raw,
397 .old_bss_to_new_bss_info_raw_len = msc_a->ho.info.old_bss_to_new_bss_info_raw_len,
398
399 /* Don't send AoIP Transport Layer Address for inter-MSC Handover */
400 .rtp_ran_local = (msc_a->ho.new_cell.type == MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER)
401 ? call_leg_local_ip(msc_a->cc.call_leg, RTP_TO_RAN) : NULL,
Philipp Maier7da956e2020-06-09 14:34:40 +0200402 .call_id_present = true,
403 .call_id = cc_trans->callref,
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100404 },
405 };
406
Neels Hofmeyr73d093a2021-06-23 23:54:43 +0200407 if (msc_a->geran_encr.key_len)
408 LOG_MSC_A(msc_a, LOGL_DEBUG, "HO Request with ciphering: A5/%d kc %s kc128 %s\n",
409 msc_a->geran_encr.alg_id - 1,
410 osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.key, msc_a->geran_encr.key_len),
411 msc_a->geran_encr.kc128_present ?
412 osmo_hexdump_nospc_c(OTC_SELECT, msc_a->geran_encr.kc128, sizeof(msc_a->geran_encr.kc128))
413 : "-");
414
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100415 if (msc_a->cc.active_trans) {
416 if (mncc_bearer_cap_to_channel_type(&channel_type, &msc_a->cc.active_trans->bearer_cap)) {
417 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
418 "Failed to encode Bearer Cap to Channel Type\n");
419 return;
420 }
421 ran_enc_msg.handover_request.geran.channel_type = &channel_type;
422 }
423
424 gsm0808_cell_id_from_cgi(&ran_enc_msg.handover_request.cell_id_serving, CELL_IDENT_WHOLE_GLOBAL, &vsub->cgi);
425 ran_enc_msg.handover_request.cell_id_target = msc_a->ho.new_cell.cid;
426
427 if (msc_a_msg_down(msc_a, MSC_ROLE_T, MSC_T_EV_FROM_A_PREPARE_HANDOVER_REQUEST, &ran_enc_msg))
428 msc_ho_try_next_cell(msc_a, "Failed to send Handover Request message\n");
429}
430
431static void msc_ho_fsm_wait_request_ack_onenter(struct osmo_fsm_inst *fi, uint32_t prev_state)
432{
433 struct msc_a *msc_a = fi->priv;
434 struct msc_i *msc_i = msc_a_msc_i(msc_a);
435 struct msc_t *msc_t;
436 struct ran_peer *rp;
437 const char *ipa_name;
438
439 msc_t = msc_a_msc_t(msc_a);
440 if (msc_t) {
441 /* All the other code should prevent this from happening, ever. */
442 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
443 "Cannot initiate Handover Request, there still is an active MSC-T role: %s\n",
444 msc_t->c.fi->id);
445 return;
446 }
447
448 if (!msc_i) {
449 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
450 "Cannot initiate Handover Request, there is no MSC-I role\n");
451 return;
452 }
453
454 if (!msc_i->c.remote_to
455 && !(msc_i->ran_conn && msc_i->ran_conn->ran_peer)) {
456 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
457 "Cannot initiate Handover Request, MSC-I role has no connection\n");
458 return;
459 }
460
461 switch (msc_a->ho.new_cell.type) {
462 case MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER:
463 rp = msc_a->ho.new_cell.ran_peer;
464 OSMO_ASSERT(rp && rp->fi);
465
466 if (msc_i->c.remote_to) {
467 LOG_HO(msc_a, LOGL_INFO,
468 "Starting inter-MSC Subsequent Handover from remote MSC %s to local %s\n",
469 msc_i->c.remote_to->remote_name, rp->fi->id);
470 msc_a->ho.subsequent_ho = true;
471 } else {
472 LOG_HO(msc_a, LOGL_INFO, "Starting inter-BSC Handover from %s to %s\n",
473 msc_i->ran_conn->ran_peer->fi->id, rp->fi->id);
474 }
475
Vadim Yanitskiya870faf2019-05-11 02:45:46 +0700476 msc_t = msc_t_alloc(msc_a->c.msub, rp);
477 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100478
479 case MSC_NEIGHBOR_TYPE_REMOTE_MSC:
480 ipa_name = msc_a->ho.new_cell.msc_ipa_name;
481 OSMO_ASSERT(ipa_name);
482
483 if (msc_i->c.remote_to) {
484 LOG_HO(msc_a, LOGL_INFO,
485 "Starting inter-MSC Subsequent Handover from remote MSC %s to remote MSC at %s\n",
486 msc_i->c.remote_to->remote_name, osmo_quote_str(ipa_name, -1));
487 msc_a->ho.subsequent_ho = true;
488 } else {
489 LOG_HO(msc_a, LOGL_INFO, "Starting inter-MSC Handover from local %s to remote MSC at %s\n",
490 msc_i->ran_conn->ran_peer->fi->id,
491 osmo_quote_str(ipa_name, -1));
492 }
493
Vadim Yanitskiya870faf2019-05-11 02:45:46 +0700494 msc_t = msc_t_remote_alloc(msc_a->c.msub, msc_a->c.ran,
495 (const uint8_t *) ipa_name,
496 strlen(ipa_name));
497 break;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100498
499 default:
500 msc_ho_try_next_cell(msc_a, "unknown Handover target type %d\n", msc_a->ho.new_cell.type);
501 return;
502 }
503
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100504 if (!msc_t) {
505 /* There should definitely be one now. */
506 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE,
507 "Cannot initiate Handover Request, failed to set up a target MSC-T\n");
508 return;
509 }
Vadim Yanitskiya870faf2019-05-11 02:45:46 +0700510
511 msc_ho_send_handover_request(msc_a);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100512}
513
514static void msc_ho_rx_request_ack(struct msc_a *msc_a, struct msc_a_ran_dec_data *hra);
515
516static void msc_ho_fsm_wait_request_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
517{
518 struct msc_a *msc_a = fi->priv;
519
520 switch (event) {
521
522 case MSC_HO_EV_RX_REQUEST_ACK:
523 msc_ho_rx_request_ack(msc_a, (struct msc_a_ran_dec_data*)data);
524 return;
525
526 case MSC_HO_EV_RX_FAILURE:
527 msc_ho_failed(msc_a, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE,
528 "Received Handover Failure message\n");
529 return;
530
531 default:
532 OSMO_ASSERT(false);
533 }
534}
535
536static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a);
537
538void msc_ho_mncc_forward_cb(struct mncc_call *mncc_call, const union mncc_msg *mncc_msg, void *data)
539{
540 struct msc_a *msc_a = data;
541 switch (mncc_msg->msg_type) {
542 case MNCC_RTP_CONNECT:
543 msc_a->ho.rtp_switched_to_new_cell = true;
544 return;
545 default:
546 return;
547 }
548}
549
550/* Initiate call forwarding via MNCC: call the Handover Number that the other MSC assigned. */
551static int msc_ho_start_inter_msc_call_forwarding(struct msc_a *msc_a, struct msc_t *msc_t,
552 const struct msc_a_ran_dec_data *hra)
553{
554 const struct osmo_gsup_message *e_info = hra->an_apdu->e_info;
555 struct gsm_mncc outgoing_call_req = {};
556 struct call_leg *cl = msc_a->cc.call_leg;
557 struct rtp_stream *rtp_to_ran = cl ? cl->rtp[RTP_TO_RAN] : NULL;
558 struct mncc_call *mncc_call;
559
560 if (!e_info || !e_info->msisdn_enc || !e_info->msisdn_enc_len) {
561 msc_ho_try_next_cell(msc_a,
562 "No Handover Number in Handover Request Acknowledge from remote MSC\n");
563 return -EINVAL;
564 }
565
Neels Hofmeyrda3ce712019-05-09 14:16:26 +0200566 if (!rtp_to_ran) {
567 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "Unexpected: no RTP stream is set up\n");
568 return -EINVAL;
569 }
570
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100571 /* Backup old cell's RTP IP:port and codec data */
572 msc_a->ho.old_cell.ran_remote_rtp = rtp_to_ran->remote;
573 msc_a->ho.old_cell.codec = rtp_to_ran->codec;
574
575 /* Blindly taken over from an MNCC trace of existing code: send an all-zero CCCAP: */
576 outgoing_call_req.fields |= MNCC_F_CCCAP;
577
578 /* Called number */
579 outgoing_call_req.fields |= MNCC_F_CALLED;
580 outgoing_call_req.called.plan = 1; /* Empirical magic number. There seem to be no enum or defines for this.
581 * The only other place setting this apparently is gsm48_decode_called(). */
582 if (gsm48_decode_bcd_number2(outgoing_call_req.called.number, sizeof(outgoing_call_req.called.number),
583 e_info->msisdn_enc, e_info->msisdn_enc_len, 0)) {
584 msc_ho_try_next_cell(msc_a,
585 "Failed to decode Handover Number in Handover Request Acknowledge"
586 " from remote MSC\n");
587 return -EINVAL;
588 }
589
590 if (msc_a->cc.active_trans) {
591 outgoing_call_req.fields |= MNCC_F_BEARER_CAP;
592 outgoing_call_req.bearer_cap = msc_a->cc.active_trans->bearer_cap;
593 }
594
595 mncc_call = mncc_call_alloc(msc_a_vsub(msc_a),
596 msc_a->ho.fi,
597 MSC_HO_EV_MNCC_FORWARDING_COMPLETE,
598 MSC_HO_EV_MNCC_FORWARDING_FAILED,
599 msc_ho_mncc_forward_cb, msc_a);
600
601 mncc_call_set_rtp_stream(mncc_call, rtp_to_ran);
602 msc_a->ho.new_cell.mncc_forwarding_to_remote_ran = mncc_call;
603 return mncc_call_outgoing_start(mncc_call, &outgoing_call_req);
604}
605
606static void msc_ho_rx_request_ack(struct msc_a *msc_a, struct msc_a_ran_dec_data *hra)
607{
608 struct msc_t *msc_t = msc_a_msc_t(msc_a);
609 struct ran_msg ran_enc_msg;
610
611 OSMO_ASSERT(hra->ran_dec);
612 OSMO_ASSERT(hra->an_apdu);
613
614 if (!msc_t) {
615 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "MSC-T role missing\n");
616 return;
617 }
618
619 if (!hra->ran_dec->handover_request_ack.rr_ho_command
620 || !hra->ran_dec->handover_request_ack.rr_ho_command_len) {
621 msc_ho_try_next_cell(msc_a, "Missing mandatory IE in Handover Request Acknowledge:"
622 " L3 Info (RR Handover Command)\n");
623 return;
624 }
625
626 if (!hra->ran_dec->handover_request_ack.chosen_channel_present) {
627 LOG_HO(msc_a, LOGL_DEBUG, "No 'Chosen Channel' IE in Handover Request Ack\n");
628 msc_t->geran.chosen_channel = 0;
629 } else
630 msc_t->geran.chosen_channel = hra->ran_dec->handover_request_ack.chosen_channel;
631
632 if (!hra->ran_dec->handover_request_ack.chosen_encr_alg) {
633 LOG_HO(msc_a, LOGL_DEBUG, "No 'Chosen Encryption Algorithm' IE in Handover Request Ack\n");
634 msc_t->geran.chosen_encr_alg = 0;
635 } else {
636 msc_t->geran.chosen_encr_alg = hra->ran_dec->handover_request_ack.chosen_encr_alg;
637 if (msc_t->geran.chosen_encr_alg < 1 || msc_t->geran.chosen_encr_alg > 8) {
638 msc_ho_try_next_cell(msc_a, "Handover Request Ack: Invalid 'Chosen Encryption Algorithm': %u\n",
639 msc_t->geran.chosen_encr_alg);
640 return;
641 }
642 }
643
644 msc_t->geran.chosen_speech_version = hra->ran_dec->handover_request_ack.chosen_speech_version;
645 if (!msc_t->geran.chosen_speech_version)
646 LOG_HO(msc_a, LOGL_DEBUG, "No 'Chosen Speech Version' IE in Handover Request Ack\n");
647
648 /* Inter-MSC call forwarding? */
649 if (msc_a->ho.new_cell.type == MSC_NEIGHBOR_TYPE_REMOTE_MSC) {
650 if (msc_ho_start_inter_msc_call_forwarding(msc_a, msc_t, hra))
651 return;
652 }
653
654 msc_ho_fsm_state_chg(msc_a, MSC_HO_ST_WAIT_COMPLETE);
655
656 /* Forward the RR Handover Command composed by the new RAN peer down to the old RAN peer */
657 ran_enc_msg = (struct ran_msg){
658 .msg_type = RAN_MSG_HANDOVER_COMMAND,
659 .handover_command = {
660 .rr_ho_command = hra->ran_dec->handover_request_ack.rr_ho_command,
661 .rr_ho_command_len = hra->ran_dec->handover_request_ack.rr_ho_command_len,
662 },
663 };
664
665 if (msc_a_msg_down(msc_a, MSC_ROLE_I,
666 msc_a->ho.subsequent_ho ? MSC_I_EV_FROM_A_PREPARE_SUBSEQUENT_HANDOVER_RESULT
667 : MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST,
668 &ran_enc_msg)) {
669 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "Failed to send Handover Command\n");
670 return;
671 }
672
673 msc_a->ho.new_cell.ran_remote_rtp = hra->ran_dec->handover_request_ack.remote_rtp;
Neels Hofmeyr84ce2062019-10-05 05:15:25 +0200674 if (osmo_sockaddr_str_is_nonzero(&msc_a->ho.new_cell.ran_remote_rtp)) {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100675 LOG_HO(msc_a, LOGL_DEBUG, "Request Ack contains cell's RTP address " OSMO_SOCKADDR_STR_FMT "\n",
676 OSMO_SOCKADDR_STR_FMT_ARGS(&msc_a->ho.new_cell.ran_remote_rtp));
677 }
678
679 msc_a->ho.new_cell.codec_present = hra->ran_dec->handover_request_ack.codec_present;
680 msc_a->ho.new_cell.codec = hra->ran_dec->handover_request_ack.codec;
681 if (hra->ran_dec->handover_request_ack.codec_present) {
682 LOG_HO(msc_a, LOGL_DEBUG, "Request Ack contains codec %s\n",
683 osmo_mgcpc_codec_name(msc_a->ho.new_cell.codec));
684 }
685}
686
687static void msc_ho_rtp_switch_to_new_cell(struct msc_a *msc_a)
688{
689 struct call_leg *cl = msc_a->cc.call_leg;
690 struct rtp_stream *rtp_to_ran = cl ? cl->rtp[RTP_TO_RAN] : NULL;
691
692 if (!rtp_to_ran) {
693 LOG_HO(msc_a, LOGL_DEBUG, "No RTP stream, nothing to switch\n");
694 return;
695 }
696
Neels Hofmeyr84ce2062019-10-05 05:15:25 +0200697 if (!osmo_sockaddr_str_is_nonzero(&msc_a->ho.new_cell.ran_remote_rtp)) {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100698 LOG_HO(msc_a, LOGL_DEBUG, "New cell's RTP IP:port not yet known, not switching RTP stream\n");
699 return;
700 }
701
702 if (msc_a->ho.rtp_switched_to_new_cell) {
703 LOG_HO(msc_a, LOGL_DEBUG, "Already switched RTP to new cell\n");
704 return;
705 }
706 msc_a->ho.rtp_switched_to_new_cell = true;
707
708 /* Backup old cell's RTP IP:port and codec data */
709 msc_a->ho.old_cell.ran_remote_rtp = rtp_to_ran->remote;
710 msc_a->ho.old_cell.codec = rtp_to_ran->codec;
711
712 LOG_HO(msc_a, LOGL_DEBUG, "Switching RTP stream to new cell: from " OSMO_SOCKADDR_STR_FMT " to " OSMO_SOCKADDR_STR_FMT "\n",
713 OSMO_SOCKADDR_STR_FMT_ARGS(&msc_a->ho.old_cell.ran_remote_rtp),
714 OSMO_SOCKADDR_STR_FMT_ARGS(&msc_a->ho.new_cell.ran_remote_rtp));
715
716 /* If a previous forwarding to a remote MSC is still active, this now becomes no longer responsible for the RTP
717 * stream. */
718 if (msc_a->cc.mncc_forwarding_to_remote_ran) {
719 if (msc_a->cc.mncc_forwarding_to_remote_ran->rtps != rtp_to_ran) {
720 LOG_HO(msc_a, LOGL_ERROR,
721 "Unexpected state: previous MNCC forwarding not using RTP-to-RAN stream\n");
722 /* That would be weird, but carry on anyway... */
723 }
724 mncc_call_detach_rtp_stream(msc_a->cc.mncc_forwarding_to_remote_ran);
725 }
726
727 /* Switch over to the new peer */
728 rtp_stream_set_remote_addr(rtp_to_ran, &msc_a->ho.new_cell.ran_remote_rtp);
729 if (msc_a->ho.new_cell.codec_present)
730 rtp_stream_set_codec(rtp_to_ran, msc_a->ho.new_cell.codec);
731 else
732 LOG_HO(msc_a, LOGL_ERROR, "No codec is set\n");
733 rtp_stream_commit(rtp_to_ran);
734}
735
736static void msc_ho_rtp_rollback_to_old_cell(struct msc_a *msc_a)
737{
738 struct call_leg *cl = msc_a->cc.call_leg;
739 struct rtp_stream *rtp_to_ran = cl ? cl->rtp[RTP_TO_RAN] : NULL;
740
741 if (!msc_a->ho.rtp_switched_to_new_cell) {
742 LOG_HO(msc_a, LOGL_DEBUG, "Not switched RTP to new cell yet, no need to roll back\n");
743 return;
744 }
745
746 if (!rtp_to_ran) {
747 LOG_HO(msc_a, LOGL_DEBUG, "No RTP stream, nothing to switch\n");
748 return;
749 }
750
Neels Hofmeyr84ce2062019-10-05 05:15:25 +0200751 if (!osmo_sockaddr_str_is_nonzero(&msc_a->ho.old_cell.ran_remote_rtp)) {
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100752 LOG_HO(msc_a, LOGL_DEBUG, "Have no RTP IP:port for the old cell, not switching back to\n");
753 return;
754 }
755
756 /* The new call forwarding to a remote MSC is no longer needed because the handover failed */
757 if (msc_a->ho.new_cell.mncc_forwarding_to_remote_ran)
758 mncc_call_detach_rtp_stream(msc_a->ho.new_cell.mncc_forwarding_to_remote_ran);
759
760 /* If before this handover, there was a call forwarding to a remote MSC in place, this now goes back into
761 * responsibility. */
762 if (msc_a->cc.mncc_forwarding_to_remote_ran)
763 mncc_call_set_rtp_stream(msc_a->cc.mncc_forwarding_to_remote_ran, rtp_to_ran);
764
765 msc_a->ho.rtp_switched_to_new_cell = false;
766 msc_a->ho.ready_to_switch_rtp = false;
767 LOG_HO(msc_a, LOGL_NOTICE, "Switching RTP back to old cell\n");
768
769 /* Switch back to the old cell */
770 rtp_stream_set_remote_addr(rtp_to_ran, &msc_a->ho.old_cell.ran_remote_rtp);
771 rtp_stream_set_codec(rtp_to_ran, msc_a->ho.old_cell.codec);
772 rtp_stream_commit(rtp_to_ran);
773}
774
775static void msc_ho_send_handover_succeeded(struct msc_a *msc_a)
776{
777 struct ran_msg ran_enc_msg = {
778 .msg_type = RAN_MSG_HANDOVER_SUCCEEDED,
779 };
780
781 if (msc_a_msg_down(msc_a, MSC_ROLE_I, MSC_I_EV_FROM_A_FORWARD_ACCESS_SIGNALLING_REQUEST, &ran_enc_msg))
782 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "Failed to send Handover Succeeded message\n");
783}
784
785static void msc_ho_fsm_wait_complete(struct osmo_fsm_inst *fi, uint32_t event, void *data)
786{
787 struct msc_a *msc_a = fi->priv;
788
789 switch (event) {
790
791 case MSC_HO_EV_RX_DETECT:
792 msc_a->ho.ready_to_switch_rtp = true;
793 /* For inter-MSC, the mncc_fsm switches the rtp_stream upon MNCC_RTP_CONNECT.
794 * For inter-BSC, need to switch here to the address obtained from Handover Request Ack. */
795 if (msc_a->ho.new_cell.type == MSC_NEIGHBOR_TYPE_LOCAL_RAN_PEER)
796 msc_ho_rtp_switch_to_new_cell(msc_a);
797 msc_ho_send_handover_succeeded(msc_a);
798 return;
799
800 case MSC_HO_EV_RX_COMPLETE:
801 msc_ho_success(msc_a);
802 return;
803
804 case MSC_HO_EV_RX_FAILURE:
805 msc_ho_failed(msc_a, GSM0808_CAUSE_NO_RADIO_RESOURCE_AVAILABLE,
806 "Received Handover Failure message\n");
807 return;
808
809 case MSC_HO_EV_MNCC_FORWARDING_FAILED:
810 msc_ho_failed(msc_a, GSM0808_CAUSE_EQUIPMENT_FAILURE, "MNCC Forwarding failed\n");
811 return;
812
813 case MSC_HO_EV_MNCC_FORWARDING_COMPLETE:
814 return;
815
816 default:
817 OSMO_ASSERT(false);
818 }
819}
820
821static void msc_ho_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
822{
823 struct msc_a *msc_a = fi->priv;
824 struct msc_t *msc_t = msc_a_msc_t(msc_a);
825
826 /* paranoia */
827 if (msc_a->ho.fi != fi)
828 return;
829
830 /* Completely clear all handover state */
831 msc_a->ho = (struct msc_ho_state){};
832
833 if (msc_t)
834 msc_t_clear(msc_t);
835}
836
837static int msc_ho_fsm_timer_cb(struct osmo_fsm_inst *fi)
838{
839 return 1;
840}
841
842#define S(x) (1 << (x))
843
844static const struct osmo_fsm_state msc_ho_fsm_states[] = {
845 [MSC_HO_ST_REQUIRED] = {
846 .name = OSMO_STRINGIFY(MSC_HO_ST_REQUIRED),
847 .out_state_mask = 0
848 | S(MSC_HO_ST_REQUIRED)
849 | S(MSC_HO_ST_WAIT_REQUEST_ACK)
850 ,
851 .onenter = msc_ho_fsm_required_onenter,
852 },
853 [MSC_HO_ST_WAIT_REQUEST_ACK] = {
854 .name = OSMO_STRINGIFY(MSC_HO_ST_WAIT_REQUEST_ACK),
855 .in_event_mask = 0
856 | S(MSC_HO_EV_RX_REQUEST_ACK)
857 | S(MSC_HO_EV_RX_FAILURE)
858 ,
859 .out_state_mask = 0
860 | S(MSC_HO_ST_REQUIRED)
861 | S(MSC_HO_ST_WAIT_COMPLETE)
862 ,
863 .onenter = msc_ho_fsm_wait_request_ack_onenter,
864 .action = msc_ho_fsm_wait_request_ack,
865 },
866 [MSC_HO_ST_WAIT_COMPLETE] = {
867 .name = OSMO_STRINGIFY(MSC_HO_ST_WAIT_COMPLETE),
868 .in_event_mask = 0
869 | S(MSC_HO_EV_RX_DETECT)
870 | S(MSC_HO_EV_RX_COMPLETE)
871 | S(MSC_HO_EV_RX_FAILURE)
872 | S(MSC_HO_EV_MNCC_FORWARDING_COMPLETE)
873 | S(MSC_HO_EV_MNCC_FORWARDING_FAILED)
874 ,
875 .action = msc_ho_fsm_wait_complete,
876 },
877};
878
879static const struct value_string msc_ho_fsm_event_names[] = {
880 OSMO_VALUE_STRING(MSC_HO_EV_RX_REQUEST_ACK),
881 OSMO_VALUE_STRING(MSC_HO_EV_RX_DETECT),
882 OSMO_VALUE_STRING(MSC_HO_EV_RX_COMPLETE),
883 OSMO_VALUE_STRING(MSC_HO_EV_RX_FAILURE),
884 {}
885};
886
887struct osmo_fsm msc_ho_fsm = {
888 .name = "handover",
889 .states = msc_ho_fsm_states,
890 .num_states = ARRAY_SIZE(msc_ho_fsm_states),
891 .log_subsys = DHO,
892 .event_names = msc_ho_fsm_event_names,
893 .timer_cb = msc_ho_fsm_timer_cb,
894 .cleanup = msc_ho_fsm_cleanup,
895};