blob: 35f28420a929e786d5abe8cab3d13679266a2b3d [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
125/* Drop all SCCP connections for this ran_peer, respond with RESET ACKNOWLEDGE and move to READY state. */
126static void ran_peer_rx_reset(struct ran_peer *rp)
127{
128 struct msgb *reset_ack;
129
130 ran_peer_discard_all_conns(rp);
131
132 reset_ack = rp->sri->ran->sccp_ran_ops.make_reset_msg(rp->sri, SCCP_RAN_MSG_RESET_ACK);
133
134 if (!reset_ack) {
135 LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to compose RESET ACKNOWLEDGE message\n");
136 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
137 return;
138 }
139
140 if (sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, reset_ack)) {
141 LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to send RESET ACKNOWLEDGE message\n");
142 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
Vadim Yanitskiy53d3e0e2019-05-10 02:44:57 +0700143 msgb_free(reset_ack);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100144 return;
145 }
146
147 LOG_RAN_PEER(rp, LOGL_INFO, "Sent RESET ACKNOWLEDGE\n");
148
Vadim Yanitskiy53d3e0e2019-05-10 02:44:57 +0700149 /* sccp_ran_down_l2_cl() doesn't free msgb */
150 msgb_free(reset_ack);
151
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100152 ran_peer_state_chg(rp, RAN_PEER_ST_READY);
153}
154
Pau Espin Pedrolf15852b2019-05-13 19:54:02 +0200155static void ran_peer_rx_reset_ack(struct ran_peer *rp)
156{
157 ran_peer_state_chg(rp, RAN_PEER_ST_READY);
158}
159
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100160void ran_peer_reset(struct ran_peer *rp)
161{
162 struct msgb *reset;
163
164 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET_ACK);
165 ran_peer_discard_all_conns(rp);
166
167 reset = rp->sri->ran->sccp_ran_ops.make_reset_msg(rp->sri, SCCP_RAN_MSG_RESET);
168
169 if (!reset) {
170 LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to compose RESET message\n");
171 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
172 return;
173 }
174
175 if (sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, reset)) {
176 LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to send RESET message\n");
177 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
178 return;
179 }
180}
181
182void ran_peer_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
183{
184 struct ran_peer *rp = fi->priv;
185 struct ran_peer_ev_ctx *ctx = data;
186 struct msgb *msg = ctx->msg;
187
188 switch (event) {
189 case RAN_PEER_EV_MSG_UP_CL:
190 switch (rp->sri->ran->sccp_ran_ops.is_reset_msg(rp->sri, msg)) {
191 case 1:
192 osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET, msg);
193 return;
194 case 2:
195 osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET_ACK, msg);
196 return;
197 default:
198 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled ConnectionLess message received: %s\n",
199 rp->sri->ran->sccp_ran_ops.msg_name(rp->sri, msg));
200 return;
201 }
202
203 default:
204 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
205 return;
206 }
207}
208
209void clear_and_disconnect(struct ran_peer *rp, uint32_t conn_id)
210{
211 struct msgb *clear;
212 struct ran_msg ran_enc_msg = {
213 .msg_type = RAN_MSG_CLEAR_COMMAND,
214 .clear_command = {
215 .gsm0808_cause = GSM0808_CAUSE_EQUIPMENT_FAILURE,
216 },
217 };
218
219 clear = rp->sri->ran->ran_encode(rp->fi, &ran_enc_msg);
220 if (!clear
221 || sccp_ran_down_l2_co(rp->sri, conn_id, clear))
222 LOG_RAN_PEER(rp, LOGL_ERROR, "Cannot sent Clear command\n");
223
224 sccp_ran_disconnect(rp->sri, conn_id, 0);
225}
226
227void ran_peer_st_wait_rx_reset(struct osmo_fsm_inst *fi, uint32_t event, void *data)
228{
229 struct ran_peer *rp = fi->priv;
230 struct ran_peer_ev_ctx *ctx;
231
232 switch (event) {
233
234 case RAN_PEER_EV_MSG_UP_CO:
235 case RAN_PEER_EV_MSG_UP_CO_INITIAL:
236 ctx = data;
237 OSMO_ASSERT(ctx);
238
239 if (rp->sri->ignore_missing_reset) {
240 LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
241 " Accepting RAN peer implicitly (legacy compat)\n");
242 ran_peer_state_chg(rp, RAN_PEER_ST_READY);
243 osmo_fsm_inst_dispatch(rp->fi, event, data);
244 return;
245 }
246
247 LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
248 " Disconnecting on incoming message, sending RESET to RAN peer.\n");
249 /* No valid RESET procedure has happened here yet. Usually, we're expecting the RAN peer (BSC,
250 * RNC) to first send a RESET message before sending Connection Oriented messages. So if we're
251 * getting a CO message, likely we've just restarted or something. Send a RESET to the peer. */
252
253 /* Make sure the MS / UE properly disconnects. */
254 clear_and_disconnect(rp, ctx->conn_id);
255
256 ran_peer_reset(rp);
257 return;
258
259 case RAN_PEER_EV_RX_RESET:
260 ran_peer_rx_reset(rp);
261 return;
262
263 default:
264 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
265 return;
266 }
267}
268
269void ran_peer_st_wait_rx_reset_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
270{
271 struct ran_peer *rp = fi->priv;
272 struct ran_peer_ev_ctx *ctx;
273
274 switch (event) {
275
276 case RAN_PEER_EV_RX_RESET_ACK:
Pau Espin Pedrolf15852b2019-05-13 19:54:02 +0200277 ran_peer_rx_reset_ack(rp);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100278 return;
279
280 case RAN_PEER_EV_MSG_UP_CO:
281 case RAN_PEER_EV_MSG_UP_CO_INITIAL:
282 ctx = data;
283 OSMO_ASSERT(ctx);
284 LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
285 " Disconnecting on incoming message, sending RESET to RAN peer.\n");
286 sccp_ran_disconnect(rp->sri, ctx->conn_id, 0);
287 /* No valid RESET procedure has happened here yet. */
288 ran_peer_reset(rp);
289 return;
290
291 case RAN_PEER_EV_RX_RESET:
292 ran_peer_rx_reset(rp);
293 return;
294
295 default:
296 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
297 return;
298 }
299}
300
301static struct ran_conn *new_incoming_conn(struct ran_peer *rp, uint32_t conn_id)
302{
303 struct gsm_network *net = rp->sri->user_data;
304 struct msub *msub;
305 struct msc_i *msc_i;
306 struct msc_a *msc_a;
307 struct ran_conn *ran_conn;
308
309 msub = msub_alloc(net);
310 OSMO_ASSERT(msub);
311 msc_i = msc_i_alloc(msub, rp->sri->ran);
312 OSMO_ASSERT(msc_i);
313
314 ran_conn = ran_conn_create_incoming(rp, conn_id);
315 if (!ran_conn) {
316 LOG_RAN_PEER(rp, LOGL_ERROR, "Cannot allocate ran_conn\n");
317 return NULL;
318 }
319 msc_i_set_ran_conn(msc_i, ran_conn);
320
321 msc_a = msc_a_alloc(msub, rp->sri->ran);
322 OSMO_ASSERT(msc_a);
323
324 return msc_i->ran_conn;
325}
326
327void ran_peer_st_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
328{
329 struct ran_peer *rp = fi->priv;
330 struct ran_peer_ev_ctx *ctx;
331 struct ran_conn *conn;
332 struct an_apdu an_apdu;
333
334 switch (event) {
335
336 case RAN_PEER_EV_MSG_UP_CO_INITIAL:
337 ctx = data;
338 OSMO_ASSERT(ctx)
339 OSMO_ASSERT(!ctx->conn);
340 OSMO_ASSERT(ctx->msg);
341
342 conn = new_incoming_conn(rp, ctx->conn_id);
343 if (!conn)
344 return;
345 if (!conn->msc_role) {
346 LOG_RAN_PEER(rp, LOGL_ERROR,
347 "Rx CO Initial message on conn that is not associated with any MSC role\n");
348 return;
349 }
350
351
352 an_apdu = (struct an_apdu){
353 .an_proto = rp->sri->ran->an_proto,
354 .msg = ctx->msg,
355 };
356
357 osmo_fsm_inst_dispatch(conn->msc_role, MSC_EV_FROM_RAN_COMPLETE_LAYER_3, &an_apdu);
358 return;
359
360 case RAN_PEER_EV_MSG_UP_CO:
361 ctx = data;
362 OSMO_ASSERT(ctx);
363 OSMO_ASSERT(ctx->conn);
364 OSMO_ASSERT(ctx->msg);
365
366 if (!ctx->conn->msc_role) {
367 LOG_RAN_PEER(rp, LOGL_ERROR,
368 "Rx CO message on conn that is not associated with any MSC role\n");
369 return;
370 }
371
372 an_apdu = (struct an_apdu){
373 .an_proto = rp->sri->ran->an_proto,
374 .msg = ctx->msg,
375 };
376
377 osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu);
378 return;
379
380 case RAN_PEER_EV_MSG_DOWN_CO_INITIAL:
381 ctx = data;
382 OSMO_ASSERT(ctx);
383 OSMO_ASSERT(ctx->msg);
384 sccp_ran_down_l2_co_initial(rp->sri, &rp->peer_addr, ctx->conn_id, ctx->msg);
385 return;
386
387 case RAN_PEER_EV_MSG_DOWN_CO:
388 ctx = data;
389 OSMO_ASSERT(ctx);
390 OSMO_ASSERT(ctx->msg);
391 sccp_ran_down_l2_co(rp->sri, ctx->conn_id, ctx->msg);
392 return;
393
394 case RAN_PEER_EV_MSG_DOWN_CL:
395 OSMO_ASSERT(data);
396 sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, (struct msgb*)data);
397 return;
398
399 case RAN_PEER_EV_RX_RESET:
400 ran_peer_rx_reset(rp);
401 return;
402
403 default:
404 LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
405 return;
406 }
407}
408
409static int ran_peer_fsm_timer_cb(struct osmo_fsm_inst *fi)
410{
411 struct ran_peer *rp = fi->priv;
412 ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
413 return 0;
414}
415
416void ran_peer_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
417{
418 struct ran_peer *rp = fi->priv;
419 ran_peer_discard_all_conns(rp);
420 llist_del(&rp->entry);
421}
422
423static const struct value_string ran_peer_fsm_event_names[] = {
424 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CL),
425 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CO_INITIAL),
426 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CO),
427 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CL),
428 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CO_INITIAL),
429 OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CO),
430 OSMO_VALUE_STRING(RAN_PEER_EV_RX_RESET),
431 OSMO_VALUE_STRING(RAN_PEER_EV_RX_RESET_ACK),
432 OSMO_VALUE_STRING(RAN_PEER_EV_CONNECTION_SUCCESS),
433 OSMO_VALUE_STRING(RAN_PEER_EV_CONNECTION_TIMEOUT),
434 {}
435};
436
437#define S(x) (1 << (x))
438
439static const struct osmo_fsm_state ran_peer_fsm_states[] = {
440 [RAN_PEER_ST_WAIT_RX_RESET] = {
441 .name = "WAIT_RX_RESET",
442 .action = ran_peer_st_wait_rx_reset,
443 .in_event_mask = 0
444 | S(RAN_PEER_EV_RX_RESET)
445 | S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
446 | S(RAN_PEER_EV_MSG_UP_CO)
447 | S(RAN_PEER_EV_CONNECTION_TIMEOUT)
448 ,
449 .out_state_mask = 0
450 | S(RAN_PEER_ST_WAIT_RX_RESET)
451 | S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
452 | S(RAN_PEER_ST_READY)
453 | S(RAN_PEER_ST_DISCARDING)
454 ,
455 },
456 [RAN_PEER_ST_WAIT_RX_RESET_ACK] = {
457 .name = "WAIT_RX_RESET_ACK",
458 .action = ran_peer_st_wait_rx_reset_ack,
459 .in_event_mask = 0
460 | S(RAN_PEER_EV_RX_RESET)
461 | S(RAN_PEER_EV_RX_RESET_ACK)
462 | S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
463 | S(RAN_PEER_EV_MSG_UP_CO)
464 | S(RAN_PEER_EV_CONNECTION_TIMEOUT)
465 ,
466 .out_state_mask = 0
467 | S(RAN_PEER_ST_WAIT_RX_RESET)
468 | S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
469 | S(RAN_PEER_ST_READY)
470 | S(RAN_PEER_ST_DISCARDING)
471 ,
472 },
473 [RAN_PEER_ST_READY] = {
474 .name = "READY",
475 .action = ran_peer_st_ready,
476 .in_event_mask = 0
477 | S(RAN_PEER_EV_RX_RESET)
478 | S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
479 | S(RAN_PEER_EV_MSG_UP_CO)
480 | S(RAN_PEER_EV_MSG_DOWN_CO_INITIAL)
481 | S(RAN_PEER_EV_MSG_DOWN_CO)
482 | S(RAN_PEER_EV_MSG_DOWN_CL)
483 ,
484 .out_state_mask = 0
485 | S(RAN_PEER_ST_WAIT_RX_RESET)
486 | S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
487 | S(RAN_PEER_ST_READY)
488 | S(RAN_PEER_ST_DISCARDING)
489 ,
490 },
491 [RAN_PEER_ST_DISCARDING] = {
492 .name = "DISCARDING",
493 },
494};
495
496static struct osmo_fsm ran_peer_fsm = {
497 .name = "ran_peer",
498 .states = ran_peer_fsm_states,
499 .num_states = ARRAY_SIZE(ran_peer_fsm_states),
500 .log_subsys = DRR,
501 .event_names = ran_peer_fsm_event_names,
502 .timer_cb = ran_peer_fsm_timer_cb,
503 .cleanup = ran_peer_fsm_cleanup,
504 .allstate_action = ran_peer_allstate_action,
505 .allstate_event_mask = 0
506 | S(RAN_PEER_EV_MSG_UP_CL)
507 ,
508};
509
510int ran_peer_up_l2(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *calling_addr, bool co, uint32_t conn_id,
511 struct msgb *l2)
512{
513 struct ran_peer *ran_peer = NULL;
514 uint32_t event;
515 struct ran_peer_ev_ctx ctx = {
516 .conn_id = conn_id,
517 .msg = l2,
518 };
519
520 if (co) {
521 struct ran_conn *conn;
522 llist_for_each_entry(conn, &sri->ran_conns, entry) {
523 if (conn->sccp_conn_id == conn_id) {
524 ran_peer = conn->ran_peer;
525 ctx.conn = conn;
526 break;
527 }
528 }
529
530 if (ran_peer && calling_addr) {
531 LOG_SCCP_RAN_CO(sri, calling_addr, conn_id, LOGL_ERROR,
532 "Connection-Oriented Initial message for already existing conn_id."
533 " Dropping message.\n");
534 return -EINVAL;
535 }
536
537 if (!ran_peer && !calling_addr) {
538 LOG_SCCP_RAN_CO(sri, calling_addr, conn_id, LOGL_ERROR,
539 "Connection-Oriented non-Initial message for unknown conn_id %u."
540 " Dropping message.\n", conn_id);
541 return -EINVAL;
542 }
543 }
544
545 if (calling_addr) {
546 ran_peer = ran_peer_find_or_create(sri, calling_addr);
547 if (!ran_peer) {
548 LOG_SCCP_RAN_CL(sri, calling_addr, LOGL_ERROR, "Cannot register RAN peer\n");
549 return -EIO;
550 }
551 }
552
553 OSMO_ASSERT(ran_peer && ran_peer->fi);
554
555 if (co)
556 event = calling_addr ? RAN_PEER_EV_MSG_UP_CO_INITIAL : RAN_PEER_EV_MSG_UP_CO;
557 else
558 event = RAN_PEER_EV_MSG_UP_CL;
559
560 return osmo_fsm_inst_dispatch(ran_peer->fi, event, &ctx);
561}
562
563void ran_peer_disconnect(struct sccp_ran_inst *sri, uint32_t conn_id)
564{
565 struct ran_conn *conn;
566 llist_for_each_entry(conn, &sri->ran_conns, entry) {
567 if (conn->sccp_conn_id == conn_id) {
568 ran_conn_discard(conn);
569 return;
570 }
571 }
572}
573
574struct ran_peer *ran_peer_find_by_cell_id(struct sccp_ran_inst *sri, const struct gsm0808_cell_id *cid,
575 bool expecting_single_match)
576{
577 struct ran_peer *rp;
578 struct ran_peer *found = NULL;
579
580 llist_for_each_entry(rp, &sri->ran_peers, entry) {
581 if (cell_id_list_find(&rp->cells_seen, cid, 0, false)) {
582 if (!expecting_single_match)
583 return rp;
584 /* Otherwise continue iterating and log errors for multiple matches... */
585 if (found) {
586 LOG_RAN_PEER(found, LOGL_ERROR, "Cell appears in more than one RAN peer:"
587 " %s also appears in %s\n",
588 gsm0808_cell_id_name(cid), rp->fi->id);
589 } else
590 found = rp;
591 }
592 }
593 return found;
594}
595
596struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *addr)
597{
598 struct ran_peer *rp;
599
600 llist_for_each_entry(rp, &sri->ran_peers, entry) {
601 if (!osmo_sccp_addr_ri_cmp(addr, &rp->peer_addr))
602 return rp;
603 }
604 return NULL;
605}
606
607int ran_peers_down_paging(struct sccp_ran_inst *sri, enum CELL_IDENT page_where, struct vlr_subscr *vsub,
608 enum paging_cause cause)
609{
610 struct ran_peer *rp;
611 int ret = 0;
612 struct gsm0808_cell_id page_id;
613 gsm0808_cell_id_from_cgi(&page_id, page_where, &vsub->cgi);
614
615 switch (page_where) {
616 case CELL_IDENT_NO_CELL:
617 LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Asked to page on NO_CELL, wich doesn't make sense.\n");
618 return 0;
619
620 case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
621 case CELL_IDENT_UTRAN_RNC:
622 case CELL_IDENT_UTRAN_LAC_RNC:
623 LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Don't know how to page on %s\n",
624 gsm0808_cell_id_name(&page_id));
625 return 0;
626
627 default:
628 break;
629 };
630
631 llist_for_each_entry(rp, &sri->ran_peers, entry) {
632 ret += ran_peer_down_paging(rp, &page_id, vsub, cause);
633 }
634
635 if (!ret)
636 LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Paging failed, no RAN peers found for %s\n",
637 gsm0808_cell_id_name(&page_id));
638 return ret;
639}
640
641/* If the given vsub->cgi matches this ran_peer with respect to page_where, page and return 1.
642 * Otherwise return 0. (Return value: number of pagings sent) */
643int ran_peer_down_paging(struct ran_peer *rp, const struct gsm0808_cell_id *page_id, struct vlr_subscr *vsub,
644 enum paging_cause cause)
645{
646 struct msgb *l2;
647
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100648 /* There are also the RAN peers that are configured in the neighbor ident for Handover, but if those aren't
649 * connected, then we can't Page there. */
Vadim Yanitskiyd24c46a2019-05-14 21:49:47 +0700650 if (!cell_id_list_find(&rp->cells_seen, page_id, 0, false))
651 return 0;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100652
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100653 LOG_RAN_PEER_CAT(rp, DPAG, LOGL_DEBUG, "Paging for %s on %s\n", vlr_subscr_name(vsub),
654 gsm0808_cell_id_name(page_id));
655 l2 = rp->sri->ran->sccp_ran_ops.make_paging_msg(rp->sri, page_id, vsub->imsi, vsub->tmsi, cause);
656 if (osmo_fsm_inst_dispatch(rp->fi, RAN_PEER_EV_MSG_DOWN_CL, l2)) {
657 /* Not allowed to send messages, the peer is not properly connected yet/anymore */
658 LOG_RAN_PEER_CAT(rp, DPAG, LOGL_ERROR,
659 "Paging for %s matched this RAN peer, but emitting a Paging failed\n",
660 gsm0808_cell_id_name(page_id));
Vadim Yanitskiyede95d12019-05-14 21:41:06 +0700661 msgb_free(l2);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100662 return 0;
663 }
Vadim Yanitskiyede95d12019-05-14 21:41:06 +0700664
665 /* The RAN_PEER_EV_MSG_DOWN_CL handler calls sccp_ran_down_l2_cl(),
666 * which doesn't free msgb. We have to do this ourselves. */
667 msgb_free(l2);
668
Neels Hofmeyrc4628a32018-12-07 14:47:34 +0100669 return 1;
670}