/* ip.access nanoBTS specific code */

/* (C) 2009-2010 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 <arpa/inet.h>

#include <osmocom/gsm/tlv.h>

#include <openbsc/gsm_data.h>
#include <openbsc/signal.h>
#include <openbsc/abis_nm.h>
#include <openbsc/e1_input.h> /* for ipaccess_setup() */

static int bts_model_nanobts_start(struct gsm_network *net);

static struct gsm_bts_model model_nanobts = {
	.type = GSM_BTS_TYPE_NANOBTS,
	.name = "nanobts",
	.start = bts_model_nanobts_start,
	.oml_rcvmsg = &abis_nm_rcvmsg,
	.nm_att_tlvdef = {
		.def = {
			/* ip.access specifics */
			[NM_ATT_IPACC_DST_IP] =		{ TLV_TYPE_FIXED, 4 },
			[NM_ATT_IPACC_DST_IP_PORT] =	{ TLV_TYPE_FIXED, 2 },
			[NM_ATT_IPACC_STREAM_ID] =	{ TLV_TYPE_TV, },
			[NM_ATT_IPACC_SEC_OML_CFG] =	{ TLV_TYPE_FIXED, 6 },
			[NM_ATT_IPACC_IP_IF_CFG] =	{ TLV_TYPE_FIXED, 8 },
			[NM_ATT_IPACC_IP_GW_CFG] =	{ TLV_TYPE_FIXED, 12 },
			[NM_ATT_IPACC_IN_SERV_TIME] =	{ TLV_TYPE_FIXED, 4 },
			[NM_ATT_IPACC_LOCATION] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_PAGING_CFG] =	{ TLV_TYPE_FIXED, 2 },
			[NM_ATT_IPACC_UNIT_ID] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_UNIT_NAME] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_SNMP_CFG] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_PRIM_OML_CFG_LIST] = { TLV_TYPE_TL16V },
			[NM_ATT_IPACC_NV_FLAGS] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_FREQ_CTRL] =	{ TLV_TYPE_FIXED, 2 },
			[NM_ATT_IPACC_PRIM_OML_FB_TOUT] = { TLV_TYPE_TL16V },
			[NM_ATT_IPACC_CUR_SW_CFG] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_TIMING_BUS] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_CGI] =		{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_RAC] =		{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_OBJ_VERSION] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_GPRS_PAGING_CFG]= { TLV_TYPE_TL16V },
			[NM_ATT_IPACC_NSEI] =		{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_BVCI] =		{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_NSVCI] =		{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_NS_CFG] =		{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_BSSGP_CFG] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_NS_LINK_CFG] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_RLC_CFG] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_ALM_THRESH_LIST]=	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_MONIT_VAL_LIST] = { TLV_TYPE_TL16V },
			[NM_ATT_IPACC_TIB_CONTROL] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_SUPP_FEATURES] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_CODING_SCHEMES] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_RLC_CFG_2] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_HEARTB_TOUT] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_UPTIME] =		{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_RLC_CFG_3] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_SSL_CFG] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_SEC_POSSIBLE] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_IML_SSL_STATE] =	{ TLV_TYPE_TL16V },
			[NM_ATT_IPACC_REVOC_DATE] =	{ TLV_TYPE_TL16V },
		},
	},
};

static unsigned char nanobts_attr_bts[] = {
	NM_ATT_INTERF_BOUND, 0x55, 0x5b, 0x61, 0x67, 0x6d, 0x73,
	/* interference avg. period in numbers of SACCH multifr */
	NM_ATT_INTAVE_PARAM, 0x06,
	/* conn fail based on SACCH error rate */
	NM_ATT_CONN_FAIL_CRIT, 0x00, 0x02, 0x01, 0x10,
	NM_ATT_T200, 0x1e, 0x24, 0x24, 0xa8, 0x34, 0x21, 0xa8,
	NM_ATT_MAX_TA, 0x3f,
	NM_ATT_OVERL_PERIOD, 0x00, 0x01, 10, /* seconds */
	NM_ATT_CCCH_L_T, 10, /* percent */
	NM_ATT_CCCH_L_I_P, 1, /* seconds */
	NM_ATT_RACH_B_THRESH, 10, /* busy threshold in - dBm */
	NM_ATT_LDAVG_SLOTS, 0x03, 0xe8, /* rach load averaging 1000 slots */
	NM_ATT_BTS_AIR_TIMER, 128, /* miliseconds */
	NM_ATT_NY1, 10, /* 10 retransmissions of physical config */
	NM_ATT_BCCH_ARFCN, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
	NM_ATT_BSIC, HARDCODED_BSIC,
	//NM_ATT_IPACC_CGI, 0, 7,  0x00, 0xf1, 0x10, 0x00, 0x01, 0x00, 0x00,
};

static unsigned char nanobts_attr_radio[] = {
	NM_ATT_RF_MAXPOWR_R, 0x0c, /* number of -2dB reduction steps / Pn */
	NM_ATT_ARFCN_LIST, 0x00, 0x02, HARDCODED_ARFCN >> 8, HARDCODED_ARFCN & 0xff,
};

static unsigned char nanobts_attr_nse[] = {
	NM_ATT_IPACC_NSEI, 0, 2,  0x03, 0x9d, /* NSEI 925 */
	NM_ATT_IPACC_NS_CFG, 0, 7,  3,  /* (un)blocking timer (Tns-block) */
				    3,  /* (un)blocking retries */
				    3,  /* reset timer (Tns-reset) */
				    3,  /* reset retries */
				    30,  /* test timer (Tns-test) */
				    3,  /* alive timer (Tns-alive) */
				    10, /* alive retrires */
	NM_ATT_IPACC_BSSGP_CFG, 0, 11,
				    3,  /* blockimg timer (T1) */
				    3,  /* blocking retries */
				    3,  /* unblocking retries */
				    3,  /* reset timer */
				    3,  /* reset retries */
				    10, /* suspend timer (T3) in 100ms */
				    3,  /* suspend retries */
				    10, /* resume timer (T4) in 100ms */
				    3,  /* resume retries */
				    10, /* capability update timer (T5) */
				    3,  /* capability update retries */
};

static unsigned char nanobts_attr_cell[] = {
	NM_ATT_IPACC_RAC, 0, 1,  1, /* routing area code */
	NM_ATT_IPACC_GPRS_PAGING_CFG, 0, 2,
		5,	/* repeat time (50ms) */
		3,	/* repeat count */
	NM_ATT_IPACC_BVCI, 0, 2,  0x03, 0x9d, /* BVCI 925 */
	NM_ATT_IPACC_RLC_CFG, 0, 9,
		20, 	/* T3142 */
		5, 	/* T3169 */
		5,	/* T3191 */
		200,	/* T3193 */
		5,	/* T3195 */
		10,	/* N3101 */
		4,	/* N3103 */
		8,	/* N3105 */
		15,	/* RLC CV countdown */
	NM_ATT_IPACC_CODING_SCHEMES, 0, 2,  0x0f, 0x00,	/* CS1..CS4 */
	NM_ATT_IPACC_RLC_CFG_2, 0, 5,
		0x00, 250,	/* T downlink TBF extension (0..500) */
		0x00, 250,	/* T uplink TBF extension (0..500) */
		2,	/* CS2 */
#if 0
	/* EDGE model only, breaks older models.
	 * Should inquire the BTS capabilities */
	NM_ATT_IPACC_RLC_CFG_3, 0, 1,
		2,	/* MCS2 */
#endif
};

static unsigned char nanobts_attr_nsvc0[] = {
	NM_ATT_IPACC_NSVCI, 0, 2,  0x03, 0x9d, /* 925 */
	NM_ATT_IPACC_NS_LINK_CFG, 0, 8,
		0x59, 0xd8, /* remote udp port (23000) */
		192, 168, 100, 11, /* remote ip address */
		0x59, 0xd8, /* local udp port (23000) */
};

static void patch_16(uint8_t *data, const uint16_t val)
{
	memcpy(data, &val, sizeof(val));
}

static void patch_32(uint8_t *data, const uint32_t val)
{
	memcpy(data, &val, sizeof(val));
}

/*
 * Patch the various SYSTEM INFORMATION tables to update
 * the LAI
 */
static void patch_nm_tables(struct gsm_bts *bts)
{
	uint8_t arfcn_low = bts->c0->arfcn & 0xff;
	uint8_t arfcn_high = (bts->c0->arfcn >> 8) & 0x0f;

	/* patch ARFCN into BTS Attributes */
	nanobts_attr_bts[42] &= 0xf0;
	nanobts_attr_bts[42] |= arfcn_high;
	nanobts_attr_bts[43] = arfcn_low;

	/* patch the RACH attributes */
	if (bts->rach_b_thresh != -1) {
		nanobts_attr_bts[33] = bts->rach_b_thresh & 0xff;
	}

	if (bts->rach_ldavg_slots != -1) {
		uint8_t avg_high = bts->rach_ldavg_slots & 0xff;
		uint8_t avg_low = (bts->rach_ldavg_slots >> 8) & 0x0f;

		nanobts_attr_bts[35] = avg_high;
		nanobts_attr_bts[36] = avg_low;
	}

	/* patch BSIC */
	nanobts_attr_bts[sizeof(nanobts_attr_bts)-11] = bts->bsic;

	/* patch CGI */
	//abis_nm_ipaccess_cgi(nanobts_attr_bts+sizeof(nanobts_attr_bts)-7, bts);

	/* patch the power reduction */
	nanobts_attr_radio[1] = bts->c0->max_power_red / 2;

	/* patch NSEI */
	nanobts_attr_nse[3] = bts->gprs.nse.nsei >> 8;
	nanobts_attr_nse[4] = bts->gprs.nse.nsei & 0xff;
	memcpy(nanobts_attr_nse+8, bts->gprs.nse.timer,
		ARRAY_SIZE(bts->gprs.nse.timer));
	memcpy(nanobts_attr_nse+18, bts->gprs.cell.timer,
		ARRAY_SIZE(bts->gprs.cell.timer));

	/* patch NSVCI */
	nanobts_attr_nsvc0[3] = bts->gprs.nsvc[0].nsvci >> 8;
	nanobts_attr_nsvc0[4] = bts->gprs.nsvc[0].nsvci & 0xff;

	/* patch IP address as SGSN IP */
	patch_16(nanobts_attr_nsvc0 + 8, 
			htons(bts->gprs.nsvc[0].remote_port));
	patch_32(nanobts_attr_nsvc0 + 10,
			htonl(bts->gprs.nsvc[0].remote_ip));
	patch_16(nanobts_attr_nsvc0 + 14,
			htons(bts->gprs.nsvc[0].local_port));

	/* patch BVCI */
	nanobts_attr_cell[12] = bts->gprs.cell.bvci >> 8;
	nanobts_attr_cell[13] = bts->gprs.cell.bvci & 0xff;
	/* patch RAC */
	nanobts_attr_cell[3] = bts->gprs.rac;

	if (bts->gprs.mode == BTS_GPRS_EGPRS) {
		/* patch EGPRS coding schemes MCS 1..9 */
		nanobts_attr_cell[29] = 0x8f;
		nanobts_attr_cell[30] = 0xff;
	}
}


/* Callback function to be called whenever we get a GSM 12.21 state change event */
static int nm_statechg_event(int evt, struct nm_statechg_signal_data *nsd)
{
	uint8_t obj_class = nsd->obj_class;
	void *obj = nsd->obj;
	struct gsm_nm_state *new_state = nsd->new_state;

	struct gsm_bts *bts;
	struct gsm_bts_trx *trx;
	struct gsm_bts_trx_ts *ts;
	struct gsm_bts_gprs_nsvc *nsvc;

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

	/* This event-driven BTS setup is currently only required on nanoBTS */

	/* S_NM_STATECHG_ADM is called after we call chg_adm_state() and would create
	 * endless loop */
	if (evt != S_NM_STATECHG_OPER)
		return 0;

	switch (obj_class) {
	case NM_OC_SITE_MANAGER:
		bts = container_of(obj, struct gsm_bts, site_mgr);
		if ((new_state->operational == NM_OPSTATE_ENABLED &&
		     new_state->availability == NM_AVSTATE_OK) ||
		    (new_state->operational == NM_OPSTATE_DISABLED &&
		     new_state->availability == NM_AVSTATE_OFF_LINE))
			abis_nm_opstart(bts, obj_class, 0xff, 0xff, 0xff);
		break;
	case NM_OC_BTS:
		bts = obj;
		if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
			patch_nm_tables(bts);
			abis_nm_set_bts_attr(bts, nanobts_attr_bts,
					     sizeof(nanobts_attr_bts));
			abis_nm_chg_adm_state(bts, obj_class,
					      bts->bts_nr, 0xff, 0xff,
					      NM_STATE_UNLOCKED);
			abis_nm_opstart(bts, obj_class,
					bts->bts_nr, 0xff, 0xff);
		}
		break;
	case NM_OC_CHANNEL:
		ts = obj;
		trx = ts->trx;
		if (new_state->operational == NM_OPSTATE_DISABLED &&
		    new_state->availability == NM_AVSTATE_DEPENDENCY) {
			patch_nm_tables(trx->bts);
			enum abis_nm_chan_comb ccomb =
						abis_nm_chcomb4pchan(ts->pchan);
			abis_nm_set_channel_attr(ts, ccomb);
			abis_nm_chg_adm_state(trx->bts, obj_class,
					      trx->bts->bts_nr, trx->nr, ts->nr,
					      NM_STATE_UNLOCKED);
			abis_nm_opstart(trx->bts, obj_class,
					trx->bts->bts_nr, trx->nr, ts->nr);
		}
		break;
	case NM_OC_RADIO_CARRIER:
		trx = obj;
		if (new_state->operational == NM_OPSTATE_DISABLED &&
		    new_state->availability == NM_AVSTATE_OK)
			abis_nm_opstart(trx->bts, obj_class, trx->bts->bts_nr,
					trx->nr, 0xff);
		break;
	case NM_OC_GPRS_NSE:
		bts = container_of(obj, struct gsm_bts, gprs.nse);
		if (bts->gprs.mode == BTS_GPRS_NONE)
			break;
		if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
			abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
						  0xff, 0xff, nanobts_attr_nse,
						  sizeof(nanobts_attr_nse));
			abis_nm_opstart(bts, obj_class, bts->bts_nr,
					0xff, 0xff);
		}
		break;
	case NM_OC_GPRS_CELL:
		bts = container_of(obj, struct gsm_bts, gprs.cell);
		if (bts->gprs.mode == BTS_GPRS_NONE)
			break;
		if (new_state->availability == NM_AVSTATE_DEPENDENCY) {
			abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
						  0, 0xff, nanobts_attr_cell,
						  sizeof(nanobts_attr_cell));
			abis_nm_opstart(bts, obj_class, bts->bts_nr,
					0, 0xff);
			abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
					      0, 0xff, NM_STATE_UNLOCKED);
			abis_nm_chg_adm_state(bts, NM_OC_GPRS_NSE, bts->bts_nr,
					      0xff, 0xff, NM_STATE_UNLOCKED);
		}
		break;
	case NM_OC_GPRS_NSVC:
		nsvc = obj;
		bts = nsvc->bts;
		if (bts->gprs.mode == BTS_GPRS_NONE)
			break;
		/* We skip NSVC1 since we only use NSVC0 */
		if (nsvc->id == 1)
			break;
		if (new_state->availability == NM_AVSTATE_OFF_LINE) {
			abis_nm_ipaccess_set_attr(bts, obj_class, bts->bts_nr,
						  nsvc->id, 0xff,
						  nanobts_attr_nsvc0,
						  sizeof(nanobts_attr_nsvc0));
			abis_nm_opstart(bts, obj_class, bts->bts_nr,
					nsvc->id, 0xff);
			abis_nm_chg_adm_state(bts, obj_class, bts->bts_nr,
					      nsvc->id, 0xff,
					      NM_STATE_UNLOCKED);
		}
	default:
		break;
	}
	return 0;
}

/* Callback function to be called every time we receive a 12.21 SW activated report */
static int sw_activ_rep(struct msgb *mb)
{
	struct abis_om_fom_hdr *foh = msgb_l3(mb);
	struct gsm_bts *bts = mb->trx->bts;
	struct gsm_bts_trx *trx = gsm_bts_trx_num(bts, foh->obj_inst.trx_nr);

	if (!trx)
		return -EINVAL;

	if (trx->bts->type != GSM_BTS_TYPE_NANOBTS)
		return 0;

	switch (foh->obj_class) {
	case NM_OC_BASEB_TRANSC:
		abis_nm_chg_adm_state(trx->bts, foh->obj_class,
				      trx->bts->bts_nr, trx->nr, 0xff,
				      NM_STATE_UNLOCKED);
		abis_nm_opstart(trx->bts, foh->obj_class,
				trx->bts->bts_nr, trx->nr, 0xff);
		/* TRX software is active, tell it to initiate RSL Link */
		abis_nm_ipaccess_rsl_connect(trx, 0, 3003, trx->rsl_tei);
		break;
	case NM_OC_RADIO_CARRIER: {
		/*
		 * Locking the radio carrier will make it go
		 * offline again and we would come here. The
		 * framework should determine that there was
		 * no change and avoid recursion.
		 *
		 * This code is here to make sure that on start
		 * a TRX remains locked.
		 */
		int rc_state = trx->mo.nm_state.administrative;
		/* Patch ARFCN into radio attribute */
		nanobts_attr_radio[5] &= 0xf0;
		nanobts_attr_radio[5] |= trx->arfcn >> 8;
		nanobts_attr_radio[6] = trx->arfcn & 0xff;
		abis_nm_set_radio_attr(trx, nanobts_attr_radio,
				       sizeof(nanobts_attr_radio));
		abis_nm_chg_adm_state(trx->bts, foh->obj_class,
				      trx->bts->bts_nr, trx->nr, 0xff,
				      rc_state);
		abis_nm_opstart(trx->bts, foh->obj_class, trx->bts->bts_nr,
				trx->nr, 0xff);
		break;
		}
	}
	return 0;
}

/* Callback function to be called every time we receive a signal from NM */
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_SW_ACTIV_REP:
		return sw_activ_rep(signal_data);
	case S_NM_STATECHG_OPER:
	case S_NM_STATECHG_ADM:
		return nm_statechg_event(signal, signal_data);
	default:
		break;
	}
	return 0;
}

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

	gsm_btsmodel_set_feature(&model_nanobts, BTS_FEAT_GPRS);
	gsm_btsmodel_set_feature(&model_nanobts, BTS_FEAT_EGPRS);

	osmo_signal_register_handler(SS_NM, nm_sig_cb, NULL);

	/* Call A-bis input driver, start server sockets for OML and RSL. */
	return ipaccess_setup(net);
}

int bts_model_nanobts_init(void)
{
	return gsm_bts_model_register(&model_nanobts);
}
