/* The concept of a subscriber for the MSC, roughly HLR/VLR functionality */

/* (C) 2008 by Harald Welte <laforge@gnumonks.org>
 * (C) 2009,2013 by Holger Hans Peter Freyther <zecke@selfish.org>
 *
 * All Rights Reserved
 *
 * 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 "../../bscconfig.h"

#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include <time.h>
#include <stdbool.h>

#include <osmocom/core/talloc.h>

#include <osmocom/vty/vty.h>

#ifdef BUILD_IU
#include <osmocom/ranap/iu_client.h>
#else
#include <osmocom/msc/iu_dummy.h>
#endif

#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/gsm_04_08.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/db.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/osmo_msc.h>
#include <osmocom/msc/msc_ifaces.h>
#include <osmocom/msc/a_iface.h>

void subscr_paging_cancel(struct vlr_subscr *vsub, enum gsm_paging_event event)
{
	subscr_paging_dispatch(GSM_HOOK_RR_PAGING, event, NULL, NULL, vsub);
}

int subscr_paging_dispatch(unsigned int hooknum, unsigned int event,
			   struct msgb *msg, void *data, void *param)
{
	struct subscr_request *request, *tmp;
	struct ran_conn *conn = data;
	struct vlr_subscr *vsub = param;
	struct paging_signal_data sig_data;

	OSMO_ASSERT(vsub);
	OSMO_ASSERT(hooknum == GSM_HOOK_RR_PAGING);
	OSMO_ASSERT(!(conn && (conn->vsub != vsub)));
	OSMO_ASSERT(!((event == GSM_PAGING_SUCCEEDED) && !conn));

	LOGP(DPAG, LOGL_DEBUG, "Paging %s for %s (event=%d)\n",
	     event == GSM_PAGING_SUCCEEDED ? "success" : "failure",
	     vlr_subscr_name(vsub), event);

	if (!vsub->cs.is_paging) {
		LOGP(DPAG, LOGL_ERROR,
		     "Paging Response received for subscriber"
		     " that is not paging.\n");
		return -EINVAL;
	}

	osmo_timer_del(&vsub->cs.paging_response_timer);

	if (event == GSM_PAGING_SUCCEEDED
	    || event == GSM_PAGING_EXPIRED)
		msc_stop_paging(vsub);

	/* Inform parts of the system we don't know */
	sig_data.vsub = vsub;
	sig_data.conn = conn;
	sig_data.paging_result = event;
	osmo_signal_dispatch(SS_PAGING,
			     event == GSM_PAGING_SUCCEEDED ?
				S_PAGING_SUCCEEDED : S_PAGING_EXPIRED,
			     &sig_data);

	llist_for_each_entry_safe(request, tmp, &vsub->cs.requests, entry) {
		llist_del(&request->entry);
		if (request->cbfn) {
			LOGP(DPAG, LOGL_DEBUG, "Calling paging cbfn.\n");
			request->cbfn(hooknum, event, msg, data, request->param);
		} else
			LOGP(DPAG, LOGL_DEBUG, "Paging without action.\n");
		talloc_free(request);
	}

	/* balanced with the moment we start paging */
	vsub->cs.is_paging = false;
	vlr_subscr_put(vsub);
	return 0;
}

int msc_paging_request(struct vlr_subscr *vsub)
{
	/* The subscriber was last seen in subscr->lac. Find out which
	 * BSCs/RNCs are responsible and send them a paging request via open
	 * SCCP connections (if any). */
	switch (vsub->cs.attached_via_ran) {
	case RAN_GERAN_A:
		return a_iface_tx_paging(vsub->imsi, vsub->tmsi, vsub->lac);
	case RAN_UTRAN_IU:
		return ranap_iu_page_cs(vsub->imsi,
					vsub->tmsi == GSM_RESERVED_TMSI?
					NULL : &vsub->tmsi,
					vsub->lac);
	default:
		break;
	}

	LOGP(DPAG, LOGL_ERROR, "%s: Cannot page, subscriber not attached\n",
	     vlr_subscr_name(vsub));
	return -EINVAL;
}

static void paging_response_timer_cb(void *data)
{
	struct vlr_subscr *vsub = data;
	subscr_paging_cancel(vsub, GSM_PAGING_EXPIRED);
}

/*! \brief Start a paging request for vsub, call cbfn(param) when done.
 * \param vsub  subscriber to page.
 * \param cbfn  function to call when the conn is established.
 * \param param  caller defined param to pass to cbfn().
 * \param label  human readable label of the request kind used for logging.
 */
struct subscr_request *subscr_request_conn(struct vlr_subscr *vsub,
					   gsm_cbfn *cbfn, void *param,
					   const char *label)
{
	int rc;
	struct subscr_request *request;
	struct gsm_network *net = vsub->vlr->user_ctx;

	/* Start paging.. we know it is async so we can do it before */
	if (!vsub->cs.is_paging) {
		LOGP(DMM, LOGL_DEBUG, "Subscriber %s not paged yet, start paging.\n",
		     vlr_subscr_name(vsub));
		rc = msc_paging_request(vsub);
		if (rc <= 0) {
			LOGP(DMM, LOGL_ERROR, "Subscriber %s paging failed: %d\n",
			     vlr_subscr_name(vsub), rc);
			return NULL;
		}
		/* reduced on the first paging callback */
		vlr_subscr_get(vsub);
		vsub->cs.is_paging = true;
		osmo_timer_setup(&vsub->cs.paging_response_timer, paging_response_timer_cb, vsub);
		osmo_timer_schedule(&vsub->cs.paging_response_timer, net->paging_response_timer, 0);
	} else {
		LOGP(DMM, LOGL_DEBUG, "Subscriber %s already paged.\n",
			vlr_subscr_name(vsub));
	}

	/* TODO: Stop paging in case of memory allocation failure */
	request = talloc_zero(vsub, struct subscr_request);
	if (!request)
		return NULL;

	request->cbfn = cbfn;
	request->param = param;
	llist_add_tail(&request->entry, &vsub->cs.requests);
	return request;
}

void subscr_remove_request(struct subscr_request *request)
{
	llist_del(&request->entry);
	talloc_free(request);
}

struct ran_conn *connection_for_subscr(struct vlr_subscr *vsub)
{
	struct gsm_network *net = vsub->vlr->user_ctx;
	struct ran_conn *conn;

	llist_for_each_entry(conn, &net->ran_conns, entry) {
		if (conn->vsub == vsub)
			return conn;
	}

	return NULL;
}
