/* 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 <openbsc/e1_input.h>
#include <openbsc/signal.h>

#include "../libabis/input/lapd.h"

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

static void bootstrap_om_trx(struct gsm_bts_trx *trx)
{
	struct abis_om2k_mo trx_mo = { OM2K_MO_CLS_TRXC, 0, 255, trx->nr };

	LOGP(DNM, LOGL_NOTICE, "bootstrapping OML for TRX %u/%u\n",
	     trx->bts->nr, trx->nr);

	abis_om2k_tx_reset_cmd(trx->bts, &trx_mo);
}

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 (start)
				lapd_sap_start(ts->driver.dahdi.lapd, link->tei, link->sapi);
			else
				lapd_sap_stop(ts->driver.dahdi.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_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;

	if (subsys != SS_INPUT)
		return 0;

	switch (signal) {
	case S_INP_TEI_UP:
		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_INP_LINE_INIT:
		/* Right now Ericsson RBS are only supported on DAHDI */
		if (strcasecmp(isd->line->driver->name, "DAHDI"))
			break;
		start_sabm_in_line(isd->line, 1);
		break;
	case S_INP_LINE_ALARM:
		if (strcasecmp(isd->line->driver->name, "DAHDI"))
			break;
		start_sabm_in_line(isd->line, 0);
		break;
	case S_INP_LINE_NOALARM:
		if (strcasecmp(isd->line->driver->name, "DAHDI"))
			break;
		start_sabm_in_line(isd->line, 1);
		break;
	}

	return 0;
}

static void nm_statechg_evt(unsigned int signal,
			    struct nm_statechg_signal_data *nsd)
{
	struct abis_om2k_mo mo;

	if (nsd->bts->type != GSM_BTS_TYPE_RBS2000)
		return;

	switch (nsd->om2k_mo->class) {
	case OM2K_MO_CLS_CF:
		if (nsd->new_state->operational != NM_OPSTATE_ENABLED ||
		    nsd->new_state->availability != OM2K_MO_S_STARTED)
			break;
		/* CF has started, we can trigger IS and TF start */
		abis_om2k_tx_connect_cmd(nsd->bts, &om2k_mo_is);
		abis_om2k_tx_connect_cmd(nsd->bts, &om2k_mo_tf);
		break;
	case OM2K_MO_CLS_IS:
		if (nsd->new_state->availability == OM2K_MO_S_ENABLED) {
			/* IS is enabled, we can proceed with TRXC/RX/TX/TS */
			break;
		}
		if (nsd->new_state->operational != NM_OPSTATE_ENABLED)
			break;
		/* IS has started, we can configure + enable it */
		abis_om2k_tx_is_conf_req(nsd->bts);
		break;
	case OM2K_MO_CLS_TF:
		if (nsd->new_state->operational != NM_OPSTATE_ENABLED ||
		    nsd->new_state->availability == OM2K_MO_S_DISABLED)
			break;
		if (nsd->new_state->availability == OM2K_MO_S_STARTED) {
			/* TF has started, configure + enable it */
			abis_om2k_tx_is_conf_req(nsd->bts);
		}
		break;
	case OM2K_MO_CLS_TRXC:
		if (nsd->new_state->availability != OM2K_MO_S_STARTED)
			break;
		/* TRXC is started, connect the TX and RX objects */
		memcpy(&mo, nsd->om2k_mo, sizeof(mo));
		mo.class = OM2K_MO_CLS_TX;
		abis_om2k_tx_connect_cmd(nsd->bts, &mo);
		mo.class = OM2K_MO_CLS_RX;
		abis_om2k_tx_connect_cmd(nsd->bts, &mo);
		break;
	case OM2K_MO_CLS_RX:
		if (nsd->new_state->operational != NM_OPSTATE_ENABLED ||
		    nsd->new_state->availability != OM2K_MO_S_STARTED)
			break;
		/* RX is started, configure + enable it */
		abis_om2k_tx_rx_conf_req(nsd->obj);
		break;
	case OM2K_MO_CLS_TX:
		if (nsd->new_state->operational != NM_OPSTATE_ENABLED ||
		    nsd->new_state->availability != OM2K_MO_S_STARTED)
			break;
		/* RX is started, configure + enable it */
		abis_om2k_tx_tx_conf_req(nsd->obj);
		break;
	}
}

static void nm_conf_res(struct nm_om2k_signal_data *nsd)
{
	switch (nsd->om2k_mo->class) {
	case OM2K_MO_CLS_IS:
	case OM2K_MO_CLS_TF:
	case OM2K_MO_CLS_RX:
	case OM2K_MO_CLS_TX:
		/* If configuration was a success, enable it */
		abis_om2k_tx_enable_req(nsd->bts, nsd->om2k_mo);
		break;
	}
}

static int nm_sig_cb(unsigned int subsys, unsigned int signal,
		     void *handler_data, void *signal_data)
{
	if (subsys != SS_NM)
		return 0;

	switch (signal) {
	case S_NM_STATECHG_OPER:
	case S_NM_STATECHG_ADM:
		nm_statechg_evt(signal, signal_data);
		break;
	case S_NM_OM2K_CONF_RES:
		nm_conf_res(signal_data);
		break;
	default:
		break;
	}

	return 0;
}

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

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

int bts_model_rbs2k_init(void)
{
	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_HOPPING);
	gsm_btsmodel_set_feature(&model_rbs2k, BTS_FEAT_HSCSD);

	register_signal_handler(SS_INPUT, inp_sig_cb, NULL);
	register_signal_handler(SS_GLOBAL, gbl_sig_cb, NULL);
	register_signal_handler(SS_NM, nm_sig_cb, NULL);

	return gsm_bts_model_register(&model_rbs2k);
}
