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