blob: c936d5c5daa559f89d8a5894f43b430336454cbb [file] [log] [blame]
Neels Hofmeyrc4628a32018-12-07 14:47:34 +01001#pragma once
2
3#include <osmocom/core/linuxlist.h>
4#include <osmocom/gsm/gsm0808.h>
5#include <osmocom/sigtran/sccp_sap.h>
6
7#include <osmocom/msc/debug.h>
8#include <osmocom/msc/paging.h>
9
10struct vlr_subscr;
11struct ran_conn;
12struct neighbor_ident_entry;
13
14#define LOG_RAN_PEER_CAT(RAN_PEER, subsys, loglevel, fmt, args ...) \
15 LOGPFSMSL((RAN_PEER)? (RAN_PEER)->fi : NULL, subsys, loglevel, fmt, ## args)
16
17#define LOG_RAN_PEER(RAN_PEER, loglevel, fmt, args ...) \
18 LOG_RAN_PEER_CAT(RAN_PEER, \
19 (RAN_PEER) && (RAN_PEER)->sri? (RAN_PEER)->sri->ran->log_subsys : DMSC, \
20 loglevel, fmt, ## args)
21
22/* A BSC or RNC with activity on a local SCCP connection.
23 * Here we collect those BSC and RNC peers that are actually connected to the MSC and manage their connection Reset
24 * status.
25 *
26 * Before we had explicit neighbor configuration for inter-BSC and inter-MSC handover, the only way to know which peer
27 * address corresponds to which LAC (for paging a specific LAC) was to collect the LAC from L3 messages coming in on a
28 * subscriber connection. We still continue that practice to support unconfigured operation.
29 *
30 * The neighbor list config extends this by possibly naming LAC and CI that have not seen explicit activity yet, and
31 * allows us to page towards the correct peer's SCCP address from the start.
32 *
33 * So, for paging, the idea is to look for a LAC that is recorded here, and if not found, query the neighbor
34 * configuration for a peer's SCCP address matching that LAC. If found, look for active connections on that SCCP address
35 * here.
36 *
37 * Any valid RAN peer will contact us and initiate a RESET procedure. In turn, on osmo-msc start, we may choose to
38 * initiate a RESET procedure towards every known RAN peer.
39 *
40 * Semantically, it would make sense to keep the list of ran_conn instances in each struct ran_peer, but since
41 * non-Initial Connection-Oriented messages indicate only the conn by id (and identify the ran_peer from that), the conn
42 * list is kept in sccp_ran_inst. For convenience, see ran_peer_for_each_ran_conn().
43 */
44struct ran_peer {
Neels Hofmeyr754def92020-09-23 01:33:56 +020045 /* Entry in sccp_ran_inst->ran_peers */
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010046 struct llist_head entry;
47
48 struct sccp_ran_inst *sri;
49 struct osmo_sccp_addr peer_addr;
50 struct osmo_fsm_inst *fi;
51
52 /* See cell_id_list.h */
53 struct llist_head cells_seen;
Pau Espin Pedrolf9f38b52019-05-07 11:48:16 +020054
55 /* Whether we detected the BSC supports Osmux (during BSSMAP_RESET) */
56 bool remote_supports_osmux;
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010057};
58
59#define ran_peer_for_each_ran_conn(RAN_CONN, RAN_PEER) \
60 llist_for_each_entry(RAN_CONN, &(RAN_PEER)->sri->ran_conns, entry) \
61 if ((RAN_CONN)->ran_peer == (RAN_PEER))
62
63#define ran_peer_for_each_ran_conn_safe(RAN_CONN, RAN_CONN_NEXT, RAN_PEER) \
64 llist_for_each_entry_safe(RAN_CONN, RAN_CONN_NEXT, &(RAN_PEER)->sri->ran_conns, entry) \
65 if ((RAN_CONN)->ran_peer == (RAN_PEER))
66
67enum ran_peer_state {
68 RAN_PEER_ST_WAIT_RX_RESET = 0,
69 RAN_PEER_ST_WAIT_RX_RESET_ACK,
70 RAN_PEER_ST_READY,
71 RAN_PEER_ST_DISCARDING,
72};
73
74enum ran_peer_event {
75 RAN_PEER_EV_MSG_UP_CL = 0,
76 RAN_PEER_EV_MSG_UP_CO_INITIAL,
77 RAN_PEER_EV_MSG_UP_CO,
78 RAN_PEER_EV_MSG_DOWN_CL,
79 RAN_PEER_EV_MSG_DOWN_CO_INITIAL,
80 RAN_PEER_EV_MSG_DOWN_CO,
81 RAN_PEER_EV_RX_RESET,
82 RAN_PEER_EV_RX_RESET_ACK,
83 RAN_PEER_EV_CONNECTION_SUCCESS,
84 RAN_PEER_EV_CONNECTION_TIMEOUT,
85};
86
87struct ran_peer_ev_ctx {
88 uint32_t conn_id;
89 struct ran_conn *conn;
90 struct msgb *msg;
91};
92
93struct ran_peer *ran_peer_find_or_create(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr);
Neels Hofmeyrcbcfe992020-09-23 01:32:11 +020094struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr);
Neels Hofmeyrc4628a32018-12-07 14:47:34 +010095
96void ran_peer_cells_seen_add(struct ran_peer *ran_peer, const struct gsm0808_cell_id *id);
97
98int ran_peer_up_l2(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *calling_addr, bool co, uint32_t conn_id,
99 struct msgb *l2);
100void ran_peer_disconnect(struct sccp_ran_inst *sri, uint32_t conn_id);
101
102int ran_peers_down_paging(struct sccp_ran_inst *sri, enum CELL_IDENT page_where, struct vlr_subscr *vsub,
103 enum paging_cause cause);
104int ran_peer_down_paging(struct ran_peer *rp, const struct gsm0808_cell_id *page_id, struct vlr_subscr *vsub,
105 enum paging_cause cause);
106
107struct ran_peer *ran_peer_find_by_cell_id(struct sccp_ran_inst *sri, const struct gsm0808_cell_id *cid,
108 bool expecting_single_match);