/* Ericsson RBS-2xxx specific code */

/* (C) 2011 by Harald Welte <laforge@gnumonks.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 <osmocom/gsm/tlv.h>

#include <openbsc/debug.h>
#include <openbsc/gsm_data.h>
#include <openbsc/abis_om2000.h>
#include <openbsc/abis_nm.h>
#include <osmocom/abis/e1_input.h>
#include <openbsc/signal.h>

#include <osmocom/abis/lapd.h>

static void bootstrap_om_bts(struct gsm_bts *bts)
{
	LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for BTS %u\n", bts->nr);

	/* FIXME: this is global init, not bootstrapping */
	abis_om2k_bts_init(bts);
	abis_om2k_trx_init(bts->c0);

	/* TODO: Should we wait for a Failure report? */
	om2k_bts_fsm_start(bts);
}

static void bootstrap_om_trx(struct gsm_bts_trx *trx)
{
	LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for TRX %u/%u\n",
	     trx->bts->nr, trx->nr);
	/* FIXME */
}

static int shutdown_om(struct gsm_bts *bts)
{
	/* FIXME */
	return 0;
}


/* Tell LAPD to start start the SAP (send SABM requests) for all signalling
 * timeslots in this line */
static void start_sabm_in_line(struct e1inp_line *line, int start)
{
	struct e1inp_sign_link *link;
	int i;

	for (i = 0; i < ARRAY_SIZE(line->ts); i++) {
		struct e1inp_ts *ts = &line->ts[i];

		if (ts->type != E1INP_TS_TYPE_SIGN)
			continue;

		llist_for_each_entry(link, &ts->sign.sign_links, list) {
			if (!ts->lapd)
				continue;
			lapd_instance_set_profile(ts->lapd,
						  &lapd_profile_abis_ericsson);

			if (start)
				lapd_sap_start(ts->lapd, link->tei, link->sapi);
			else
				lapd_sap_stop(ts->lapd, link->tei, link->sapi);
		}
	}
}

/* Callback function to be called every time we receive a signal from INPUT */
static int gbl_sig_cb(unsigned int subsys, unsigned int signal,
		      void *handler_data, void *signal_data)
{
	struct gsm_bts *bts;

	if (subsys != SS_L_GLOBAL)
		return 0;

	switch (signal) {
	case S_GLOBAL_BTS_CLOSE_OM:
		bts = signal_data;
		if (bts->type == GSM_BTS_TYPE_RBS2000)
			shutdown_om(signal_data);
		break;
	}

	return 0;
}

/* Callback function to be called every time we receive a signal from INPUT */
static int inp_sig_cb(unsigned int subsys, unsigned int signal,
		      void *handler_data, void *signal_data)
{
	struct input_signal_data *isd = signal_data;
	struct e1inp_ts *e1i_ts;

	if (subsys != SS_L_INPUT)
		return 0;

	switch (signal) {
	case S_L_INP_TEI_UP:
		LOGP(DNM, LOGL_DEBUG, "%s() signal: S_L_INP_TEI_UP\n", __func__);
		switch (isd->link_type) {
		case E1INP_SIGN_OML:
			if (isd->trx->bts->type != GSM_BTS_TYPE_RBS2000)
				break;
			if (isd->tei == isd->trx->bts->oml_tei)
				bootstrap_om_bts(isd->trx->bts);
			else
				bootstrap_om_trx(isd->trx);
			break;
		}
		break;
	case S_L_INP_TEI_DN:
		LOGP(DNM, LOGL_DEBUG, "%s() signal: S_L_INP_TEI_DN\n", __func__);
		if (isd->trx->bts->type != GSM_BTS_TYPE_RBS2000)
			break;
		LOGP(DNM, LOGL_NOTICE, "Line-%u TS-%u TEI-%u SAPI-%u: Link "
		     "Lost for Ericsson RBS2000. Re-starting DL Establishment\n",
		     isd->line->num, isd->ts_nr, isd->tei, isd->sapi);
		/* Some datalink for a given TEI/SAPI went down, try to re-start it */
		e1i_ts = &isd->line->ts[isd->ts_nr-1];
		OSMO_ASSERT(e1i_ts->type == E1INP_TS_TYPE_SIGN);
		lapd_sap_start(e1i_ts->lapd, isd->tei, isd->sapi);
		break;
	case S_L_INP_LINE_INIT:
		LOGP(DNM, LOGL_DEBUG, "%s() signal: S_L_INP_LINE_INIT\n", __func__);
	case S_L_INP_LINE_NOALARM:
		LOGP(DNM, LOGL_DEBUG, "%s() signal: S_L_INP_LINE_NOALARM\n", __func__);
		if (strcasecmp(isd->line->driver->name, "DAHDI")
		 && strcasecmp(isd->line->driver->name, "MISDN_LAPD")
		 && strcasecmp(isd->line->driver->name, "UNIXSOCKET"))
			break;
		start_sabm_in_line(isd->line, 1);
		break;
	case S_L_INP_LINE_ALARM:
		LOGP(DNM, LOGL_DEBUG, "%s() signal: S_L_INP_LINE_ALARM\n", __func__);
		if (strcasecmp(isd->line->driver->name, "DAHDI")
		 && strcasecmp(isd->line->driver->name, "MISDN_LAPD")
		 && strcasecmp(isd->line->driver->name, "UNIXSOCKET"))
			break;
		start_sabm_in_line(isd->line, 0);
		break;
	}

	return 0;
}

static void config_write_bts(struct vty *vty, struct gsm_bts *bts)
{
	abis_om2k_config_write_bts(vty, bts);
}

static int bts_model_rbs2k_start(struct gsm_network *net);

static void bts_model_rbs2k_e1line_bind_ops(struct e1inp_line *line)
{
	e1inp_line_bind_ops(line, &bts_isdn_e1inp_line_ops);
}

static struct gsm_bts_model model_rbs2k = {
	.type = GSM_BTS_TYPE_RBS2000,
	.name = "rbs2000",
	.start = bts_model_rbs2k_start,
	.oml_rcvmsg = &abis_om2k_rcvmsg,
	.config_write_bts = &config_write_bts,
	.e1line_bind_ops = &bts_model_rbs2k_e1line_bind_ops,
};

static int bts_model_rbs2k_start(struct gsm_network *net)
{
	model_rbs2k.features.data = &model_rbs2k._features_data[0];
	model_rbs2k.features.data_len = sizeof(model_rbs2k._features_data);

	gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_GPRS);
	gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_EGPRS);
	gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_HOPPING);
	gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_HSCSD);
	gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_MULTI_TSC);

	osmo_signal_register_handler(SS_L_INPUT, inp_sig_cb, NULL);
	osmo_signal_register_handler(SS_L_GLOBAL, gbl_sig_cb, NULL);

	return 0;
}

int bts_model_rbs2k_init(void)
{
	return gsm_bts_model_register(&model_rbs2k);
}
