/*
 * (C) 2019 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
 * All Rights Reserved
 *
 * SPDX-License-Identifier: AGPL-3.0+
 *
 * Author: Neels Hofmeyr
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#include <osmocom/core/linuxlist.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/fsm.h>
#include <osmocom/sigtran/sccp_helpers.h>

#include <osmocom/msc/ran_peer.h>
#include <osmocom/msc/sccp_ran.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/msc_i.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/ran_conn.h>
#include <osmocom/msc/cell_id_list.h>

static struct osmo_fsm ran_peer_fsm;

static __attribute__((constructor)) void ran_peer_init()
{
	OSMO_ASSERT( osmo_fsm_register(&ran_peer_fsm) == 0);
}

/* Allocate a RAN peer with FSM instance. To deallocate, call osmo_fsm_inst_term(ran_peer->fi). */
static struct ran_peer *ran_peer_alloc(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
{
	struct ran_peer *rp;
	struct osmo_fsm_inst *fi;
	char *sccp_addr;
	char *pos;

	fi = osmo_fsm_inst_alloc(&ran_peer_fsm, sri, NULL, LOGL_DEBUG, NULL);
	OSMO_ASSERT(fi);

	/* Unfortunately, osmo_sccp_inst_addr_name() returns "RI=SSN_PC,PC=0.24.1,SSN=BSSAP" but neither commas nor
	 * full-stops are allowed as FSM inst id. Make it "RI=SSN_PC:PC-0-24-1:SSN-BSSAP". */
	sccp_addr = osmo_sccp_inst_addr_name(sri->sccp, peer_addr);
	for (pos = sccp_addr; *pos; pos++) {
		if (*pos == ',')
			*pos = ':';
		else if (*pos == '.' || *pos == '=')
			*pos = '-';
	}
	osmo_fsm_inst_update_id_f(fi, "%s:%s", osmo_rat_type_name(sri->ran->type), sccp_addr);

	rp = talloc_zero(fi, struct ran_peer);
	OSMO_ASSERT(rp);
	*rp = (struct ran_peer){
		.sri = sri,
		.peer_addr = *peer_addr,
		.fi = fi,
	};
	INIT_LLIST_HEAD(&rp->cells_seen);
	fi->priv = rp;

	llist_add(&rp->entry, &sri->ran_peers);

	return rp;
}

struct ran_peer *ran_peer_find_or_create(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
{
	struct ran_peer *rp = ran_peer_find(sri, peer_addr);
	if (rp)
		return rp;
	return ran_peer_alloc(sri, peer_addr);
}

struct ran_peer *ran_peer_find(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *peer_addr)
{
	struct ran_peer *rp;
	llist_for_each_entry(rp, &sri->ran_peers, entry) {
		if (osmo_sccp_addr_ri_cmp(peer_addr, &rp->peer_addr))
			continue;
		return rp;
	}
	return NULL;
}

void ran_peer_cells_seen_add(struct ran_peer *ran_peer, const struct gsm0808_cell_id *cid)
{
	if (!cell_id_list_add_cell(ran_peer, &ran_peer->cells_seen, cid))
		return;
	LOG_RAN_PEER_CAT(ran_peer, DPAG, LOGL_NOTICE, "Added seen cell to this RAN peer: %s\n",
			 gsm0808_cell_id_name(cid));
}

static const struct osmo_tdef_state_timeout ran_peer_fsm_timeouts[32] = {
	[RAN_PEER_ST_WAIT_RX_RESET_ACK] = { .T = -1 },
	[RAN_PEER_ST_DISCARDING] = { .T = -2 },
};

#define ran_peer_state_chg(RAN_PEER, NEXT_STATE) \
	osmo_tdef_fsm_inst_state_chg((RAN_PEER)->fi, NEXT_STATE, ran_peer_fsm_timeouts, g_sccp_tdefs, 5)

void ran_peer_discard_all_conns(struct ran_peer *rp)
{
	struct ran_conn *conn, *next;

	ran_peer_for_each_ran_conn_safe(conn, next, rp) {
		ran_conn_discard(conn);
	}
}

/* TODO: create an sccp_ran_ops.rx_reset(_ack) to handle this differently on 2g and 3G */
/* We expect RAN peer to provide use with an Osmocom extension TLV in BSSMAP_RESET to
 * announce Osmux support */
static void ran_peer_update_osmux_support(struct ran_peer *rp, struct msgb *msg)
{
	struct tlv_parsed tp;
	int rc;
	bool old_value = rp->remote_supports_osmux;

	OSMO_ASSERT(msg);
	msg->l3h = msg->l2h + sizeof(struct bssmap_header);
	rc = tlv_parse(&tp, gsm0808_att_tlvdef(), msg->l3h + 1, msgb_l3len(msg) - 1, 0, 0);
	if (rc < 0)
		LOG_RAN_PEER(rp, LOGL_NOTICE, "Failed parsing TLV looking for Osmux support\n");

	if (TLVP_PRESENT(&tp, GSM0808_IE_OSMO_OSMUX_SUPPORT)) {
		rp->remote_supports_osmux = true;
	} else {
		rp->remote_supports_osmux = false;
	}

	if (old_value != rp->remote_supports_osmux)
		LOG_RAN_PEER(rp, LOGL_INFO, "BSC detected AoIP Osmux support changed: %d->%d\n",
		     old_value, rp->remote_supports_osmux);
}

/* Drop all SCCP connections for this ran_peer, respond with RESET ACKNOWLEDGE and move to READY state. */
static void ran_peer_rx_reset(struct ran_peer *rp, struct msgb* msg)
{
	struct msgb *reset_ack;

	ran_peer_discard_all_conns(rp);

	ran_peer_update_osmux_support(rp, msg);

	reset_ack = rp->sri->ran->sccp_ran_ops.make_reset_msg(rp->sri, SCCP_RAN_MSG_RESET_ACK);

	if (!reset_ack) {
		LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to compose RESET ACKNOWLEDGE message\n");
		ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
		return;
	}

	if (sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, reset_ack)) {
		LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to send RESET ACKNOWLEDGE message\n");
		ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
		msgb_free(reset_ack);
		return;
	}

	LOG_RAN_PEER(rp, LOGL_INFO, "Sent RESET ACKNOWLEDGE\n");

	/* sccp_ran_down_l2_cl() doesn't free msgb */
	msgb_free(reset_ack);

	ran_peer_state_chg(rp, RAN_PEER_ST_READY);
}

static void ran_peer_rx_reset_ack(struct ran_peer *rp, struct msgb* msg)
{
	ran_peer_state_chg(rp, RAN_PEER_ST_READY);
	ran_peer_update_osmux_support(rp, msg);
}

void ran_peer_reset(struct ran_peer *rp)
{
	struct msgb *reset;

	ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET_ACK);
	ran_peer_discard_all_conns(rp);

	reset = rp->sri->ran->sccp_ran_ops.make_reset_msg(rp->sri, SCCP_RAN_MSG_RESET);

	if (!reset) {
		LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to compose RESET message\n");
		ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
		return;
	}

	if (sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, reset)) {
		LOG_RAN_PEER(rp, LOGL_ERROR, "Failed to send RESET message\n");
		ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
		return;
	}
}

void ran_peer_allstate_action(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct ran_peer *rp = fi->priv;
	struct ran_peer_ev_ctx *ctx = data;
	struct msgb *msg = ctx->msg;

	switch (event) {
	case RAN_PEER_EV_MSG_UP_CL:
		switch (rp->sri->ran->sccp_ran_ops.is_reset_msg(rp->sri, msg)) {
		case 1:
			osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET, msg);
			return;
		case 2:
			osmo_fsm_inst_dispatch(fi, RAN_PEER_EV_RX_RESET_ACK, msg);
			return;
		default:
			LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled ConnectionLess message received: %s\n",
				     rp->sri->ran->sccp_ran_ops.msg_name(rp->sri, msg));
			return;
		}

	default:
		LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
		return;
	}
}

void clear_and_disconnect(struct ran_peer *rp, uint32_t conn_id)
{
	struct msgb *clear;
	struct ran_msg ran_enc_msg = {
		.msg_type = RAN_MSG_CLEAR_COMMAND,
		.clear_command = {
			.gsm0808_cause = GSM0808_CAUSE_EQUIPMENT_FAILURE,
		},
	};

	clear = rp->sri->ran->ran_encode(rp->fi, &ran_enc_msg);
	if (!clear
	    || sccp_ran_down_l2_co(rp->sri, conn_id, clear))
		LOG_RAN_PEER(rp, LOGL_ERROR, "Cannot sent Clear command\n");

	sccp_ran_disconnect(rp->sri, conn_id, 0);
}

void ran_peer_st_wait_rx_reset(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct ran_peer *rp = fi->priv;
	struct ran_peer_ev_ctx *ctx;
	struct msgb *msg;

	switch (event) {

	case RAN_PEER_EV_MSG_UP_CO:
	case RAN_PEER_EV_MSG_UP_CO_INITIAL:
		ctx = data;
		OSMO_ASSERT(ctx);

		if (rp->sri->ignore_missing_reset) {
			LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
				     " Accepting RAN peer implicitly (legacy compat)\n");
			ran_peer_state_chg(rp, RAN_PEER_ST_READY);
			osmo_fsm_inst_dispatch(rp->fi, event, data);
			return;
		}

		LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
			     " Disconnecting on incoming message, sending RESET to RAN peer.\n");
		/* No valid RESET procedure has happened here yet. Usually, we're expecting the RAN peer (BSC,
		 * RNC) to first send a RESET message before sending Connection Oriented messages. So if we're
		 * getting a CO message, likely we've just restarted or something. Send a RESET to the peer. */

		/* Make sure the MS / UE properly disconnects. */
		clear_and_disconnect(rp, ctx->conn_id);

		ran_peer_reset(rp);
		return;

	case RAN_PEER_EV_RX_RESET:
		msg = (struct msgb*)data;
		ran_peer_rx_reset(rp, msg);
		return;

	default:
		LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
		return;
	}
}

void ran_peer_st_wait_rx_reset_ack(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct ran_peer *rp = fi->priv;
	struct ran_peer_ev_ctx *ctx;
	struct msgb *msg;

	switch (event) {

	case RAN_PEER_EV_RX_RESET_ACK:
		msg = (struct msgb*)data;
		ran_peer_rx_reset_ack(rp, msg);
		return;

	case RAN_PEER_EV_MSG_UP_CO:
	case RAN_PEER_EV_MSG_UP_CO_INITIAL:
		ctx = data;
		OSMO_ASSERT(ctx);
		LOG_RAN_PEER(rp, LOGL_ERROR, "Receiving CO message on RAN peer that has not done a proper RESET yet."
			     " Disconnecting on incoming message, sending RESET to RAN peer.\n");
		sccp_ran_disconnect(rp->sri, ctx->conn_id, 0);
		/* No valid RESET procedure has happened here yet. */
		ran_peer_reset(rp);
		return;

	case RAN_PEER_EV_RX_RESET:
		msg = (struct msgb*)data;
		ran_peer_rx_reset(rp, msg);
		return;

	default:
		LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
		return;
	}
}

static struct ran_conn *new_incoming_conn(struct ran_peer *rp, uint32_t conn_id)
{
	struct gsm_network *net = rp->sri->user_data;
	struct msub *msub;
	struct msc_i *msc_i;
	struct msc_a *msc_a;
	struct ran_conn *ran_conn;

	msub = msub_alloc(net);
	OSMO_ASSERT(msub);
	msc_i = msc_i_alloc(msub, rp->sri->ran);
	OSMO_ASSERT(msc_i);

	ran_conn = ran_conn_create_incoming(rp, conn_id);
	if (!ran_conn) {
		LOG_RAN_PEER(rp, LOGL_ERROR, "Cannot allocate ran_conn\n");
		return NULL;
	}
	msc_i_set_ran_conn(msc_i, ran_conn);

	msc_a = msc_a_alloc(msub, rp->sri->ran);
	OSMO_ASSERT(msc_a);

	return msc_i->ran_conn;
}

void ran_peer_st_ready(struct osmo_fsm_inst *fi, uint32_t event, void *data)
{
	struct ran_peer *rp = fi->priv;
	struct ran_peer_ev_ctx *ctx;
	struct ran_conn *conn;
	struct an_apdu an_apdu;
	struct msgb *msg;

	switch (event) {

	case RAN_PEER_EV_MSG_UP_CO_INITIAL:
		ctx = data;
		OSMO_ASSERT(ctx)
		OSMO_ASSERT(!ctx->conn);
		OSMO_ASSERT(ctx->msg);

		conn = new_incoming_conn(rp, ctx->conn_id);
		if (!conn)
			return;
		if (!conn->msc_role) {
			LOG_RAN_PEER(rp, LOGL_ERROR,
				     "Rx CO Initial message on conn that is not associated with any MSC role\n");
			return;
		}


		an_apdu = (struct an_apdu){
			.an_proto = rp->sri->ran->an_proto,
			.msg = ctx->msg,
		};

		osmo_fsm_inst_dispatch(conn->msc_role, MSC_EV_FROM_RAN_COMPLETE_LAYER_3, &an_apdu);
		return;

	case RAN_PEER_EV_MSG_UP_CO:
		ctx = data;
		OSMO_ASSERT(ctx);
		OSMO_ASSERT(ctx->conn);
		OSMO_ASSERT(ctx->msg);

		if (!ctx->conn->msc_role) {
			LOG_RAN_PEER(rp, LOGL_ERROR,
				     "Rx CO message on conn that is not associated with any MSC role\n");
			return;
		}

		an_apdu = (struct an_apdu){
			.an_proto = rp->sri->ran->an_proto,
			.msg = ctx->msg,
		};

		osmo_fsm_inst_dispatch(ctx->conn->msc_role, MSC_EV_FROM_RAN_UP_L2, &an_apdu);
		return;

	case RAN_PEER_EV_MSG_DOWN_CO_INITIAL:
		ctx = data;
		OSMO_ASSERT(ctx);
		OSMO_ASSERT(ctx->msg);
		sccp_ran_down_l2_co_initial(rp->sri, &rp->peer_addr, ctx->conn_id, ctx->msg);
		return;

	case RAN_PEER_EV_MSG_DOWN_CO:
		ctx = data;
		OSMO_ASSERT(ctx);
		OSMO_ASSERT(ctx->msg);
		sccp_ran_down_l2_co(rp->sri, ctx->conn_id, ctx->msg);
		return;

	case RAN_PEER_EV_MSG_DOWN_CL:
		OSMO_ASSERT(data);
		sccp_ran_down_l2_cl(rp->sri, &rp->peer_addr, (struct msgb*)data);
		return;

	case RAN_PEER_EV_RX_RESET:
		msg = (struct msgb*)data;
		ran_peer_rx_reset(rp, msg);
		return;

	default:
		LOG_RAN_PEER(rp, LOGL_ERROR, "Unhandled event: %s\n", osmo_fsm_event_name(&ran_peer_fsm, event));
		return;
	}
}

static int ran_peer_fsm_timer_cb(struct osmo_fsm_inst *fi)
{
	struct ran_peer *rp = fi->priv;
	ran_peer_state_chg(rp, RAN_PEER_ST_WAIT_RX_RESET);
	return 0;
}

void ran_peer_fsm_cleanup(struct osmo_fsm_inst *fi, enum osmo_fsm_term_cause cause)
{
	struct ran_peer *rp = fi->priv;
	ran_peer_discard_all_conns(rp);
	llist_del(&rp->entry);
}

static const struct value_string ran_peer_fsm_event_names[] = {
	OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CL),
	OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CO_INITIAL),
	OSMO_VALUE_STRING(RAN_PEER_EV_MSG_UP_CO),
	OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CL),
	OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CO_INITIAL),
	OSMO_VALUE_STRING(RAN_PEER_EV_MSG_DOWN_CO),
	OSMO_VALUE_STRING(RAN_PEER_EV_RX_RESET),
	OSMO_VALUE_STRING(RAN_PEER_EV_RX_RESET_ACK),
	OSMO_VALUE_STRING(RAN_PEER_EV_CONNECTION_SUCCESS),
	OSMO_VALUE_STRING(RAN_PEER_EV_CONNECTION_TIMEOUT),
	{}
};

#define S(x)	(1 << (x))

static const struct osmo_fsm_state ran_peer_fsm_states[] = {
	[RAN_PEER_ST_WAIT_RX_RESET] = {
		.name = "WAIT_RX_RESET",
		.action = ran_peer_st_wait_rx_reset,
		.in_event_mask = 0
			| S(RAN_PEER_EV_RX_RESET)
			| S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
			| S(RAN_PEER_EV_MSG_UP_CO)
			| S(RAN_PEER_EV_CONNECTION_TIMEOUT)
			,
		.out_state_mask = 0
			| S(RAN_PEER_ST_WAIT_RX_RESET)
			| S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
			| S(RAN_PEER_ST_READY)
			| S(RAN_PEER_ST_DISCARDING)
			,
	},
	[RAN_PEER_ST_WAIT_RX_RESET_ACK] = {
		.name = "WAIT_RX_RESET_ACK",
		.action = ran_peer_st_wait_rx_reset_ack,
		.in_event_mask = 0
			| S(RAN_PEER_EV_RX_RESET)
			| S(RAN_PEER_EV_RX_RESET_ACK)
			| S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
			| S(RAN_PEER_EV_MSG_UP_CO)
			| S(RAN_PEER_EV_CONNECTION_TIMEOUT)
			,
		.out_state_mask = 0
			| S(RAN_PEER_ST_WAIT_RX_RESET)
			| S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
			| S(RAN_PEER_ST_READY)
			| S(RAN_PEER_ST_DISCARDING)
			,
	},
	[RAN_PEER_ST_READY] = {
		.name = "READY",
		.action = ran_peer_st_ready,
		.in_event_mask = 0
			| S(RAN_PEER_EV_RX_RESET)
			| S(RAN_PEER_EV_MSG_UP_CO_INITIAL)
			| S(RAN_PEER_EV_MSG_UP_CO)
			| S(RAN_PEER_EV_MSG_DOWN_CO_INITIAL)
			| S(RAN_PEER_EV_MSG_DOWN_CO)
			| S(RAN_PEER_EV_MSG_DOWN_CL)
			,
		.out_state_mask = 0
			| S(RAN_PEER_ST_WAIT_RX_RESET)
			| S(RAN_PEER_ST_WAIT_RX_RESET_ACK)
			| S(RAN_PEER_ST_READY)
			| S(RAN_PEER_ST_DISCARDING)
			,
	},
	[RAN_PEER_ST_DISCARDING] = {
		.name = "DISCARDING",
	},
};

static struct osmo_fsm ran_peer_fsm = {
	.name = "ran_peer",
	.states = ran_peer_fsm_states,
	.num_states = ARRAY_SIZE(ran_peer_fsm_states),
	.log_subsys = DRR,
	.event_names = ran_peer_fsm_event_names,
	.timer_cb = ran_peer_fsm_timer_cb,
	.cleanup = ran_peer_fsm_cleanup,
	.allstate_action = ran_peer_allstate_action,
	.allstate_event_mask = 0
		| S(RAN_PEER_EV_MSG_UP_CL)
		,
};

int ran_peer_up_l2(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *calling_addr, bool co, uint32_t conn_id,
		   struct msgb *l2)
{
	struct ran_peer *ran_peer = NULL;
	uint32_t event;
	struct ran_peer_ev_ctx ctx = {
		.conn_id = conn_id,
		.msg = l2,
	};

	if (co) {
		struct ran_conn *conn;
		llist_for_each_entry(conn, &sri->ran_conns, entry) {
			if (conn->sccp_conn_id == conn_id) {
				ran_peer = conn->ran_peer;
				ctx.conn = conn;
				break;
			}
		}

		if (ran_peer && calling_addr) {
			LOG_SCCP_RAN_CO(sri, calling_addr, conn_id, LOGL_ERROR,
					"Connection-Oriented Initial message for already existing conn_id."
					" Dropping message.\n");
			return -EINVAL;
		}

		if (!ran_peer && !calling_addr) {
			LOG_SCCP_RAN_CO(sri, calling_addr, conn_id, LOGL_ERROR,
					"Connection-Oriented non-Initial message for unknown conn_id %u."
					" Dropping message.\n", conn_id);
			return -EINVAL;
		}
	}

	if (calling_addr) {
		ran_peer = ran_peer_find_or_create(sri, calling_addr);
		if (!ran_peer) {
			LOG_SCCP_RAN_CL(sri, calling_addr, LOGL_ERROR, "Cannot register RAN peer\n");
			return -EIO;
		}
	}

	OSMO_ASSERT(ran_peer && ran_peer->fi);

	if (co)
		event = calling_addr ? RAN_PEER_EV_MSG_UP_CO_INITIAL : RAN_PEER_EV_MSG_UP_CO;
	else
		event = RAN_PEER_EV_MSG_UP_CL;

	return osmo_fsm_inst_dispatch(ran_peer->fi, event, &ctx);
}

void ran_peer_disconnect(struct sccp_ran_inst *sri, uint32_t conn_id)
{
	struct ran_conn *conn;
	llist_for_each_entry(conn, &sri->ran_conns, entry) {
		if (conn->sccp_conn_id == conn_id) {
			ran_conn_discard(conn);
			return;
		}
	}
}

struct ran_peer *ran_peer_find_by_cell_id(struct sccp_ran_inst *sri, const struct gsm0808_cell_id *cid,
					  bool expecting_single_match)
{
	struct ran_peer *rp;
	struct ran_peer *found = NULL;

	llist_for_each_entry(rp, &sri->ran_peers, entry) {
		if (cell_id_list_find(&rp->cells_seen, cid, 0, false)) {
			if (!expecting_single_match)
				return rp;
			/* Otherwise continue iterating and log errors for multiple matches... */
			if (found) {
				LOG_RAN_PEER(found, LOGL_ERROR, "Cell appears in more than one RAN peer:"
					     " %s also appears in %s\n",
					     gsm0808_cell_id_name(cid), rp->fi->id);
			} else
				found = rp;
		}
	}
	return found;
}

struct ran_peer *ran_peer_find_by_addr(struct sccp_ran_inst *sri, const struct osmo_sccp_addr *addr)
{
	struct ran_peer *rp;

	llist_for_each_entry(rp, &sri->ran_peers, entry) {
		if (!osmo_sccp_addr_ri_cmp(addr, &rp->peer_addr))
			return rp;
	}
	return NULL;
}

int ran_peers_down_paging(struct sccp_ran_inst *sri, enum CELL_IDENT page_where, struct vlr_subscr *vsub,
			  enum paging_cause cause)
{
	struct ran_peer *rp;
	int ret = 0;
	struct gsm0808_cell_id page_id;
	gsm0808_cell_id_from_cgi(&page_id, page_where, &vsub->cgi);

	switch (page_where) {
	case CELL_IDENT_NO_CELL:
		LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Asked to page on NO_CELL, wich doesn't make sense.\n");
		return 0;

	case CELL_IDENT_UTRAN_PLMN_LAC_RNC:
	case CELL_IDENT_UTRAN_RNC:
	case CELL_IDENT_UTRAN_LAC_RNC:
		LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Don't know how to page on %s\n",
				 gsm0808_cell_id_name(&page_id));
		return 0;

	default:
		break;
	};

	llist_for_each_entry(rp, &sri->ran_peers, entry) {
		ret += ran_peer_down_paging(rp, &page_id, vsub, cause);
	}

	if (!ret)
		LOG_SCCP_RAN_CAT(sri, DPAG, LOGL_ERROR, "Paging failed, no RAN peers found for %s\n",
				 gsm0808_cell_id_name(&page_id));
	return ret;
}

/* If the given vsub->cgi matches this ran_peer with respect to page_where, page and return 1.
 * Otherwise return 0. (Return value: number of pagings sent) */
int ran_peer_down_paging(struct ran_peer *rp, const struct gsm0808_cell_id *page_id, struct vlr_subscr *vsub,
			 enum paging_cause cause)
{
	struct msgb *l2;

	/* There are also the RAN peers that are configured in the neighbor ident for Handover, but if those aren't
	 * connected, then we can't Page there. */
	if (!cell_id_list_find(&rp->cells_seen, page_id, 0, false))
		return 0;

	LOG_RAN_PEER_CAT(rp, DPAG, LOGL_DEBUG, "Paging for %s on %s\n", vlr_subscr_name(vsub),
			 gsm0808_cell_id_name(page_id));
	l2 = rp->sri->ran->sccp_ran_ops.make_paging_msg(rp->sri, page_id, vsub->imsi, vsub->tmsi, cause);
	if (osmo_fsm_inst_dispatch(rp->fi, RAN_PEER_EV_MSG_DOWN_CL, l2)) {
		/* Not allowed to send messages, the peer is not properly connected yet/anymore */
		LOG_RAN_PEER_CAT(rp, DPAG, LOGL_ERROR,
				 "Paging for %s matched this RAN peer, but emitting a Paging failed\n",
				 gsm0808_cell_id_name(page_id));
		msgb_free(l2);
		return 0;
	}

	/* The RAN_PEER_EV_MSG_DOWN_CL handler calls sccp_ran_down_l2_cl(),
	 * which doesn't free msgb. We have to do this ourselves. */
	msgb_free(l2);

	return 1;
}
