blob: 001dfb1e01d254b4ef48967641a610f3feae1286 [file] [log] [blame]
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001/*
2 * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
3 * All Rights Reserved
4 *
5 * SPDX-License-Identifier: AGPL-3.0+
6 *
7 * Author: Neels Hofmeyr
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU Affero General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU Affero General Public License for more details.
18 *
19 * You should have received a copy of the GNU Affero General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include <osmocom/core/linuxlist.h>
24#include <osmocom/core/logging.h>
25#include <osmocom/core/fsm.h>
26#include <osmocom/sigtran/sccp_helpers.h>
27
28#include <osmocom/msc/ran_peer.h>
29#include <osmocom/msc/sccp_ran.h>
30#include <osmocom/msc/msub.h>
31#include <osmocom/msc/msc_i.h>
32#include <osmocom/msc/msc_a.h>
33#include <osmocom/msc/vlr.h>
34#include <osmocom/msc/ran_conn.h>
35#include <osmocom/msc/cell_id_list.h>
36
37static struct osmo_fsm ran_peer_fsm;
38
39static __attribute__((constructor)) void ran_peer_init()
40{
41 OSMO_ASSERT( osmo_fsm_register(&ran_peer_fsm) == 0);
42}
43
44/* Allocate a RAN peer with FSM instance. To deallocate, call osmo_fsm_inst_term(ran_peer->fi). */
45static struct ran_peer *ran_peer_alloc(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
46{
47 struct ran_peer *rp;
48 struct osmo_fsm_inst *fi;
49 char *sccp_addr;
50 char *pos;
51
52 fi = osmo_fsm_inst_alloc(&ran_peer_fsm, sri, NULL, LOGL_DEBUG, NULL);
53 OSMO_ASSERT(fi);
54
55 /* Unfortunately, osmo_sccp_inst_addr_name() returns "RI=SSN_PC,PC=0.24.1,SSN=BSSAP" but neither commas nor
56 * full-stops are allowed as FSM inst id. Make it "RI=SSN_PC:PC-0-24-1:SSN-BSSAP". */
57 sccp_addr = osmo_sccp_inst_addr_name(sri->sccp, peer_addr);
58 for (pos = sccp_addr; *pos; pos++) {
59 if (*pos == ',')
60 *pos = ':';
61 else if (*pos == '.' || *pos == '=')
62 *pos = '-';
63 }
64 osmo_fsm_inst_update_id_f(fi, "%s:%s", osmo_rat_type_name(sri->ran->type), sccp_addr);
65
66 rp = talloc_zero(fi, struct ran_peer);
67 OSMO_ASSERT(rp);
68 *rp = (struct ran_peer){
69 .sri = sri,
70 .peer_addr = *peer_addr,
71 .fi = fi,
72 };
73 INIT_LLIST_HEAD(&rp->cells_seen);
74 fi->priv = rp;
75
76 llist_add(&rp->entry, &sri->ran_peers);
77
78 return rp;
79}
80
81struct ran_peer *ran_peer_find_or_create(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
82{
83 struct ran_peer *rp = ran_peer_find(sri, peer_addr);
84 if (rp)
85 return rp;
86 return ran_peer_alloc(sri, peer_addr);
87}
88
89struct ran_peer *ran_peer_find(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
90{
91 struct ran_peer *rp;
92 llist_for_each_entry(rp, &sri->ran_peers, entry) {
93 if (osmo_sccp_addr_ri_cmp(peer_addr, &rp->peer_addr))
94 continue;
95 return rp;
96 }
97 return NULL;
98}
99
100void ran_peer_cells_seen_add(struct ran_peer *ran_peer, const struct gsm0808_cell_id *cid)
101{
102 if (!cell_id_list_add_cell(ran_peer, &ran_peer->cells_seen, cid))
103 return;
104 LOG_RAN_PEER_CAT(ran_peer, DPAG, LOGL_NOTICE, "Added seen cell to this RAN peer: %s\n",
105 gsm0808_cell_id_name(cid));
106}
107
108static const struct osmo_tdef_state_timeout ran_peer_fsm_timeouts[32] = {
109 [RAN_PEER_ST_WAIT_RX_RESET_ACK] = { .T = -1 },
110 [RAN_PEER_ST_DISCARDING] = { .T = -2 },
111};
112
113#define ran_peer_state_chg(RAN_PEER, NEXT_STATE) \
114 osmo_tdef_fsm_inst_state_chg((RAN_PEER)->fi, NEXT_STATE, ran_peer_fsm_timeouts, g_sccp_tdefs, 5)
115
116void ran_peer_discard_all_conns(struct ran_peer *rp)
117{
118 struct ran_conn *conn, *next;
119
120 ran_peer_for_each_ran_conn_safe(conn, next, rp) {
121 ran_conn_discard(conn);
122 }
123}
124
Neels Hofmeyrb6972742020-06-26 15:20:51 +0200125static void ran_peer_update_osmux_support(struct ran_peer *rp, int supports_osmux)
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200126{
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200127 bool old_value = rp->remote_supports_osmux;
128
Neels Hofmeyrb6972742020-06-26 15:20:51 +0200129 switch (supports_osmux) {
130 case 1:
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200131 rp->remote_supports_osmux = true;
Neels Hofmeyrb6972742020-06-26 15:20:51 +0200132 break;
133 case -1:
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200134 rp->remote_supports_osmux = false;
Neels Hofmeyrb6972742020-06-26 15:20:51 +0200135 break;
136 default:
137 return;
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200138 }
139
140 if (old_value != rp->remote_supports_osmux)
141 LOG_RAN_PEER(rp, LOGL_INFO, "BSC detected AoIP Osmux support changed: %d->%d\n",
142 old_value, rp->remote_supports_osmux);
143}
144
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100145/* Drop all SCCP connections for this ran_peer, respond with RESET ACKNOWLEDGE and move to READY state. */
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200146static void ran_peer_rx_reset(struct ran_peer *rp, struct msgb* msg)
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100147{
148 struct msgb *reset_ack;
149
150 ran_peer_discard_all_conns(rp);
151
152 reset_ack = rp->sri->ran->sccp_ran_ops.make_reset_msg(rp->sri, SCCP_RAN_MSG_RESET_ACK);
153
154 if (!reset_ack) {
155 LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to compose RESET ACKNOWLEDGE message\n");
156 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
157 return;
158 }
159
160 if (sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, reset_ack)) {
161 LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to send RESET ACKNOWLEDGE message\n");
162 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
Vadim Yanitskiy53d3e0e2019-05-10 02:44:57 +0700163 msgb_free(reset_ack);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100164 return;
165 }
166
167 LOG_RAN_PEER(rp, LOGL_INFO, "Sent RESET ACKNOWLEDGE\n");
168
Vadim Yanitskiy53d3e0e2019-05-10 02:44:57 +0700169 /* sccp_ran_down_l2_cl() doesn't free msgb */
170 msgb_free(reset_ack);
171
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100172 ran_peer_state_chg(rp, RAN_PEER_ST_READY);
173}
174
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200175static void ran_peer_rx_reset_ack(struct ran_peer *rp, struct msgb* msg)
Pau Espin Pedrolf15852b2019-05-13 19:54:02 +0200176{
177 ran_peer_state_chg(rp, RAN_PEER_ST_READY);
178}
179
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100180void ran_peer_reset(struct ran_peer *rp)
181{
182 struct msgb *reset;
183
184 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET_ACK);
185 ran_peer_discard_all_conns(rp);
186
187 reset = rp->sri->ran->sccp_ran_ops.make_reset_msg(rp->sri, SCCP_RAN_MSG_RESET);
188
189 if (!reset) {
190 LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to compose RESET message\n");
191 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
192 return;
193 }
194
195 if (sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, reset)) {
196 LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to send RESET message\n");
197 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
198 return;
199 }
200}
201
202void ran_peer_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
203{
204 struct ran_peer *rp = fi->priv;
205 struct ran_peer_ev_ctx *ctx = data;
206 struct msgb *msg = ctx->msg;
Neels Hofmeyr59de1562020-07-04 01:49:10 +0200207 enum reset_msg_type is_reset;
Neels Hofmeyrb6972742020-06-26 15:20:51 +0200208 int supports_osmux;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100209
210 switch (event) {
211 case RAN_PEER_EV_MSG_UP_CL:
Neels Hofmeyr59de1562020-07-04 01:49:10 +0200212 is_reset = rp->sri->ran->sccp_ran_ops.is_reset_msg(rp->sri, fi, msg, &supports_osmux);
Neels Hofmeyrb6972742020-06-26 15:20:51 +0200213 ran_peer_update_osmux_support(rp, supports_osmux);
Neels Hofmeyr59de1562020-07-04 01:49:10 +0200214 switch (is_reset) {
215 case SCCP_RAN_MSG_RESET:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100216 osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET, msg);
217 return;
Neels Hofmeyr59de1562020-07-04 01:49:10 +0200218 case SCCP_RAN_MSG_RESET_ACK:
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100219 osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET_ACK, msg);
220 return;
221 default:
222 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled ConnectionLess message received: %s\n",
223 rp->sri->ran->sccp_ran_ops.msg_name(rp->sri, msg));
224 return;
225 }
226
227 default:
228 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
229 return;
230 }
231}
232
233void clear_and_disconnect(struct ran_peer *rp, uint32_t conn_id)
234{
235 struct msgb *clear;
236 struct ran_msg ran_enc_msg = {
237 .msg_type = RAN_MSG_CLEAR_COMMAND,
238 .clear_command = {
239 .gsm0808_cause = GSM0808_CAUSE_EQUIPMENT_FAILURE,
240 },
241 };
242
243 clear = rp->sri->ran->ran_encode(rp->fi, &ran_enc_msg);
244 if (!clear
245 || sccp_ran_down_l2_co(rp->sri, conn_id, clear))
246 LOG_RAN_PEER(rp, LOGL_ERROR, "Cannot sent Clear command\n");
247
248 sccp_ran_disconnect(rp->sri, conn_id, 0);
249}
250
251void ran_peer_st_wait_rx_reset(struct osmo_fsm_inst *fi, uint32_t event, void *data)
252{
253 struct ran_peer *rp = fi->priv;
254 struct ran_peer_ev_ctx *ctx;
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200255 struct msgb *msg;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100256
257 switch (event) {
258
259 case RAN_PEER_EV_MSG_UP_CO:
260 case RAN_PEER_EV_MSG_UP_CO_INITIAL:
261 ctx = data;
262 OSMO_ASSERT(ctx);
263
264 if (rp->sri->ignore_missing_reset) {
265 LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
266 " Accepting RAN peer implicitly (legacy compat)\n");
267 ran_peer_state_chg(rp, RAN_PEER_ST_READY);
268 osmo_fsm_inst_dispatch(rp->fi, event, data);
269 return;
270 }
271
272 LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
273 " Disconnecting on incoming message, sending RESET to RAN peer.\n");
274 /* No valid RESET procedure has happened here yet. Usually, we're expecting the RAN peer (BSC,
275 * RNC) to first send a RESET message before sending Connection Oriented messages. So if we're
276 * getting a CO message, likely we've just restarted or something. Send a RESET to the peer. */
277
278 /* Make sure the MS / UE properly disconnects. */
279 clear_and_disconnect(rp, ctx->conn_id);
280
281 ran_peer_reset(rp);
282 return;
283
284 case RAN_PEER_EV_RX_RESET:
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200285 msg = (struct msgb*)data;
286 ran_peer_rx_reset(rp, msg);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100287 return;
288
289 default:
290 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
291 return;
292 }
293}
294
295void ran_peer_st_wait_rx_reset_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
296{
297 struct ran_peer *rp = fi->priv;
298 struct ran_peer_ev_ctx *ctx;
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200299 struct msgb *msg;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100300
301 switch (event) {
302
303 case RAN_PEER_EV_RX_RESET_ACK:
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200304 msg = (struct msgb*)data;
305 ran_peer_rx_reset_ack(rp, msg);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100306 return;
307
308 case RAN_PEER_EV_MSG_UP_CO:
309 case RAN_PEER_EV_MSG_UP_CO_INITIAL:
310 ctx = data;
311 OSMO_ASSERT(ctx);
312 LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
313 " Disconnecting on incoming message, sending RESET to RAN peer.\n");
314 sccp_ran_disconnect(rp->sri, ctx->conn_id, 0);
315 /* No valid RESET procedure has happened here yet. */
316 ran_peer_reset(rp);
317 return;
318
319 case RAN_PEER_EV_RX_RESET:
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200320 msg = (struct msgb*)data;
321 ran_peer_rx_reset(rp, msg);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100322 return;
323
324 default:
325 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
326 return;
327 }
328}
329
330static struct ran_conn *new_incoming_conn(struct ran_peer *rp, uint32_t conn_id)
331{
332 struct gsm_network *net = rp->sri->user_data;
333 struct msub *msub;
334 struct msc_i *msc_i;
335 struct msc_a *msc_a;
336 struct ran_conn *ran_conn;
337
338 msub = msub_alloc(net);
339 OSMO_ASSERT(msub);
340 msc_i = msc_i_alloc(msub, rp->sri->ran);
341 OSMO_ASSERT(msc_i);
342
343 ran_conn = ran_conn_create_incoming(rp, conn_id);
344 if (!ran_conn) {
345 LOG_RAN_PEER(rp, LOGL_ERROR, "Cannot allocate ran_conn\n");
346 return NULL;
347 }
348 msc_i_set_ran_conn(msc_i, ran_conn);
349
350 msc_a = msc_a_alloc(msub, rp->sri->ran);
351 OSMO_ASSERT(msc_a);
352
353 return msc_i->ran_conn;
354}
355
356void ran_peer_st_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
357{
358 struct ran_peer *rp = fi->priv;
359 struct ran_peer_ev_ctx *ctx;
360 struct ran_conn *conn;
361 struct an_apdu an_apdu;
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200362 struct msgb *msg;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100363
364 switch (event) {
365
366 case RAN_PEER_EV_MSG_UP_CO_INITIAL:
367 ctx = data;
Vadim Yanitskiyd14422a2019-07-09 00:37:49 +0700368 OSMO_ASSERT(ctx);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100369 OSMO_ASSERT(!ctx->conn);
370 OSMO_ASSERT(ctx->msg);
371
372 conn = new_incoming_conn(rp, ctx->conn_id);
373 if (!conn)
374 return;
375 if (!conn->msc_role) {
376 LOG_RAN_PEER(rp, LOGL_ERROR,
377 "Rx CO Initial message on conn that is not associated with any MSC role\n");
378 return;
379 }
380
381
382 an_apdu = (struct an_apdu){
383 .an_proto = rp->sri->ran->an_proto,
384 .msg = ctx->msg,
385 };
386
387 osmo_fsm_inst_dispatch(conn->msc_role, MSC_EV_FROM_RAN_COMPLETE_LAYER_3, &an_apdu);
388 return;
389
390 case RAN_PEER_EV_MSG_UP_CO:
391 ctx = data;
392 OSMO_ASSERT(ctx);
393 OSMO_ASSERT(ctx->conn);
394 OSMO_ASSERT(ctx->msg);
395
396 if (!ctx->conn->msc_role) {
397 LOG_RAN_PEER(rp, LOGL_ERROR,
398 "Rx CO message on conn that is not associated with any MSC role\n");
399 return;
400 }
401
402 an_apdu = (struct an_apdu){
403 .an_proto = rp->sri->ran->an_proto,
404 .msg = ctx->msg,
405 };
406
407 osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu);
408 return;
409
410 case RAN_PEER_EV_MSG_DOWN_CO_INITIAL:
411 ctx = data;
412 OSMO_ASSERT(ctx);
413 OSMO_ASSERT(ctx->msg);
414 sccp_ran_down_l2_co_initial(rp->sri, &rp->peer_addr, ctx->conn_id, ctx->msg);
415 return;
416
417 case RAN_PEER_EV_MSG_DOWN_CO:
418 ctx = data;
419 OSMO_ASSERT(ctx);
420 OSMO_ASSERT(ctx->msg);
421 sccp_ran_down_l2_co(rp->sri, ctx->conn_id, ctx->msg);
422 return;
423
424 case RAN_PEER_EV_MSG_DOWN_CL:
425 OSMO_ASSERT(data);
426 sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, (struct msgb*)data);
427 return;
428
429 case RAN_PEER_EV_RX_RESET:
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +0200430 msg = (struct msgb*)data;
431 ran_peer_rx_reset(rp, msg);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100432 return;
433
434 default:
435 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
436 return;
437 }
438}
439
440static int ran_peer_fsm_timer_cb(struct osmo_fsm_inst *fi)
441{
442 struct ran_peer *rp = fi->priv;
443 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
444 return 0;
445}
446
447void ran_peer_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
448{
449 struct ran_peer *rp = fi->priv;
450 ran_peer_discard_all_conns(rp);
451 llist_del(&rp->entry);
452}
453
454static const struct value_string ran_peer_fsm_event_names[] = {
455 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CL),
456 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CO_INITIAL),
457 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CO),
458 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CL),
459 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CO_INITIAL),
460 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CO),
461 OSMO_VALUE_STRING(RAN_PEER_EV_RX_RESET),
462 OSMO_VALUE_STRING(RAN_PEER_EV_RX_RESET_ACK),
463 OSMO_VALUE_STRING(RAN_PEER_EV_CONNECTION_SUCCESS),
464 OSMO_VALUE_STRING(RAN_PEER_EV_CONNECTION_TIMEOUT),
465 {}
466};
467
468#define S(x) (1 << (x))
469
470static const struct osmo_fsm_state ran_peer_fsm_states[] = {
471 [RAN_PEER_ST_WAIT_RX_RESET] = {
472 .name = "WAIT_RX_RESET",
473 .action = ran_peer_st_wait_rx_reset,
474 .in_event_mask = 0
475 | S(RAN_PEER_EV_RX_RESET)
476 | S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
477 | S(RAN_PEER_EV_MSG_UP_CO)
478 | S(RAN_PEER_EV_CONNECTION_TIMEOUT)
479 ,
480 .out_state_mask = 0
481 | S(RAN_PEER_ST_WAIT_RX_RESET)
482 | S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
483 | S(RAN_PEER_ST_READY)
484 | S(RAN_PEER_ST_DISCARDING)
485 ,
486 },
487 [RAN_PEER_ST_WAIT_RX_RESET_ACK] = {
488 .name = "WAIT_RX_RESET_ACK",
489 .action = ran_peer_st_wait_rx_reset_ack,
490 .in_event_mask = 0
491 | S(RAN_PEER_EV_RX_RESET)
492 | S(RAN_PEER_EV_RX_RESET_ACK)
493 | S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
494 | S(RAN_PEER_EV_MSG_UP_CO)
495 | S(RAN_PEER_EV_CONNECTION_TIMEOUT)
496 ,
497 .out_state_mask = 0
498 | S(RAN_PEER_ST_WAIT_RX_RESET)
499 | S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
500 | S(RAN_PEER_ST_READY)
501 | S(RAN_PEER_ST_DISCARDING)
502 ,
503 },
504 [RAN_PEER_ST_READY] = {
505 .name = "READY",
506 .action = ran_peer_st_ready,
507 .in_event_mask = 0
508 | S(RAN_PEER_EV_RX_RESET)
509 | S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
510 | S(RAN_PEER_EV_MSG_UP_CO)
511 | S(RAN_PEER_EV_MSG_DOWN_CO_INITIAL)
512 | S(RAN_PEER_EV_MSG_DOWN_CO)
513 | S(RAN_PEER_EV_MSG_DOWN_CL)
514 ,
515 .out_state_mask = 0
516 | S(RAN_PEER_ST_WAIT_RX_RESET)
517 | S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
518 | S(RAN_PEER_ST_READY)
519 | S(RAN_PEER_ST_DISCARDING)
520 ,
521 },
522 [RAN_PEER_ST_DISCARDING] = {
523 .name = "DISCARDING",
524 },
525};
526
527static struct osmo_fsm ran_peer_fsm = {
528 .name = "ran_peer",
529 .states = ran_peer_fsm_states,
530 .num_states = ARRAY_SIZE(ran_peer_fsm_states),
531 .log_subsys = DRR,
532 .event_names = ran_peer_fsm_event_names,
533 .timer_cb = ran_peer_fsm_timer_cb,
534 .cleanup = ran_peer_fsm_cleanup,
535 .allstate_action = ran_peer_allstate_action,
536 .allstate_event_mask = 0
537 | S(RAN_PEER_EV_MSG_UP_CL)
538 ,
539};
540
541int ran_peer_up_l2(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *calling_addr, bool co, uint32_t conn_id,
542 struct msgb *l2)
543{
544 struct ran_peer *ran_peer = NULL;
545 uint32_t event;
546 struct ran_peer_ev_ctx ctx = {
547 .conn_id = conn_id,
548 .msg = l2,
549 };
550
551 if (co) {
552 struct ran_conn *conn;
553 llist_for_each_entry(conn, &sri->ran_conns, entry) {
554 if (conn->sccp_conn_id == conn_id) {
555 ran_peer = conn->ran_peer;
556 ctx.conn = conn;
557 break;
558 }
559 }
560
561 if (ran_peer && calling_addr) {
562 LOG_SCCP_RAN_CO(sri, calling_addr, conn_id, LOGL_ERROR,
563 "Connection-Oriented Initial message for already existing conn_id."
564 " Dropping message.\n");
565 return -EINVAL;
566 }
567
568 if (!ran_peer && !calling_addr) {
569 LOG_SCCP_RAN_CO(sri, calling_addr, conn_id, LOGL_ERROR,
570 "Connection-Oriented non-Initial message for unknown conn_id %u."
571 " Dropping message.\n", conn_id);
572 return -EINVAL;
573 }
574 }
575
576 if (calling_addr) {
577 ran_peer = ran_peer_find_or_create(sri, calling_addr);
578 if (!ran_peer) {
579 LOG_SCCP_RAN_CL(sri, calling_addr, LOGL_ERROR, "Cannot register RAN peer\n");
580 return -EIO;
581 }
582 }
583
584 OSMO_ASSERT(ran_peer && ran_peer->fi);
585
586 if (co)
587 event = calling_addr ? RAN_PEER_EV_MSG_UP_CO_INITIAL : RAN_PEER_EV_MSG_UP_CO;
588 else
589 event = RAN_PEER_EV_MSG_UP_CL;
590
591 return osmo_fsm_inst_dispatch(ran_peer->fi, event, &ctx);
592}
593
594void ran_peer_disconnect(struct sccp_ran_inst *sri, uint32_t conn_id)
595{
596 struct ran_conn *conn;
597 llist_for_each_entry(conn, &sri->ran_conns, entry) {
598 if (conn->sccp_conn_id == conn_id) {
599 ran_conn_discard(conn);
600 return;
601 }
602 }
603}
604
605struct ran_peer *ran_peer_find_by_cell_id(struct sccp_ran_inst *sri, const struct gsm0808_cell_id *cid,
606 bool expecting_single_match)
607{
608 struct ran_peer *rp;
609 struct ran_peer *found = NULL;
610
611 llist_for_each_entry(rp, &sri->ran_peers, entry) {
612 if (cell_id_list_find(&rp->cells_seen, cid, 0, false)) {
613 if (!expecting_single_match)
614 return rp;
615 /* Otherwise continue iterating and log errors for multiple matches... */
616 if (found) {
617 LOG_RAN_PEER(found, LOGL_ERROR, "Cell appears in more than one RAN peer:"
618 " %s also appears in %s\n",
619 gsm0808_cell_id_name(cid), rp->fi->id);
620 } else
621 found = rp;
622 }
623 }
624 return found;
625}
626
627struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *addr)
628{
629 struct ran_peer *rp;
630
631 llist_for_each_entry(rp, &sri->ran_peers, entry) {
632 if (!osmo_sccp_addr_ri_cmp(addr, &rp->peer_addr))
633 return rp;
634 }
635 return NULL;
636}
637
638int ran_peers_down_paging(struct sccp_ran_inst *sri, enum CELL_IDENT page_where, struct vlr_subscr *vsub,
639 enum paging_cause cause)
640{
641 struct ran_peer *rp;
642 int ret = 0;
643 struct gsm0808_cell_id page_id;
644 gsm0808_cell_id_from_cgi(&page_id, page_where, &vsub->cgi);
645
646 switch (page_where) {
647 case CELL_IDENT_NO_CELL:
Martin Hauke3f07dac2019-11-14 17:49:08 +0100648 LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Asked to page on NO_CELL, which doesn't make sense.\n");
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100649 return 0;
650
651 case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
652 case CELL_IDENT_UTRAN_RNC:
653 case CELL_IDENT_UTRAN_LAC_RNC:
654 LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Don't know how to page on %s\n",
655 gsm0808_cell_id_name(&page_id));
656 return 0;
657
658 default:
659 break;
660 };
661
662 llist_for_each_entry(rp, &sri->ran_peers, entry) {
663 ret += ran_peer_down_paging(rp, &page_id, vsub, cause);
664 }
665
666 if (!ret)
667 LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Paging failed, no RAN peers found for %s\n",
668 gsm0808_cell_id_name(&page_id));
669 return ret;
670}
671
672/* If the given vsub->cgi matches this ran_peer with respect to page_where, page and return 1.
673 * Otherwise return 0. (Return value: number of pagings sent) */
674int ran_peer_down_paging(struct ran_peer *rp, const struct gsm0808_cell_id *page_id, struct vlr_subscr *vsub,
675 enum paging_cause cause)
676{
677 struct msgb *l2;
678
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100679 /* There are also the RAN peers that are configured in the neighbor ident for Handover, but if those aren't
680 * connected, then we can't Page there. */
Vadim Yanitskiyd24c46a2019-05-14 21:49:47 +0700681 if (!cell_id_list_find(&rp->cells_seen, page_id, 0, false))
682 return 0;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100683
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100684 LOG_RAN_PEER_CAT(rp, DPAG, LOGL_DEBUG, "Paging for %s on %s\n", vlr_subscr_name(vsub),
685 gsm0808_cell_id_name(page_id));
686 l2 = rp->sri->ran->sccp_ran_ops.make_paging_msg(rp->sri, page_id, vsub->imsi, vsub->tmsi, cause);
687 if (osmo_fsm_inst_dispatch(rp->fi, RAN_PEER_EV_MSG_DOWN_CL, l2)) {
688 /* Not allowed to send messages, the peer is not properly connected yet/anymore */
689 LOG_RAN_PEER_CAT(rp, DPAG, LOGL_ERROR,
690 "Paging for %s matched this RAN peer, but emitting a Paging failed\n",
691 gsm0808_cell_id_name(page_id));
Vadim Yanitskiyede95d12019-05-14 21:41:06 +0700692 msgb_free(l2);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100693 return 0;
694 }
Vadim Yanitskiyede95d12019-05-14 21:41:06 +0700695
696 /* The RAN_PEER_EV_MSG_DOWN_CL handler calls sccp_ran_down_l2_cl(),
697 * which doesn't free msgb. We have to do this ourselves. */
698 msgb_free(l2);
699
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100700 return 1;
701}