/* (C) 2009-2011 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2009-2011 by On-Waves
 * 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 <openbsc/osmo_bsc.h>
#include <openbsc/osmo_msc_data.h>
#include <openbsc/debug.h>

#include <openbsc/gsm_04_80.h>

#include <osmocom/gsm/protocol/gsm_08_08.h>
#include <osmocom/gsm/gsm0808.h>

#include <osmocom/sccp/sccp.h>

#define return_when_not_connected(conn) \
	if (!conn->sccp_con) {\
		LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \
		return; \
	}

#define return_when_not_connected_val(conn, ret) \
	if (!conn->sccp_con) {\
		LOGP(DMSC, LOGL_ERROR, "MSC Connection not present.\n"); \
		return ret; \
	}

#define queue_msg_or_return(resp) \
	if (!resp) { \
		LOGP(DMSC, LOGL_ERROR, "Failed to allocate response.\n"); \
		return; \
	} \
	bsc_queue_for_msc(conn->sccp_con, resp);

static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause);
static int complete_layer3(struct gsm_subscriber_connection *conn,
			   struct msgb *msg, struct osmo_msc_data *msc);

static uint16_t get_network_code_for_msc(struct osmo_msc_data *msc)
{
	if (msc->core_ncc != -1)
		return msc->core_ncc;
	return msc->network->network_code;
}

static uint16_t get_country_code_for_msc(struct osmo_msc_data *msc)
{
	if (msc->core_mcc != -1)
		return msc->core_mcc;
	return msc->network->country_code;
}

static void bsc_sapi_n_reject(struct gsm_subscriber_connection *conn, int dlci)
{
	struct msgb *resp;
	return_when_not_connected(conn);

	LOGP(DMSC, LOGL_NOTICE, "Tx MSC SAPI N REJECT DLCI=0x%02x\n", dlci);

	resp = gsm0808_create_sapi_reject(dlci);
	queue_msg_or_return(resp);
}

static void bsc_cipher_mode_compl(struct gsm_subscriber_connection *conn,
				  struct msgb *msg, uint8_t chosen_encr)
{
	struct msgb *resp;
	return_when_not_connected(conn);

	LOGP(DMSC, LOGL_DEBUG, "CIPHER MODE COMPLETE from MS, forwarding to MSC\n");
	resp = gsm0808_create_cipher_complete(msg, chosen_encr);
	queue_msg_or_return(resp);
}

static void bsc_send_ussd_notification(struct gsm_subscriber_connection *conn,
			   struct msgb *msg, const char *text)
{
	struct gsm48_hdr *gh;
	int8_t pdisc;
	uint8_t mtype;
	int drop_message = 1;

	if (!text)
		return;

	if (!msg || msgb_l3len(msg) < sizeof(*gh))
		return;

	gh = msgb_l3(msg);
	pdisc = gh->proto_discr & 0x0f;
	mtype = gh->msg_type & 0xbf;

	/* Is CM service request? */
	if (pdisc == GSM48_PDISC_MM && mtype == GSM48_MT_MM_CM_SERV_REQ) {
		struct gsm48_service_request *cm;

		cm = (struct gsm48_service_request *) &gh->data[0];

		/* Is type SMS or call? */
		if (cm->cm_service_type == GSM48_CMSERV_SMS)
			drop_message = 0;
		else if (cm->cm_service_type == GSM48_CMSERV_MO_CALL_PACKET)
			drop_message = 0;
	}

	if (drop_message) {
		LOGP(DMSC, LOGL_DEBUG, "Skipping (not sending) USSD message: '%s'\n", text);
		return;
	}

	LOGP(DMSC, LOGL_INFO, "Sending USSD message: '%s'\n", text);
	gsm0480_send_ussdNotify(conn, 1, text);
	gsm0480_send_releaseComplete(conn);
}

/*
 * Instruct to reserve data for a new connectiom, create the complete
 * layer three message, send it to open the connection.
 */
static int bsc_compl_l3(struct gsm_subscriber_connection *conn, struct msgb *msg,
			uint16_t chosen_channel)
{
	struct osmo_msc_data *msc;

	LOGP(DMSC, LOGL_INFO, "Tx MSC COMPL L3\n");

	/* find the MSC link we want to use */
	msc = bsc_find_msc(conn, msg);
	if (!msc) {
		LOGP(DMSC, LOGL_ERROR, "Failed to find a MSC for a connection.\n");
		bsc_send_ussd_notification(conn, msg, conn->bts->network->bsc_data->ussd_no_msc_txt);
		return -1;
	}

	return complete_layer3(conn, msg, msc);
}

static int complete_layer3(struct gsm_subscriber_connection *conn,
			   struct msgb *msg, struct osmo_msc_data *msc)
{
	struct msgb *resp;
	uint16_t network_code;
	uint16_t country_code;
	enum bsc_con ret;

	/* allocate resource for a new connection */
	ret = bsc_create_new_connection(conn, msc);

	if (ret != BSC_CON_SUCCESS) {
		/* allocation has failed */
		if (ret == BSC_CON_REJECT_NO_LINK)
			bsc_send_ussd_notification(conn, msg, msc->ussd_msc_lost_txt);
		else if (ret == BSC_CON_REJECT_RF_GRACE)
			bsc_send_ussd_notification(conn, msg, msc->ussd_grace_txt);

		return BSC_API_CONN_POL_REJECT;
	}

	/* check return value, if failed check msg for and send USSD */

	network_code = get_network_code_for_msc(conn->sccp_con->msc);
	country_code = get_country_code_for_msc(conn->sccp_con->msc);

	bsc_scan_bts_msg(conn, msg);
	resp = gsm0808_create_layer3(msg, network_code, country_code,
				     conn->bts->location_area_code,
				     conn->bts->cell_identity);
	if (!resp) {
		LOGP(DMSC, LOGL_DEBUG, "Failed to create layer3 message.\n");
		sccp_connection_free(conn->sccp_con->sccp);
		bsc_delete_connection(conn->sccp_con);
		return BSC_API_CONN_POL_REJECT;
	}

	if (bsc_open_connection(conn->sccp_con, resp) != 0) {
		sccp_connection_free(conn->sccp_con->sccp);
		bsc_delete_connection(conn->sccp_con);
		msgb_free(resp);
		return BSC_API_CONN_POL_REJECT;
	}

	return BSC_API_CONN_POL_ACCEPT;
}

/*
 * Plastic surgery... we want to give up the current connection
 */
static int move_to_msc(struct gsm_subscriber_connection *_conn,
		       struct msgb *msg, struct osmo_msc_data *msc)
{
	struct osmo_bsc_sccp_con *old_con = _conn->sccp_con;

	/*
	 * 1. Give up the old connection.
	 * This happens by sending a clear request to the MSC,
	 * it should end with the MSC releasing the connection.
	 */
	old_con->conn = NULL;
	bsc_clear_request(_conn, 0);

	/*
	 * 2. Attempt to create a new connection to the local
	 * MSC. If it fails the caller will need to handle this
	 * properly.
	 */
	_conn->sccp_con = NULL;
	if (complete_layer3(_conn, msg, msc) != BSC_API_CONN_POL_ACCEPT) {
		gsm0808_clear(_conn);
		subscr_con_free(_conn);
		return 1;
	}

	return 2;
}

static int handle_cc_setup(struct gsm_subscriber_connection *conn,
			   struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	uint8_t pdisc = gh->proto_discr & 0x0f;
	uint8_t mtype = gh->msg_type & 0xbf;

	struct osmo_msc_data *msc;
	struct gsm_mncc_number called;
	struct tlv_parsed tp;
	unsigned payload_len;

	char _dest_nr[35];

	/*
	 * Do we have a setup message here? if not return fast.
	 */
	if (pdisc != GSM48_PDISC_CC || mtype != GSM48_MT_CC_SETUP)
		return 0;

	payload_len = msgb_l3len(msg) - sizeof(*gh);

	tlv_parse(&tp, &gsm48_att_tlvdef, gh->data, payload_len, 0, 0);
	if (!TLVP_PRESENT(&tp, GSM48_IE_CALLED_BCD)) {
		LOGP(DMSC, LOGL_ERROR, "Called BCD not present in setup.\n");
		return -1;
	}

	memset(&called, 0, sizeof(called));
	gsm48_decode_called(&called,
			    TLVP_VAL(&tp, GSM48_IE_CALLED_BCD) - 1);

	if (called.plan != 1 && called.plan != 0)
		return 0;

	if (called.plan == 1 && called.type == 1) {
		_dest_nr[0] = _dest_nr[1] = '0';
		memcpy(_dest_nr + 2, called.number, sizeof(called.number));
	} else
		memcpy(_dest_nr, called.number, sizeof(called.number));

	/*
	 * Check if the connection should be moved...
	 */
	llist_for_each_entry(msc, &conn->bts->network->bsc_data->mscs, entry) {
		if (msc->type != MSC_CON_TYPE_LOCAL)
			continue;
		if (!msc->local_pref)
			continue;
		if (regexec(&msc->local_pref_reg, _dest_nr, 0, NULL, 0) != 0)
			continue;

		return move_to_msc(conn, msg, msc);
	}

	return 0;
}


static void bsc_dtap(struct gsm_subscriber_connection *conn, uint8_t link_id, struct msgb *msg)
{
	struct msgb *resp;
	return_when_not_connected(conn);

	LOGP(DMSC, LOGL_INFO, "Tx MSC DTAP LINK_ID=0x%02x\n", link_id);

	/*
	 * We might want to move this connection to a new MSC. Ask someone
	 * to handle it. If it was handled we will return.
	 */
	if (handle_cc_setup(conn, msg) >= 1)
		return;

	bsc_scan_bts_msg(conn, msg);


	resp = gsm0808_create_dtap(msg, link_id);
	queue_msg_or_return(resp);
}

static void bsc_assign_compl(struct gsm_subscriber_connection *conn, uint8_t rr_cause,
			     uint8_t chosen_channel, uint8_t encr_alg_id,
			     uint8_t speech_model)
{
	struct msgb *resp;
	return_when_not_connected(conn);

	LOGP(DMSC, LOGL_INFO, "Tx MSC ASSIGN COMPL\n");

	resp = gsm0808_create_assignment_completed(rr_cause, chosen_channel,
						   encr_alg_id, speech_model);
	queue_msg_or_return(resp);
}

static void bsc_assign_fail(struct gsm_subscriber_connection *conn,
			    uint8_t cause, uint8_t *rr_cause)
{
	struct msgb *resp;
	return_when_not_connected(conn);

	LOGP(DMSC, LOGL_INFO, "Tx MSC ASSIGN FAIL\n");

	resp = gsm0808_create_assignment_failure(cause, rr_cause);
	queue_msg_or_return(resp);
}

static int bsc_clear_request(struct gsm_subscriber_connection *conn, uint32_t cause)
{
	struct osmo_bsc_sccp_con *sccp;
	struct msgb *resp;
	return_when_not_connected_val(conn, 1);

	LOGP(DMSC, LOGL_INFO, "Tx MSC CLEAR REQUEST\n");

	/*
	 * Remove the connection from BSC<->SCCP part, the SCCP part
	 * will either be cleared by channel release or MSC disconnect
	 */
	sccp = conn->sccp_con;
	sccp->conn = NULL;
	conn->sccp_con = NULL;

	resp = gsm0808_create_clear_rqst(GSM0808_CAUSE_RADIO_INTERFACE_FAILURE);
	if (!resp) {
		LOGP(DMSC, LOGL_ERROR, "Failed to allocate response.\n");
		return 1;
	}

	bsc_queue_for_msc(sccp, resp);
	return 1;
}

static void bsc_cm_update(struct gsm_subscriber_connection *conn,
			  const uint8_t *cm2, uint8_t cm2_len,
			  const uint8_t *cm3, uint8_t cm3_len)
{
	struct msgb *resp;
	return_when_not_connected(conn);

	resp = gsm0808_create_classmark_update(cm2, cm2_len, cm3, cm3_len);

	queue_msg_or_return(resp);
}

static void bsc_mr_config(struct gsm_subscriber_connection *conn,
			  struct gsm48_multi_rate_conf *conf)
{
	struct osmo_msc_data *msc;

	if (!conn->sccp_con) {
		LOGP(DMSC, LOGL_ERROR,
		     "No msc data available on conn %p. Audio will be broken.\n",
		     conn);
		return;
	}

	msc = conn->sccp_con->msc;

	conf->ver = 1;
	conf->icmi = 1;

	/* maybe gcc see's it is copy of _one_ byte */
	conf->m4_75 = msc->amr_conf.m4_75;
	conf->m5_15 = msc->amr_conf.m5_15;
	conf->m5_90 = msc->amr_conf.m5_90;
	conf->m6_70 = msc->amr_conf.m6_70;
	conf->m7_40 = msc->amr_conf.m7_40;
	conf->m7_95 = msc->amr_conf.m7_95;
	conf->m10_2 = msc->amr_conf.m10_2;
	conf->m12_2 = msc->amr_conf.m12_2;
}

static struct bsc_api bsc_handler = {
	.sapi_n_reject = bsc_sapi_n_reject,
	.cipher_mode_compl = bsc_cipher_mode_compl,
	.compl_l3 = bsc_compl_l3,
	.dtap  = bsc_dtap,
	.assign_compl = bsc_assign_compl,
	.assign_fail = bsc_assign_fail,
	.clear_request = bsc_clear_request,
	.classmark_chg = bsc_cm_update,
	.mr_config = bsc_mr_config,
};

struct bsc_api *osmo_bsc_api()
{
	return &bsc_handler;
}
