/* Point-to-Point (PP) Short Message Service (SMS)
 * Support on Mobile Radio Interface
 * 3GPP TS 04.11 version 7.1.0 Release 1998 / ETSI TS 100 942 V7.1.0 */

/* (C) 2008 by Daniel Willmann <daniel@totalueberwachung.de>
 * (C) 2009 by Harald Welte <laforge@gnumonks.org>
 * (C) 2010 by Holger Hans Peter Freyther <zecke@selfish.org>
 * (C) 2010 by On-Waves
 * (C) 2011 by Andreas Eversberg <jolly@eversberg.eu>
 *
 * 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/>.
 *
 */

/* Notes on msg:
 *
 * Messages from lower layer are freed by lower layer.
 *
 * Messages to upper layer are freed after upper layer call returns, so upper
 * layer cannot use data after returning. Upper layer must not free the msg.
 *
 * This implies: Lower layer messages can be forwarded to upper layer.
 *
 * Upper layer messages are freed by lower layer, so they must not be freed
 * after calling lower layer.
 *
 *
 * Notes on release:
 *
 * Whenever the process returns to IDLE, the MM connection is released using
 * MMSMS-REL-REQ. It is allowed to destroy this process while processing
 * this message.
 *
 * There is an exception, if MMSMS-REL-IND is received from lower layer, the
 * process returns to IDLE without sending MMSMS-REL-REQ.
 *
 */

#include <string.h>
#include <inttypes.h>
#include <errno.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/timer.h>

#include <osmocom/gsm/gsm0411_utils.h>
#include <osmocom/gsm/gsm0411_smc.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>

static void cp_timer_expired(void *data);

#define MAX_SMS_RETRY 2

#define SMC_LOG_STR "SMC(%" PRIu64 ") "

/* init a new instance */
void gsm411_smc_init(struct gsm411_smc_inst *inst, uint64_t id, int network,
	int (*mn_recv) (struct gsm411_smc_inst *inst, int msg_type,
			struct msgb *msg),
	int (*mm_send) (struct gsm411_smc_inst *inst, int msg_type,
			struct msgb *msg, int cp_msg_type))
{
	memset(inst, 0, sizeof(*inst));
	inst->id = id;
	inst->network = network;
	inst->cp_max_retr = MAX_SMS_RETRY;
	inst->cp_tc1 = GSM411_TMR_TC1A_SEC / (inst->cp_max_retr + 1);
	inst->cp_state = GSM411_CPS_IDLE;
	inst->mn_recv = mn_recv;
	inst->mm_send = mm_send;

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "instance created for %s\n",
		inst->id, inst->network ? "network" : "mobile");
}

/* clear instance */
void gsm411_smc_clear(struct gsm411_smc_inst *inst)
{
	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "clearing instance\n", inst->id);

	osmo_timer_del(&inst->cp_timer);

	/* free stored msg */
	if (inst->cp_msg) {
		LOGP(DLSMS, LOGL_INFO,
			SMC_LOG_STR "dropping pending message\n", inst->id);
		msgb_free(inst->cp_msg);
		inst->cp_msg = NULL;
	}
}

const char *smc_state_names[] = {
	"IDLE",
	"MM_CONN_PENDING",
	"WAIT_CP_ACK",
	"MM_ESTABLISHED",
};

const struct value_string gsm411_cp_cause_strs[] = {
	{ GSM411_CP_CAUSE_NET_FAIL,	"Network Failure" },
	{ GSM411_CP_CAUSE_CONGESTION,	"Congestion" },
	{ GSM411_CP_CAUSE_INV_TRANS_ID,	"Invalid Transaction ID" },
	{ GSM411_CP_CAUSE_SEMANT_INC_MSG, "Semantically Incorrect Message" },
	{ GSM411_CP_CAUSE_INV_MAND_INF,	"Invalid Mandatory Information" },
	{ GSM411_CP_CAUSE_MSGTYPE_NOTEXIST, "Message Type doesn't exist" },
	{ GSM411_CP_CAUSE_MSG_INCOMP_STATE,
				"Message incompatible with protocol state" },
	{ GSM411_CP_CAUSE_IE_NOTEXIST,	"IE does not exist" },
	{ GSM411_CP_CAUSE_PROTOCOL_ERR,	"Protocol Error" },
	{ 0, 0 }
};

static void new_cp_state(struct gsm411_smc_inst *inst,
	enum gsm411_cp_state state)
{
	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "new CP state %s -> %s\n", inst->id,
		smc_state_names[inst->cp_state], smc_state_names[state]);
	inst->cp_state = state;
}

static int gsm411_tx_cp_error(struct gsm411_smc_inst *inst, uint8_t cause)
{
	struct msgb *nmsg = gsm411_msgb_alloc();
	uint8_t *causep;

	LOGP(DLSMS, LOGL_NOTICE,
		SMC_LOG_STR "TX CP-ERROR, cause %d (%s)\n", inst->id, cause,
		get_value_string(gsm411_cp_cause_strs, cause));

	causep = msgb_put(nmsg, 1);
	*causep = cause;

	return inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg,
		GSM411_MT_CP_ERROR);
}

/* establish SMC connection */
static int gsm411_mnsms_est_req(struct gsm411_smc_inst *inst, struct msgb *msg)
{
	struct msgb *nmsg;

	if (inst->cp_msg) {
		LOGP(DLSMS, LOGL_FATAL,
			SMC_LOG_STR "EST REQ, but we already have an "
			"cp_msg. This should never happen, please fix!\n",
			inst->id);
		msgb_free(inst->cp_msg);
	}

	inst->cp_msg = msg;
	new_cp_state(inst, GSM411_CPS_MM_CONN_PENDING);
	/* clear stored release flag */
	inst->cp_rel = 0;
	/* send MMSMS_EST_REQ */
	nmsg = gsm411_msgb_alloc();
	return inst->mm_send(inst, GSM411_MMSMS_EST_REQ, nmsg, 0);
}

static int gsm411_mmsms_send_msg(struct gsm411_smc_inst *inst)
{
	struct msgb *nmsg;

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "send CP data\n", inst->id);
	/* reset retry counter */
	if (inst->cp_state != GSM411_CPS_WAIT_CP_ACK)
		inst->cp_retx = 0;
	/* 5.2.3.1.2: enter MO-wait for CP-ACK */
	/* 5.2.3.2.3: enter MT-wait for CP-ACK */
	new_cp_state(inst, GSM411_CPS_WAIT_CP_ACK);
	inst->cp_timer.data = inst;
	inst->cp_timer.cb = cp_timer_expired;
	/* 5.3.2.1: Set Timer TC1A */
	osmo_timer_schedule(&inst->cp_timer, inst->cp_tc1, 0);
	/* clone cp_msg */
	nmsg = gsm411_msgb_alloc();
	memcpy(msgb_put(nmsg, inst->cp_msg->len), inst->cp_msg->data,
		inst->cp_msg->len);
	/* send MMSMS_DATA_REQ with CP-DATA */
	return inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg,
				GSM411_MT_CP_DATA);
}

static int gsm411_mmsms_est_cnf(struct gsm411_smc_inst *inst, struct msgb *msg)
{
	if (!inst->cp_msg) {
		LOGP(DLSMS, LOGL_FATAL,
			SMC_LOG_STR "EST CNF, but we have no cp_msg. This "
			"should never happen, please fix!\n",
			inst->id);
		return -EINVAL;
	}

	return gsm411_mmsms_send_msg(inst);
}

/* SMC TC1* is expired */
static void cp_timer_expired(void *data)
{
	struct gsm411_smc_inst *inst = data;
	struct msgb *nmsg;

	if (inst->cp_retx == inst->cp_max_retr) {

		LOGP(DLSMS, LOGL_INFO,
			SMC_LOG_STR "TC1* timeout, no more retries.\n",
			inst->id);
		/* 5.3.2.1: enter idle state */
		new_cp_state(inst, GSM411_CPS_IDLE);
		/* indicate error */
		nmsg = gsm411_msgb_alloc();
		inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
		msgb_free(nmsg);
		/* free pending stored msg */
		if (inst->cp_msg) {
			msgb_free(inst->cp_msg);
			inst->cp_msg = NULL;
		}
		/* release MM connection */
		nmsg = gsm411_msgb_alloc();
		inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
		return;
	}

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "TC1* timeout, retrying...\n", inst->id);
	inst->cp_retx++;
	gsm411_mmsms_est_cnf(inst, NULL);
}

static int gsm411_mmsms_cp_ack(struct gsm411_smc_inst *inst, struct msgb *msg)
{
	/* free stored msg */
	if (inst->cp_msg) {
		msgb_free(inst->cp_msg);
		inst->cp_msg = NULL;
	}

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "received CP-ACK\n", inst->id);
	/* 5.3.2.1 enter MM Connection established */
	new_cp_state(inst, GSM411_CPS_MM_ESTABLISHED);
	/* 5.3.2.1: Reset Timer TC1* */
	osmo_timer_del(&inst->cp_timer);

	/* pending release? */
	if (inst->cp_rel) {
		struct msgb *nmsg;

		LOGP(DLSMS, LOGL_INFO,
			SMC_LOG_STR "we have pending release.\n",
			inst->id);
		new_cp_state(inst, GSM411_CPS_IDLE);
		/* release MM connection */
		nmsg = gsm411_msgb_alloc();
		return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
	}

	return 0;
}

static int gsm411_mmsms_cp_data(struct gsm411_smc_inst *inst, struct msgb *msg)
{
	struct msgb *nmsg;
	int mt = GSM411_MNSMS_DATA_IND;

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "received CP-DATA\n", inst->id);
	/* 5.3.1 enter MM Connection established (if idle) */
	if (inst->cp_state == GSM411_CPS_IDLE) {
		new_cp_state(inst, GSM411_CPS_MM_ESTABLISHED);
		mt = GSM411_MNSMS_EST_IND;
		/* clear stored release flag */
		inst->cp_rel = 0;
	}
	/* send MMSMS_DATA_REQ (CP ACK) */
	nmsg = gsm411_msgb_alloc();
	inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, nmsg, GSM411_MT_CP_ACK);
	/* indicate data */
	inst->mn_recv(inst, mt, msg);

	return 0;
}

/* send CP DATA */
static int gsm411_mnsms_data_req(struct gsm411_smc_inst *inst, struct msgb *msg)
{
	if (inst->cp_msg) {
		LOGP(DLSMS, LOGL_FATAL,
			SMC_LOG_STR "DATA REQ, but we already have an "
			"cp_msg. This should never happen, please fix!\n",
			inst->id);
		msgb_free(inst->cp_msg);
	}

	/* store and send */
	inst->cp_msg = msg;
	return gsm411_mmsms_send_msg(inst);
}

/* release SMC connection */
static int gsm411_mnsms_rel_req(struct gsm411_smc_inst *inst, struct msgb *msg)
{
	struct msgb *nmsg;

	msgb_free(msg);

	/* discard silently */
	if (inst->cp_state == GSM411_CPS_IDLE)
		return 0;

	/* store release, until established or released */
	if (inst->cp_state != GSM411_CPS_MM_ESTABLISHED) {
		LOGP(DLSMS, LOGL_NOTICE,
			SMC_LOG_STR "cannot release yet current state: %s\n",
			inst->id, smc_state_names[inst->cp_state]);
		inst->cp_rel = 1;
		return 0;
	}

	/* free stored msg */
	if (inst->cp_msg) {
		msgb_free(inst->cp_msg);
		inst->cp_msg = NULL;
	}

	new_cp_state(inst, GSM411_CPS_IDLE);
	/* release MM connection */
	nmsg = gsm411_msgb_alloc();
	return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
}

static int gsm411_mmsms_cp_error(struct gsm411_smc_inst *inst, struct msgb *msg)
{
	struct msgb *nmsg;

	/* free stored msg */
	if (inst->cp_msg) {
		msgb_free(inst->cp_msg);
		inst->cp_msg = NULL;
	}

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "received CP-ERROR\n", inst->id);
	/* 5.3.4 enter idle */
	new_cp_state(inst, GSM411_CPS_IDLE);
	/* indicate error */
	inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, msg);
	/* release MM connection */
	nmsg = gsm411_msgb_alloc();
	return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
}

static int gsm411_mmsms_rel_ind(struct gsm411_smc_inst *inst, struct msgb *msg)
{
	struct msgb *nmsg;

	/* free stored msg */
	if (inst->cp_msg) {
		msgb_free(inst->cp_msg);
		inst->cp_msg = NULL;
	}

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "MM layer is released\n", inst->id);
	/* 5.3.4 enter idle */
	new_cp_state(inst, GSM411_CPS_IDLE);
	/* indicate error */
	nmsg = gsm411_msgb_alloc();
	inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
	msgb_free(nmsg);

	return 0;
}

/* abort SMC connection */
static int gsm411_mnsms_abort_req(struct gsm411_smc_inst *inst,
	struct msgb *msg)
{
	struct msgb *nmsg;

	/* free stored msg */
	if (inst->cp_msg) {
		msgb_free(inst->cp_msg);
		inst->cp_msg = NULL;
	}

	/* 5.3.4 go idle */
	new_cp_state(inst, GSM411_CPS_IDLE);
	/* send MMSMS_DATA_REQ with CP-ERROR */
	inst->mm_send(inst, GSM411_MMSMS_DATA_REQ, msg, GSM411_MT_CP_ERROR);
	/* release MM connection */
	nmsg = gsm411_msgb_alloc();
	return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg, 0);
}

/* statefull handling for MNSMS SAP messages */
static const struct smcdownstate {
	uint32_t	states;
	int		type;
	const char 	*name;
	int		(*rout) (struct gsm411_smc_inst *inst,
					struct msgb *msg);
} smcdownstatelist[] = {
	/* establish request */
	{SBIT(GSM411_CPS_IDLE),
	GSM411_MNSMS_EST_REQ,
	 "MNSMS-EST-REQ", gsm411_mnsms_est_req},

	/* release request */
	{ALL_STATES,
	GSM411_MNSMS_REL_REQ,
	 "MNSMS-REL-REQ", gsm411_mnsms_rel_req},

	/* data request */
	{SBIT(GSM411_CPS_MM_ESTABLISHED),
	GSM411_MNSMS_DATA_REQ,
	 "MNSMS-DATA-REQ", gsm411_mnsms_data_req},

	/* abort request */
	{ALL_STATES - SBIT(GSM411_CPS_IDLE),
	GSM411_MNSMS_ABORT_REQ,
	 "MNSMS-ABORT-REQ", gsm411_mnsms_abort_req},
};

#define SMCDOWNSLLEN \
	(sizeof(smcdownstatelist) / sizeof(struct smcdownstate))

/* message from upper layer */
int gsm411_smc_send(struct gsm411_smc_inst *inst, int msg_type,
	struct msgb *msg)
{
	int i, rc;

	/* find function for current state and message */
	for (i = 0; i < SMCDOWNSLLEN; i++) {
		if ((msg_type == smcdownstatelist[i].type)
		  && (SBIT(inst->cp_state) & smcdownstatelist[i].states))
				break;
	}
	if (i == SMCDOWNSLLEN) {
		LOGP(DLSMS, LOGL_NOTICE,
			SMC_LOG_STR "message %u unhandled at this state %s.\n",
			inst->id, msg_type, smc_state_names[inst->cp_state]);
		msgb_free(msg);
		return 0;
	}

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "message %s received in state %s\n", inst->id,
		smcdownstatelist[i].name, smc_state_names[inst->cp_state]);

	rc = smcdownstatelist[i].rout(inst, msg);

	return rc;
}

/* statefull handling for MMSMS SAP messages */
static const struct smcdatastate {
	uint32_t	states;
	int		type, cp_type;
	const char 	*name;
	int		(*rout) (struct gsm411_smc_inst *inst,
					struct msgb *msg);
} smcdatastatelist[] = {
	/* establish confirm */
	{SBIT(GSM411_CPS_MM_CONN_PENDING),
	 GSM411_MMSMS_EST_CNF, 0,
	 "MMSMS-EST-CNF", gsm411_mmsms_est_cnf},

	/* establish indication (CP DATA) */
	{SBIT(GSM411_CPS_IDLE),
	 GSM411_MMSMS_EST_IND, GSM411_MT_CP_DATA,
	 "MMSMS-EST-IND (CP DATA)", gsm411_mmsms_cp_data},

	/* data indication (CP DATA) */
	{SBIT(GSM411_CPS_MM_ESTABLISHED),
	 GSM411_MMSMS_DATA_IND, GSM411_MT_CP_DATA,
	 "MMSMS-DATA-IND (CP DATA)", gsm411_mmsms_cp_data},

	/* data indication (CP ACK) */
	{SBIT(GSM411_CPS_WAIT_CP_ACK),
	 GSM411_MMSMS_DATA_IND, GSM411_MT_CP_ACK,
	 "MMSMS-DATA-IND (CP ACK)", gsm411_mmsms_cp_ack},

	/* data indication (CP ERROR) */
	{ALL_STATES,
	 GSM411_MMSMS_DATA_IND, GSM411_MT_CP_ERROR,
	 "MMSMS-DATA-IND (CP_ERROR)", gsm411_mmsms_cp_error},

	/* release indication */
	{ALL_STATES - SBIT(GSM411_CPS_IDLE),
	 GSM411_MMSMS_REL_IND, 0,
	 "MMSMS-REL-IND", gsm411_mmsms_rel_ind},

};

#define SMCDATASLLEN \
	(sizeof(smcdatastatelist) / sizeof(struct smcdatastate))

/* message from lower layer
 * WARNING: We must not free msg, since it will be performed by the
 * lower layer. */
int gsm411_smc_recv(struct gsm411_smc_inst *inst, int msg_type,
	struct msgb *msg, int cp_msg_type)
{
	int i, rc;

	/* find function for current state and message */
	for (i = 0; i < SMCDATASLLEN; i++) {
		/* state must match, MM message must match
		 * CP msg must match only in case of MMSMS_DATA_IND
		 */
		if ((msg_type == smcdatastatelist[i].type)
		  && (SBIT(inst->cp_state) & smcdatastatelist[i].states)
		  && (msg_type != GSM411_MMSMS_DATA_IND
		   || cp_msg_type == smcdatastatelist[i].cp_type))
				break;
	}
	if (i == SMCDATASLLEN) {
		LOGP(DLSMS, LOGL_NOTICE,
			SMC_LOG_STR "message 0x%x/%u unhandled at this "
			"state %s.\n", inst->id, msg_type, cp_msg_type,
			smc_state_names[inst->cp_state]);
		if (msg_type == GSM411_MMSMS_EST_IND
		 || msg_type == GSM411_MMSMS_DATA_IND) {
			struct msgb *nmsg;

			LOGP(DLSMS, LOGL_NOTICE,
				SMC_LOG_STR "RX Unimplemented CP "
				"msg_type: 0x%02x\n", inst->id, msg_type);
			/* 5.3.4 enter idle */
			new_cp_state(inst, GSM411_CPS_IDLE);
			/* indicate error */
			gsm411_tx_cp_error(inst,
				GSM411_CP_CAUSE_MSGTYPE_NOTEXIST);
			/* send error indication to upper layer */
			nmsg = gsm411_msgb_alloc();
			inst->mn_recv(inst, GSM411_MNSMS_ERROR_IND, nmsg);
			msgb_free(nmsg);
			/* release MM connection */
			nmsg = gsm411_msgb_alloc();
			return inst->mm_send(inst, GSM411_MMSMS_REL_REQ, nmsg,
						0);
		}
		return 0;
	}

	LOGP(DLSMS, LOGL_INFO,
		SMC_LOG_STR "message %s received in state %s\n", inst->id,
		smcdatastatelist[i].name, smc_state_names[inst->cp_state]);

	rc = smcdatastatelist[i].rout(inst, msg);

	return rc;
}
