/* 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-2012 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/>.
 *
 */


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <netinet/in.h>

#include "config.h"

#include <osmocom/core/msgb.h>
#include <osmocom/core/talloc.h>
#include <osmocom/core/utils.h>

#include <osmocom/gsm/gsm_utils.h>
#include <osmocom/gsm/gsm0411_utils.h>
#include <osmocom/gsm/protocol/gsm_04_11.h>
#include <osmocom/gsm/protocol/gsm_03_40.h>

#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/db.h>
#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/gsm_04_08.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/db.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/vlr.h>
#include <osmocom/msc/msub.h>
#include <osmocom/msc/msc_a.h>
#include <osmocom/msc/paging.h>

#ifdef BUILD_SMPP
#include "smpp_smsc.h"
#endif

void *tall_gsms_ctx;
static uint32_t new_callref = 0x40000001;

struct gsm_sms *sms_alloc(void)
{
	return talloc_zero(tall_gsms_ctx, struct gsm_sms);
}

void sms_free(struct gsm_sms *sms)
{
	/* drop references to subscriber structure */
	if (sms->receiver)
		vlr_subscr_put(sms->receiver, VSUB_USE_SMS_RECEIVER);
#ifdef BUILD_SMPP
	if (sms->smpp.esme)
		smpp_esme_put(sms->smpp.esme);
#endif

	talloc_free(sms);
}

struct gsm_sms *sms_from_text(struct vlr_subscr *receiver,
			      const char *sender_msisdn,
                              int dcs, const char *text)
{
	struct gsm_sms *sms = sms_alloc();

	if (!sms)
		return NULL;

	vlr_subscr_get(receiver, VSUB_USE_SMS_RECEIVER);
	sms->receiver = receiver;
	OSMO_STRLCPY_ARRAY(sms->text, text);

	OSMO_STRLCPY_ARRAY(sms->src.addr, sender_msisdn);
	sms->reply_path_req = 0;
	sms->status_rep_req = 0;
	sms->ud_hdr_ind = 0;
	sms->protocol_id = 0; /* implicit */
	sms->data_coding_scheme = dcs;
	OSMO_STRLCPY_ARRAY(sms->dst.addr, receiver->msisdn);
	/* Generate user_data */
	sms->user_data_len = gsm_7bit_encode_n(sms->user_data, sizeof(sms->user_data),
						sms->text, NULL);

	return sms;
}


static void send_signal(int sig_no,
			struct gsm_trans *trans,
			struct gsm_sms *sms,
			int paging_result)
{
	struct sms_signal_data sig;
	sig.trans = trans;
	sig.sms = sms;
	sig.paging_result = paging_result;
	osmo_signal_dispatch(SS_SMS, sig_no, &sig);
}

static int gsm411_sendmsg(struct gsm_trans *trans, struct msgb *msg)
{
	LOG_TRANS(trans, LOGL_DEBUG, "GSM4.11 TX %s\n", msgb_hexdump(msg));
	msg->l3h = msg->data;
	return msc_a_tx_dtap_to_i(trans->msc_a, msg);
}

/* Handle MMTS (More Messages to Send) indication */
static void gsm411_handle_mmts_ind(const struct gsm_trans *trans)
{
	int32_t use_count;

	OSMO_ASSERT(trans);
	OSMO_ASSERT(trans->msc_a);

	use_count = osmo_use_count_by(&trans->msc_a->use_count, MSC_A_USE_SMS_MMTS);
	OSMO_ASSERT(use_count >= 0); /* Shall not be negative */

	if (trans->sms.sm_rp_mmts_ind && use_count == 0) {
		LOG_TRANS(trans, LOGL_INFO, "Multi-part SMS delivery is initiated\n");
		msc_a_get(trans->msc_a, MSC_A_USE_SMS_MMTS);
	} else if (trans->sms.sm_rp_mmts_ind && use_count > 0) {
		LOG_TRANS(trans, LOGL_INFO, "Continuing multi-part SMS delivery\n");
	} else if (!trans->sms.sm_rp_mmts_ind && use_count > 0) {
		LOG_TRANS(trans, LOGL_INFO, "Multi-part SMS delivery has been completed\n");
		msc_a_put(trans->msc_a, MSC_A_USE_SMS_MMTS);
	}
}

/* Paging callback for MT SMS (Paging is triggered by SMC) */
static void mmsms_paging_cb(struct msc_a *msc_a, struct gsm_trans *trans)
{
	struct gsm_sms *sms = trans->sms.sms;

	LOG_TRANS(trans, LOGL_DEBUG, "%s(%s)\n", __func__, msc_a ? "success" : "expired");

	if (msc_a) {
		/* Paging succeeded */
		/* Associate transaction with established connection */
		msc_a_get(msc_a, MSC_A_USE_SMS);
		trans->msc_a = msc_a;

		/* Multi-part SMS: handle MMTS (More Messages to Send) indication */
		gsm411_handle_mmts_ind(trans);

		/* Confirm successful connection establishment */
		gsm411_smc_recv(&trans->sms.smc_inst, GSM411_MMSMS_EST_CNF, NULL, 0);
	} else {
		/* Paging expired or failed */
		/* Inform SMC about channel establishment failure */
		gsm411_smc_recv(&trans->sms.smc_inst, GSM411_MMSMS_REL_IND, NULL, 0);

		/* gsm411_send_rp_data() doesn't set trans->sms.sms */
		if (sms != NULL) {
			/* Notify the SMSqueue and free stored SMS */
			send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, 0);
			trans->sms.sms = NULL;
			sms_free(sms);
		}

		/* Destroy this transaction */
		trans_free(trans);
	}
}

static int gsm411_mmsms_est_req(struct gsm_trans *trans)
{
	/* Subscriber's data shall be associated */
	OSMO_ASSERT(trans->vsub != NULL);

	/* Check if connection is already established */
	if (trans->msc_a != NULL) {
		LOG_TRANS(trans, LOGL_DEBUG, "Using an existing connection\n");
		return gsm411_smc_recv(&trans->sms.smc_inst,
			GSM411_MMSMS_EST_CNF, NULL, 0);
	}

	/* Initiate Paging procedure */
	LOG_TRANS(trans, LOGL_DEBUG, "Initiating Paging due to MMSMS_EST_REQ\n");
	trans->paging_request = paging_request_start(trans->vsub, PAGING_CAUSE_SIGNALLING_LOW_PRIO,
						     mmsms_paging_cb, trans, "MT-SMS");
	if (!trans->paging_request) {
		LOG_TRANS(trans, LOGL_ERROR, "Failed to initiate Paging\n");
		/* Inform SMC about channel establishment failure */
		gsm411_smc_recv(&trans->sms.smc_inst, GSM411_MMSMS_REL_IND, NULL, 0);
		trans_free(trans);
		return -EIO;
	}

	return 0;
}

/* Prefix msg with a 04.08/04.11 CP header */
static int gsm411_cp_sendmsg(struct msgb *msg, struct gsm_trans *trans,
			     uint8_t msg_type)
{
	struct gsm48_hdr *gh;

	gh = (struct gsm48_hdr *) msgb_push(msg, sizeof(*gh));
	/* Outgoing needs the highest bit set */
	gh->proto_discr = GSM48_PDISC_SMS | (trans->transaction_id<<4);
	gh->msg_type = msg_type;
	OMSC_LINKID_CB(msg) = trans->dlci;

	LOG_TRANS(trans, LOGL_DEBUG, "sending CP message (trans=%x)\n", trans->transaction_id);

	return gsm411_sendmsg(trans, msg);
}

/* mm_send: receive MMCCSMS sap message from SMC */
static int gsm411_mm_send(struct gsm411_smc_inst *inst, int msg_type,
			struct msgb *msg, int cp_msg_type)
{
	struct gsm_trans *trans =
		container_of(inst, struct gsm_trans, sms.smc_inst);
	int rc = 0;

	switch (msg_type) {
	case GSM411_MMSMS_EST_REQ:
		rc = gsm411_mmsms_est_req(trans);
		break;
	case GSM411_MMSMS_DATA_REQ:
		rc = gsm411_cp_sendmsg(msg, trans, cp_msg_type);
		return rc; /* gsm411_cp_sendmsg() takes msg ownership */
	case GSM411_MMSMS_REL_REQ:
		LOG_TRANS(trans, LOGL_DEBUG, "Got MMSMS_REL_REQ, destroying transaction.\n");
		trans_free(trans);
		break;
	default:
		LOG_TRANS(trans, LOGL_NOTICE, "Unhandled MMCCSMS msg 0x%x\n", msg_type);
		rc = -EINVAL;
	}

	msgb_free(msg);
	return rc;
}

/* mm_send: receive MNCCSMS sap message from SMR */
int gsm411_mn_send(struct gsm411_smr_inst *inst, int msg_type,
			struct msgb *msg)
{
	struct gsm_trans *trans =
		container_of(inst, struct gsm_trans, sms.smr_inst);

	/* forward to SMC */
	return gsm411_smc_send(&trans->sms.smc_inst, msg_type, msg);
}

static int gsm340_rx_sms_submit(struct gsm_trans *trans, struct gsm_sms *gsms)
{
	if (db_sms_store(gsms) != 0) {
		LOG_TRANS(trans, LOGL_ERROR, "Failed to store SMS in Database\n");
		return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
	}
	/* dispatch a signal to tell higher level about it */
	send_signal(S_SMS_SUBMITTED, NULL, gsms, 0);

	return 0;
}

/* generate a TPDU address field compliant with 03.40 sec. 9.1.2.5 */
static int gsm340_gen_oa_sub(uint8_t *oa, unsigned int oa_len,
			 const struct gsm_sms_addr *src)
{
	/* network specific, private numbering plan */
	return gsm340_gen_oa(oa, oa_len, src->ton, src->npi, src->addr);
}

/* generate a msgb containing an 03.40 9.2.2.1 SMS-DELIVER TPDU derived from
 * struct gsm_sms, returns total size of TPDU */
static int gsm340_gen_sms_deliver_tpdu(struct gsm_trans *trans, struct msgb *msg, struct gsm_sms *sms)
{
	uint8_t *smsp;
	uint8_t oa[12];	/* max len per 03.40 */
	uint8_t octet_len;
	unsigned int old_msg_len = msg->len;
	int oa_len;

	/* generate first octet with masked bits */
	smsp = msgb_put(msg, 1);
	/* TP-MTI (message type indicator) */
	*smsp = GSM340_SMS_DELIVER_SC2MS;
	/* TP-MMS (more messages to send) */
	if (0 /* FIXME */)
		*smsp |= 0x04;
	/* TP-SRI(deliver)/SRR(submit) */
	if (sms->status_rep_req)
		*smsp |= 0x20;
	/* TP-UDHI (indicating TP-UD contains a header) */
	if (sms->ud_hdr_ind)
		*smsp |= 0x40;

	/* generate originator address */
	oa_len = gsm340_gen_oa_sub(oa, sizeof(oa), &sms->src);
	if (oa_len < 0)
		return -ENOSPC;

	smsp = msgb_put(msg, oa_len);
	memcpy(smsp, oa, oa_len);

	/* generate TP-PID */
	smsp = msgb_put(msg, 1);
	*smsp = sms->protocol_id;

	/* generate TP-DCS */
	smsp = msgb_put(msg, 1);
	*smsp = sms->data_coding_scheme;

	/* generate TP-SCTS */
	smsp = msgb_put(msg, 7);
	gsm340_gen_scts(smsp, time(NULL));

	/* generate TP-UDL */
	smsp = msgb_put(msg, 1);
	*smsp = sms->user_data_len;

	/* generate TP-UD */
	switch (gsm338_get_sms_alphabet(sms->data_coding_scheme)) {
	case DCS_7BIT_DEFAULT:
		octet_len = sms->user_data_len*7/8;
		if (sms->user_data_len*7%8 != 0)
			octet_len++;
		/* Warning, user_data_len indicates the amount of septets
		 * (characters), we need amount of octets occupied */
		smsp = msgb_put(msg, octet_len);
		memcpy(smsp, sms->user_data, octet_len);
		break;
	case DCS_UCS2:
	case DCS_8BIT_DATA:
		smsp = msgb_put(msg, sms->user_data_len);
		memcpy(smsp, sms->user_data, sms->user_data_len);
		break;
	default:
		LOG_TRANS(trans, LOGL_NOTICE, "Unhandled Data Coding Scheme: 0x%02X\n",
			  sms->data_coding_scheme);
		break;
	}

	return msg->len - old_msg_len;
}

/* As defined by GSM 03.40, Section 9.2.2.3. */
static int gsm340_gen_sms_status_report_tpdu(struct gsm_trans *trans, struct msgb *msg,
					     struct gsm_sms *sms)
{
	unsigned int old_msg_len = msg->len;
	uint8_t oa[12];	/* max len per 03.40 */
	uint8_t *smsp;
	int oa_len;

	/* generate first octet with masked bits */
	smsp = msgb_put(msg, 1);
	/* TP-MTI (message type indicator) */
	*smsp = GSM340_SMS_STATUS_REP_SC2MS;
	/* TP-MMS (more messages to send) */
	if (0 /* FIXME */)
		*smsp |= 0x04;
	/* TP-MR (message reference) */
	smsp = msgb_put(msg, 1);
	*smsp = sms->msg_ref;

	/* generate recipient address */
	oa_len = gsm340_gen_oa_sub(oa, sizeof(oa), &sms->src);
	if (oa_len < 0)
		return -ENOSPC;

	smsp = msgb_put(msg, oa_len);
	memcpy(smsp, oa, oa_len);

	/* generate TP-SCTS (Service centre timestamp) */
	smsp = msgb_put(msg, 7);
	gsm340_gen_scts(smsp, sms->created);

	/* generate TP-DT (Discharge time, in TP-SCTS format). */
	smsp = msgb_put(msg, 7);
	gsm340_gen_scts(smsp, sms->created);

	/* TP-ST (status) */
	smsp = msgb_put(msg, 1);
	/* From GSM 03.40, Section 9.2.3.15, 0x00 means OK. */
	*smsp = 0x00;

	LOG_TRANS(trans, LOGL_INFO, "sending status report for SMS reference %x\n",
		  sms->msg_ref);

	return msg->len - old_msg_len;
}

static int sms_route_mt_sms(struct gsm_trans *trans, struct gsm_sms *gsms)
{
	int rc;
	struct msc_a *msc_a = trans->msc_a;
	struct gsm_network *net = msc_a_net(msc_a);

#ifdef BUILD_SMPP
	/*
	 * Route through SMPP first before going to the local database. In case
	 * of a unroutable message and no local subscriber, SMPP will be tried
	 * twice. In case of an unknown subscriber continue with the normal
	 * delivery of the SMS.
	 */
	if (smpp_route_smpp_first()) {
		rc = smpp_try_deliver(gsms, msc_a);
		if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED)
			/* unknown subscriber, try local */
			goto try_local;
		if (rc < 0) {
			LOG_TRANS(trans, LOGL_ERROR, "SMS delivery error: %d\n", rc);
	 		rc = GSM411_RP_CAUSE_MO_TEMP_FAIL;
			/* rc will be logged by gsm411_send_rp_error() */
			rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR));
		}
		return rc;
	}

try_local:
#endif

	/* determine gsms->receiver based on dialled number */
	gsms->receiver = vlr_subscr_find_by_msisdn(net->vlr, gsms->dst.addr, VSUB_USE_SMS_RECEIVER);
	if (gsms->receiver)
		return 0;

#ifdef BUILD_SMPP
	/* Avoid a second look-up */
	if (smpp_route_smpp_first()) {
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER));
		return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
	}

	rc = smpp_try_deliver(gsms, msc_a);
	if (rc == GSM411_RP_CAUSE_MO_NUM_UNASSIGNED) {
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER));
	} else if (rc < 0) {
		LOG_TRANS(trans, LOGL_ERROR, "SMS delivery error: %d\n", rc);
		rc = GSM411_RP_CAUSE_MO_TEMP_FAIL;
		/* rc will be logged by gsm411_send_rp_error() */
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR));
	}
#else
	rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
	rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_NO_RECEIVER));
#endif

	return rc;
}


/* process an incoming TPDU (called from RP-DATA)
 * return value > 0: RP CAUSE for ERROR; < 0: silent error; 0 = success */
static int gsm340_rx_tpdu(struct gsm_trans *trans, struct msgb *msg,
			  uint32_t gsm411_msg_ref)
{
	uint8_t *smsp = msgb_sms(msg);
	struct gsm_sms *gsms;
	unsigned int sms_alphabet;
	uint8_t sms_mti, sms_vpf;
	uint8_t *sms_vp;
	uint8_t da_len_bytes;
	uint8_t address_lv[12]; /* according to 03.40 / 9.1.2.5 */
	int rc = 0;
	struct gsm_network *net;
	struct vlr_subscr *vsub;

	if (!trans->msc_a) {
		LOG_TRANS(trans, LOGL_ERROR, "Insufficient info to process TPDU: "
					     "MSC-A role is NULL?!?\n");
		return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
	}

	net = msc_a_net(trans->msc_a);
	vsub = msc_a_vsub(trans->msc_a);
	if (!net || !vsub) {
		LOG_TRANS(trans, LOGL_ERROR, "Insufficient info to process TPDU: "
					     "gsm_network and/or vlr_subscr is NULL?!?\n");
		return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
	}

	/* FIXME: should we do this on success, after all checks? */
	rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_SUBMITTED));

	gsms = sms_alloc();
	if (!gsms)
		return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;

	/* invert those fields where 0 means active/present */
	sms_mti = *smsp & 0x03;
	sms_vpf = (*smsp & 0x18) >> 3;
	gsms->status_rep_req = (*smsp & 0x20) >> 5;
	gsms->ud_hdr_ind = (*smsp & 0x40);
	/*
	 * Not evaluating MMS (More Messages to Send) because the
	 * lchan stays open anyway.
	 * Not evaluating RP (Reply Path) because we're not aware of its
	 * benefits.
	 */

	smsp++;
	gsms->msg_ref = *smsp++;

	gsms->gsm411.transaction_id = trans->transaction_id;
	gsms->gsm411.msg_ref = gsm411_msg_ref;

	/* length in bytes of the destination address */
	da_len_bytes = 2 + *smsp/2 + *smsp%2;
	if (da_len_bytes > 12) {
		LOG_TRANS(trans, LOGL_ERROR, "Destination Address > 12 bytes ?!?\n");
		rc = GSM411_RP_CAUSE_SEMANT_INC_MSG;
		goto out;
	} else if (da_len_bytes < 4) {
		LOG_TRANS(trans, LOGL_ERROR, "Destination Address < 4 bytes ?!?\n");
		rc = GSM411_RP_CAUSE_SEMANT_INC_MSG;
		goto out;
	}
	memset(address_lv, 0, sizeof(address_lv));
	memcpy(address_lv, smsp, da_len_bytes);
	/* mangle first byte to reflect length in bytes, not digits */
	address_lv[0] = da_len_bytes - 1;

	gsms->dst.ton = (address_lv[1] >> 4) & 7;
	gsms->dst.npi = address_lv[1] & 0xF;
	/* convert to real number */
	if (gsm48_decode_bcd_number2(gsms->dst.addr,
				     sizeof(gsms->dst.addr), address_lv, da_len_bytes, 1)) {
		LOG_TRANS(trans, LOGL_ERROR, "Failed to decode destination Address\n");
		rc = GSM411_RP_CAUSE_SEMANT_INC_MSG;
		goto out;
	}
	smsp += da_len_bytes;

	gsms->protocol_id = *smsp++;
	gsms->data_coding_scheme = *smsp++;

	sms_alphabet = gsm338_get_sms_alphabet(gsms->data_coding_scheme);
	if (sms_alphabet == 0xffffffff) {
		rc = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
		goto out;
	}

	switch (sms_vpf) {
	case GSM340_TP_VPF_RELATIVE:
		sms_vp = smsp++;
		break;
	case GSM340_TP_VPF_ABSOLUTE:
	case GSM340_TP_VPF_ENHANCED:
		sms_vp = smsp;
		/* the additional functionality indicator... */
		if (sms_vpf == GSM340_TP_VPF_ENHANCED && *smsp & (1<<7))
			smsp++;
		smsp += 7;
		break;
	case GSM340_TP_VPF_NONE:
		sms_vp = 0;
		break;
	default:
		LOG_TRANS(trans, LOGL_NOTICE, "SMS Validity period not implemented: 0x%02x\n", sms_vpf);
		rc = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
		goto out;
	}

	/* As per 3GPP TS 03.40, section 9.2.3.16, TP-User-Data-Length (TP-UDL)
	 * may indicate either the number of septets, or the number of octets,
	 * depending on Data Coding Scheme. We store TP-UDL value as-is,
	 * so this should be kept in mind to avoid buffer overruns. */
	gsms->user_data_len = *smsp++;
	if (gsms->user_data_len > 0) {
		if (sms_alphabet == DCS_7BIT_DEFAULT) {
			/* TP-UDL is indicated in septets (up to 160) */
			if (gsms->user_data_len > GSM340_UDL_SPT_MAX) {
				LOG_TRANS(trans, LOGL_NOTICE,
					  "TP-User-Data-Length %u (septets) "
					  "is too big, truncating to %u\n",
					  gsms->user_data_len, GSM340_UDL_SPT_MAX);
				gsms->user_data_len = GSM340_UDL_SPT_MAX;
			}
			memcpy(gsms->user_data, smsp, gsm_get_octet_len(gsms->user_data_len));
			gsm_7bit_decode_n(gsms->text, sizeof(gsms->text),
					  smsp, gsms->user_data_len);
		} else {
			/* TP-UDL is indicated in octets (up to 140) */
			if (gsms->user_data_len > GSM340_UDL_OCT_MAX) {
				LOG_TRANS(trans, LOGL_NOTICE,
					  "TP-User-Data-Length %u (octets) "
					  "is too big, truncating to %u\n",
					  gsms->user_data_len, GSM340_UDL_OCT_MAX);
				gsms->user_data_len = GSM340_UDL_OCT_MAX;
			}
			memcpy(gsms->user_data, smsp, gsms->user_data_len);
		}
	}

	OSMO_STRLCPY_ARRAY(gsms->src.addr, vsub->msisdn);

	LOG_TRANS(trans, LOGL_INFO,
		  "MO SMS -- MTI: 0x%02x, VPF: 0x%02x, "
		  "MR: 0x%02x PID: 0x%02x, DCS: 0x%02x, DA: %s, "
		  "UserDataLength: 0x%02x, UserData: \"%s\"\n",
		  sms_mti, sms_vpf, gsms->msg_ref,
		  gsms->protocol_id, gsms->data_coding_scheme, gsms->dst.addr,
		  gsms->user_data_len,
		  sms_alphabet == DCS_7BIT_DEFAULT ? gsms->text :
		  osmo_hexdump(gsms->user_data, gsms->user_data_len));

	gsms->validity_minutes = gsm340_validity_period(sms_vpf, sms_vp);

	rc = sms_route_mt_sms(trans, gsms);

	/* This SMS got routed through SMPP and we are waiting on the response. */
	if (gsms->smpp.esme) {
		rc = -EINPROGRESS;
		goto out;
	}

	/* This SMS got routed through SMPP, but the configured ESME was
	 * unavailable at this time. This is an OOO condition.
	 * Don't store this SMS in the database as we may never be
	 * able to deliver it. (we would need to process the stored SMS and
	 * attempt re-submission to the ESME)
	 */
	if (rc == GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER)
		goto out; /* free() the message */

	/*
	 * This SMS got routed through SMPP or no receiver exists.
	 * In any case, we store it in the database for further processing.
	 */

	switch (sms_mti) {
	case GSM340_SMS_SUBMIT_MS2SC:
		/* MS is submitting a SMS */
		rc = gsm340_rx_sms_submit(trans, gsms);
		break;
	case GSM340_SMS_COMMAND_MS2SC:
	case GSM340_SMS_DELIVER_REP_MS2SC:
		LOG_TRANS(trans, LOGL_NOTICE, "Unimplemented MTI 0x%02x\n", sms_mti);
		rc = GSM411_RP_CAUSE_IE_NOTEXIST;
		break;
	default:
		LOG_TRANS(trans, LOGL_NOTICE, "Undefined MTI 0x%02x\n", sms_mti);
		rc = GSM411_RP_CAUSE_IE_NOTEXIST;
		break;
	}
out:
	sms_free(gsms);

	return rc;
}

/* Prefix msg with a RP-DATA header and send as SMR DATA */
static int gsm411_rp_sendmsg(struct gsm411_smr_inst *inst, struct msgb *msg,
			     uint8_t rp_msg_type, uint8_t rp_msg_ref,
			     int rl_msg_type)
{
	struct gsm411_rp_hdr *rp;
	uint8_t len = msg->len;

	/* GSM 04.11 RP-DATA header */
	rp = (struct gsm411_rp_hdr *)msgb_push(msg, sizeof(*rp));
	rp->len = len + 2;
	rp->msg_type = rp_msg_type;
	rp->msg_ref = rp_msg_ref;

	return gsm411_smr_send(inst, rl_msg_type, msg);
}

int gsm411_send_rp_ack(struct gsm_trans *trans, uint8_t msg_ref)
{
	struct msgb *msg = gsm411_msgb_alloc();

	LOG_TRANS(trans, LOGL_DEBUG, "TX: SMS RP ACK\n");

	return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg, GSM411_MT_RP_ACK_MT,
		msg_ref, GSM411_SM_RL_REPORT_REQ);
}

int gsm411_send_rp_error(struct gsm_trans *trans, uint8_t msg_ref,
			 uint8_t cause)
{
	struct msgb *msg = gsm411_msgb_alloc();

	msgb_tv_put(msg, 1, cause);

	LOG_TRANS(trans, LOGL_NOTICE, "TX: SMS RP ERROR, cause %d (%s)\n", cause,
		get_value_string(gsm411_rp_cause_strs, cause));

	return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
		GSM411_MT_RP_ERROR_MT, msg_ref, GSM411_SM_RL_REPORT_REQ);
}

/* Receive a 04.11 TPDU inside RP-DATA / user data */
static int gsm411_rx_rp_ud(struct msgb *msg, struct gsm_trans *trans,
			  struct gsm411_rp_hdr *rph,
			  uint8_t *dst, uint8_t dst_len)
{
	int rc = 0;

	if (trans->net->sms_over_gsup) {
		/* RP-ACK or RP-ERROR is triggered as soon as we get the response */
		rc = gsm411_gsup_mo_fwd_sm_req(trans, msg, rph->msg_ref, dst, dst_len);
		if (rc) /* GSUP message sending error */
			return gsm411_send_rp_error(trans, rph->msg_ref, rc);

		return 0;
	}

	rc = gsm340_rx_tpdu(trans, msg, rph->msg_ref);
	if (rc == 0)
		return gsm411_send_rp_ack(trans, rph->msg_ref);
	else if (rc > 0)
		return gsm411_send_rp_error(trans, rph->msg_ref, rc);
	else if (rc == -EINPROGRESS)
		rc = 0;

	return rc;
}

/* Receive a 04.11 RP-DATA message in accordance with Section 7.3.1.2 */
static int gsm411_rx_rp_data(struct msgb *msg, struct gsm_trans *trans,
			     struct gsm411_rp_hdr *rph)
{
	uint8_t src_len, dst_len, rpud_len;
	uint8_t *src = NULL, *dst = NULL , *rp_ud = NULL;

	/* in the MO case, this should always be zero length */
	src_len = rph->data[0];
	if (src_len)
		src = &rph->data[1];

	dst_len = rph->data[1+src_len];
	if (dst_len)
		dst = &rph->data[1+src_len+1];

	rpud_len = rph->data[1+src_len+1+dst_len];
	if (rpud_len)
		rp_ud = &rph->data[1+src_len+1+dst_len+1];

	LOG_TRANS(trans, LOGL_DEBUG, "RX_RP-DATA: src_len=%u, dst_len=%u ud_len=%u\n",
		src_len, dst_len, rpud_len);

	if (src_len && src)
		LOG_TRANS(trans, LOGL_ERROR, "RP-DATA (MO) with SRC ?!?\n");

	if (!dst_len || !dst || !rpud_len || !rp_ud) {
		LOG_TRANS(trans, LOGL_ERROR,
			"RP-DATA (MO) without DST or TPDU ?!?\n");
		gsm411_send_rp_error(trans, rph->msg_ref,
				     GSM411_RP_CAUSE_INV_MAND_INF);
		return -EIO;
	}

	msg->l4h = rp_ud;

	LOG_TRANS(trans, LOGL_DEBUG, "DST(%u,%s)\n", dst_len, osmo_hexdump(dst, dst_len));

	return gsm411_rx_rp_ud(msg, trans, rph, dst, dst_len);
}

static struct gsm_sms *sms_report_alloc(struct gsm_sms *sms, struct gsm_trans *trans)
{
	struct gsm_sms *sms_report;
	int len;

	sms_report = sms_alloc();
	OSMO_ASSERT(sms_report);

	sms_report->msg_ref = sms->msg_ref;
	sms_report->protocol_id = sms->protocol_id;
	sms_report->data_coding_scheme = GSM338_DCS_1111_8BIT_DATA;

	/* Invert address to send status report back to origin. */
	sms_report->src = sms->dst;
	sms_report->dst = sms->src;

	/* As specified by Appendix B. Delivery Receipt Format.
	 * TODO: Many fields in this string are just set with dummy values,
	 * 	 revisit this.
	 */
	len = snprintf((char *)sms_report->user_data,
		       sizeof(sms_report->user_data),
		       "id:%.08llu sub:000 dlvrd:000 submit date:YYMMDDhhmm done date:YYMMDDhhmm stat:DELIVRD err:000 text:%.20s",
		       sms->id, sms->text);
	sms_report->user_data_len = len;
	LOG_TRANS(trans, LOGL_NOTICE, "%s\n", sms_report->user_data);

	/* This represents a sms report. */
	sms_report->is_report = true;

	return sms_report;
}

static void sms_status_report(struct gsm_sms *gsms, struct gsm_trans *trans)
{
	struct gsm_sms *sms_report;
	int rc;

	sms_report = sms_report_alloc(gsms, trans);

	rc = sms_route_mt_sms(trans, sms_report);
	if (rc < 0) {
		LOG_TRANS(trans, LOGL_ERROR, "Failed to send status report! err=%d\n", rc);
		return;
	}

	/* No route via SMPP, send the GSM 03.40 status-report now. */
	if (sms_report->receiver)
		gsm340_rx_sms_submit(trans, sms_report);

	LOG_TRANS(trans, LOGL_NOTICE, "Status report has been sent\n");

	sms_free(sms_report);
}

/* Receive a 04.11 RP-ACK message (response to RP-DATA from us) */
static int gsm411_rx_rp_ack(struct gsm_trans *trans,
			    struct gsm411_rp_hdr *rph)
{
	struct gsm_sms *sms = trans->sms.sms;

	/* Acnkowledgement to MT RP_DATA, i.e. the MS confirms it
	 * successfully received a SMS.  We can now safely mark it as
	 * transmitted */

	if (trans->net->sms_over_gsup) {
		/* Forward towards SMSC via GSUP */
		return gsm411_gsup_mt_fwd_sm_res(trans, rph->msg_ref);
	}

	if (!sms) {
		LOG_TRANS(trans, LOGL_ERROR, "RX RP-ACK but no sms in transaction?!?\n");
		return gsm411_send_rp_error(trans, rph->msg_ref,
					    GSM411_RP_CAUSE_PROTOCOL_ERR);
	}

	/* mark this SMS as sent in database */
	db_sms_mark_delivered(sms);

	send_signal(S_SMS_DELIVERED, trans, sms, 0);

	if (sms->status_rep_req)
		sms_status_report(sms, trans);

	sms_free(sms);
	trans->sms.sms = NULL;

	return 0;
}

static int gsm411_rx_rp_error(struct gsm_trans *trans,
			      struct gsm411_rp_hdr *rph)
{
	struct msc_a *msc_a = trans->msc_a;
	struct gsm_network *net = msc_a_net(msc_a);
	struct gsm_sms *sms = trans->sms.sms;
	uint8_t cause_len = rph->data[0];
	uint8_t cause = rph->data[1];

	/* Error in response to MT RP_DATA, i.e. the MS did not
	 * successfully receive the SMS.  We need to investigate
	 * the cause and take action depending on it */

	LOG_TRANS(trans, LOGL_NOTICE, "RX SMS RP-ERROR, cause %d:%d (%s)\n",
		      cause_len, cause, get_value_string(gsm411_rp_cause_strs, cause));

	if (trans->net->sms_over_gsup) {
		/* Forward towards SMSC via GSUP */
		return gsm411_gsup_mt_fwd_sm_err(trans, rph->msg_ref, cause);
	}

	if (!sms) {
		LOG_TRANS(trans, LOGL_ERROR, "RX RP-ERR, but no sms in transaction?!?\n");
		return -EINVAL;
#if 0
		return gsm411_send_rp_error(trans, rph->msg_ref,
					    GSM411_RP_CAUSE_PROTOCOL_ERR);
#endif
	}

	if (cause == GSM411_RP_CAUSE_MT_MEM_EXCEEDED) {
		/* MS has not enough memory to store the message.  We need
		 * to store this in our database and wait for a SMMA message */
		/* FIXME */
		send_signal(S_SMS_MEM_EXCEEDED, trans, sms, 0);
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_RP_ERR_MEM));
	} else {
		send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
		rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_RP_ERR_OTHER));
	}

	sms_free(sms);
	trans->sms.sms = NULL;

	return 0;
}

static int gsm411_rx_rp_smma(struct msgb *msg, struct gsm_trans *trans,
			     struct gsm411_rp_hdr *rph)
{
	int rc;

	if (trans->net->sms_over_gsup) {
		/* RP-ACK or RP-ERROR is triggered as soon as we get the response */
		rc = gsm411_gsup_mo_ready_for_sm_req(trans, rph->msg_ref);
		if (rc) /* GSUP message sending error */
			return gsm411_send_rp_error(trans, rph->msg_ref, rc);

		return 0;
	}

	rc = gsm411_send_rp_ack(trans, rph->msg_ref);

	/* MS tells us that it has memory for more SMS, we need
	 * to check if we have any pending messages for it and then
	 * transfer those */
	send_signal(S_SMS_SMMA, trans, NULL, 0);

	return rc;
}

/* receive RL DATA */
static int gsm411_rx_rl_data(struct msgb *msg, struct gsm48_hdr *gh,
			     struct gsm_trans *trans)
{
	struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
	uint8_t msg_type =  rp_data->msg_type & 0x07;
	int rc = 0;

	switch (msg_type) {
	case GSM411_MT_RP_DATA_MO:
		LOG_TRANS(trans, LOGL_DEBUG, "RX SMS RP-DATA (MO)\n");
		rc = gsm411_rx_rp_data(msg, trans, rp_data);
		break;
	case GSM411_MT_RP_SMMA_MO:
		LOG_TRANS(trans, LOGL_DEBUG, "RX SMS RP-SMMA\n");
		rc = gsm411_rx_rp_smma(msg, trans, rp_data);
		break;
	default:
		LOG_TRANS(trans, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
		rc = -EINVAL;
		break;
	}

	return rc;
}

/* receive RL REPORT */
static int gsm411_rx_rl_report(struct msgb *msg, struct gsm48_hdr *gh,
			     struct gsm_trans *trans)
{
	struct gsm411_rp_hdr *rp_data = (struct gsm411_rp_hdr*)&gh->data;
	uint8_t msg_type =  rp_data->msg_type & 0x07;
	int rc = 0;

	switch (msg_type) {
	case GSM411_MT_RP_ACK_MO:
		LOG_TRANS(trans, LOGL_DEBUG, "RX SMS RP-ACK (MO)\n");
		rc = gsm411_rx_rp_ack(trans, rp_data);
		break;
	case GSM411_MT_RP_ERROR_MO:
		LOG_TRANS(trans, LOGL_DEBUG, "RX SMS RP-ERROR (MO)\n");
		rc = gsm411_rx_rp_error(trans, rp_data);
		break;
	default:
		LOG_TRANS(trans, LOGL_NOTICE, "Invalid RP type 0x%02x\n", msg_type);
		rc = -EINVAL;
		break;
	}

	return rc;
}

/* receive SM-RL sap message from SMR
 * NOTE: Message is freed by sender
 */
int gsm411_rl_recv(struct gsm411_smr_inst *inst, int msg_type,
                        struct msgb *msg)
{
	struct gsm_trans *trans =
		container_of(inst, struct gsm_trans, sms.smr_inst);
	struct gsm48_hdr *gh = msgb_l3(msg);
	int rc = 0;

	switch (msg_type) {
	case GSM411_SM_RL_DATA_IND:
		rc = gsm411_rx_rl_data(msg, gh, trans);
		break;
	case GSM411_SM_RL_REPORT_IND:
		if (gh)
			rc = gsm411_rx_rl_report(msg, gh, trans);
		break;
	default:
		LOG_TRANS(trans, LOGL_NOTICE, "Unhandled SM-RL message 0x%x\n", msg_type);
		rc = -EINVAL;
	}

	return rc;
}

/* receive MNCCSMS sap message from SMC
 * NOTE: Message is freed by sender
 */
static int gsm411_mn_recv(struct gsm411_smc_inst *inst, int msg_type,
			struct msgb *msg)
{
	struct gsm_trans *trans =
		container_of(inst, struct gsm_trans, sms.smc_inst);
	struct gsm48_hdr *gh = msgb_l3(msg);
	int rc = 0;

	switch (msg_type) {
	case GSM411_MNSMS_EST_IND:
	case GSM411_MNSMS_DATA_IND:
		LOG_TRANS(trans, LOGL_DEBUG, "MNSMS-DATA/EST-IND\n");
		rc = gsm411_smr_recv(&trans->sms.smr_inst, msg_type, msg);
		break;
	case GSM411_MNSMS_ERROR_IND:
		if (gh)
			LOG_TRANS(trans, LOGL_DEBUG, "MNSMS-ERROR-IND, cause %d (%s)\n",
				gh->data[0],
				get_value_string(gsm411_cp_cause_strs,
				gh->data[0]));
		else
			LOG_TRANS(trans, LOGL_DEBUG, "MNSMS-ERROR-IND, no cause\n");
		rc = gsm411_smr_recv(&trans->sms.smr_inst, msg_type, msg);
		break;
	default:
		LOG_TRANS(trans, LOGL_NOTICE, "Unhandled MNCCSMS msg 0x%x\n", msg_type);
		rc = -EINVAL;
	}

	return rc;
}

static struct gsm_trans *gsm411_trans_init(struct gsm_network *net, struct vlr_subscr *vsub, struct msc_a *msc_a,
					   uint8_t tid, bool mo)
{
	/* Allocate a new transaction */
	struct gsm_trans *trans = trans_alloc(net, vsub, TRANS_SMS, tid, new_callref++);
	if (!trans) {
		LOG_TRANS(trans, LOGL_ERROR, "No memory for transaction\n");
		return NULL;
	}

	if (msc_a) {
		msc_a_get(msc_a, MSC_A_USE_SMS);
		trans->msc_a = msc_a;

		osmo_fsm_inst_dispatch(msc_a->c.fi, MSC_A_EV_TRANSACTION_ACCEPTED, trans);
		if (mo) {
			if (!osmo_use_count_by(&msc_a->use_count, MSC_A_USE_CM_SERVICE_SMS))
				LOG_TRANS(trans, LOGL_ERROR, "MO SMS without prior CM Service Request\n");
			else
				msc_a_put(msc_a, MSC_A_USE_CM_SERVICE_SMS);
		}
	}

	/* Init both SMC and SMR state machines */
	gsm411_smc_init(&trans->sms.smc_inst, 0, 1,
		gsm411_mn_recv, gsm411_mm_send);
	gsm411_smr_init(&trans->sms.smr_inst, 0, 1,
		gsm411_rl_recv, gsm411_mn_send);

	return trans;
}

/* Assigns an (unused) SM-RP-MR value to a given transaction */
static int gsm411_assign_sm_rp_mr(struct gsm_trans *trans)
{
	uint8_t mr;

	/* After allocation a given transaction has zero-initialized
	 * SM-RP-MR value, so trans_find_by_sm_rp_mr() may consider
	 * 0x00 as used. This is why we "poison" this transaction
	 * using the highest value. */
	trans->sms.sm_rp_mr = 0xff;

	/* According to 8.2.3, MR is in the range 0 through 255 */
	for (mr = 0x00; mr < 0xff; mr++) {
		if (trans_find_by_sm_rp_mr(trans->net, trans->vsub, mr))
			continue; /* this MR is busy, find another one */
		/* An unused value has been found, assign it */
		trans->sms.sm_rp_mr = mr;
		return 0;
	}

	/* All possible values are busy */
	return -EBUSY;
}

static struct gsm_trans *gsm411_alloc_mt_trans(struct gsm_network *net,
					       struct vlr_subscr *vsub)
{
	struct msc_a *msc_a;
	struct gsm_trans *trans;
	int tid;

	/* Generate a new transaction ID */
	tid = trans_assign_trans_id(net, vsub, TRANS_SMS);
	if (tid == -1) {
		LOGP(DLSMS, LOGL_ERROR, "No available transaction IDs\n");
		return NULL;
	}

	/* Attempt to find an existing connection */
	msc_a = msc_a_for_vsub(vsub, true);

	/* Allocate a new transaction */
	trans = gsm411_trans_init(net, vsub, msc_a, tid, false);
	if (!trans)
		return NULL;

	LOG_TRANS(trans, LOGL_INFO, "Going to send a MT SMS\n");

	/* Assign a unique SM-RP Message Reference */
	if (gsm411_assign_sm_rp_mr(trans) != 0) {
		LOG_TRANS(trans, LOGL_ERROR, "Failed to assign SM-RP-MR\n");
		trans_free(trans);
		return NULL;
	}

	/* Use SAPI 3 (see GSM 04.11, section 2.3) */
	trans->dlci = UM_SAPI_SMS;

	return trans;
}

/* High-level function to send an SMS to a given subscriber */
int gsm411_send_sms(struct gsm_network *net,
		    struct vlr_subscr *vsub,
		    struct gsm_sms *sms)
{
	uint8_t *data, *rp_ud_len;
	struct gsm_trans *trans;
	struct msgb *msg;
	int rc;

	/* Allocate a new transaction for MT SMS */
	trans = gsm411_alloc_mt_trans(net, vsub);
	if (!trans) {
		send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, 0);
		sms_free(sms);
		return -ENOMEM;
	}

	/* Allocate a message buffer for to be encoded SMS */
	msg = gsm411_msgb_alloc();
	if (!msg) {
		send_signal(S_SMS_UNKNOWN_ERROR, NULL, sms, 0);
		trans_free(trans);
		sms_free(sms);
		return -ENOMEM;
	}

	/* Hardcode SMSC Originating Address for now */
	data = (uint8_t *)msgb_put(msg, 8);
	data[0] = 0x07;	/* originator length == 7 */
	data[1] = 0x91; /* type of number: international, ISDN */
	data[2] = 0x44; /* 447785016005 */
	data[3] = 0x77;
	data[4] = 0x58;
	data[5] = 0x10;
	data[6] = 0x06;
	data[7] = 0x50;

	/* Hardcoded Destination Address */
	data = (uint8_t *)msgb_put(msg, 1);
	data[0] = 0;	/* destination length == 0 */

	/* obtain a pointer for the rp_ud_len, so we can fill it later */
	rp_ud_len = (uint8_t *)msgb_put(msg, 1);

	if (sms->is_report) {
		/* generate the 03.40 SMS-STATUS-REPORT TPDU */
		rc = gsm340_gen_sms_status_report_tpdu(trans, msg, sms);
	} else {
		/* generate the 03.40 SMS-DELIVER TPDU */
		rc = gsm340_gen_sms_deliver_tpdu(trans, msg, sms);
	}
	if (rc < 0) {
		send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
		sms_free(sms);
		trans_free(trans);
		msgb_free(msg);
		return rc;
	}

	*rp_ud_len = rc;

	/* Store a pointer to abstract SMS representation */
	trans->sms.sms = sms;

	rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVERED));
	db_sms_inc_deliver_attempts(trans->sms.sms);

	return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
		GSM411_MT_RP_DATA_MT, trans->sms.sm_rp_mr,
		GSM411_SM_RL_DATA_REQ);
}

/* Low-level function to send raw RP-DATA to a given subscriber */
int gsm411_send_rp_data(struct gsm_network *net, struct vlr_subscr *vsub,
			size_t sm_rp_oa_len, const uint8_t *sm_rp_oa,
			size_t sm_rp_ud_len, const uint8_t *sm_rp_ud,
			bool sm_rp_mmts_ind)
{
	struct gsm_trans *trans;
	struct msgb *msg;

	/* Allocate a new transaction for MT SMS */
	trans = gsm411_alloc_mt_trans(net, vsub);
	if (!trans)
		return -ENOMEM;

	/* Multi-part SMS: handle MMTS (More Messages to Send) indication */
	trans->sms.sm_rp_mmts_ind = sm_rp_mmts_ind;
	if (trans->msc_a != NULL)
		gsm411_handle_mmts_ind(trans);

	/* Allocate a message buffer for to be encoded SMS */
	msg = gsm411_msgb_alloc();
	if (!msg) {
		trans_free(trans);
		return -ENOMEM;
	}

	/* Encode SM-RP-OA (SMSC address) */
	msgb_lv_put(msg, sm_rp_oa_len, sm_rp_oa);

	/* Encode SM-RP-DA (shall be empty, len=0) */
	msgb_v_put(msg, 0x00);

	/* Encode RP-UD itself (SM TPDU) */
	msgb_lv_put(msg, sm_rp_ud_len, sm_rp_ud);

	rate_ctr_inc(rate_ctr_group_get_ctr(net->msc_ctrs, MSC_CTR_SMS_DELIVERED));

	return gsm411_rp_sendmsg(&trans->sms.smr_inst, msg,
		GSM411_MT_RP_DATA_MT, trans->sms.sm_rp_mr,
		GSM411_SM_RL_DATA_REQ);
}

/* Entry point for incoming GSM48_PDISC_SMS from abis_rsl.c */
int gsm0411_rcv_sms(struct msc_a *msc_a, struct msgb *msg)
{
	struct gsm48_hdr *gh = msgb_l3(msg);
	uint8_t msg_type = gh->msg_type;
	uint8_t transaction_id = gsm48_hdr_trans_id_flip_ti(gh);
	struct gsm411_rp_hdr *rph = (struct gsm411_rp_hdr *) gh->data;
	struct gsm_trans *trans;
	int new_trans = 0;
	int rc = 0;
	struct vlr_subscr *vsub = msc_a_vsub(msc_a);
	struct gsm_network *net = msc_a_net(msc_a);

	trans = trans_find_by_id(msc_a, TRANS_SMS, transaction_id);

	/*
	 * A transaction we created but don't know about?
	 */
	if (!trans && (transaction_id & 0x8) == 0) {
		LOG_TRANS(trans, LOGL_ERROR, "trans_id=%x allocated by us but known "
			"to us anymore. We are ignoring it, maybe a CP-ERROR "
			"from a MS?\n",
			transaction_id);
		return -EINVAL;
	}

	if (!trans) {
		new_trans = 1;
		trans = gsm411_trans_init(net, vsub, msc_a, transaction_id, true);
		if (!trans) {
			/* FIXME: send some error message */
			return -ENOMEM;
		}

		trans->sms.sm_rp_mr = rph->msg_ref; /* SM-RP Message Reference */
		trans->dlci = OMSC_LINKID_CB(msg); /* DLCI as received from BSC */
	}

	LOG_TRANS(trans, LOGL_DEBUG, "receiving SMS message %s\n",
		  gsm48_pdisc_msgtype_name(gsm48_hdr_pdisc(gh), gsm48_hdr_msg_type(gh)));

	/* According to section 5.3.4, due to structure of message flow on
	 * SAPI 0 and 3 it is possible that the CP-ACK of a short message
	 * transfer might not be received. In this case the reception of
	 * CP-DATA may be interpreted as the reception of the awaited
	 * CP-ACK (implicit) and CP-DATA message. */
	if (trans->sms.smc_inst.cp_state == GSM411_CPS_IDLE
	    && msg_type == GSM411_MT_CP_DATA) {
		int i;
		struct gsm_trans *ptrans;

		/* Scan through all remote initiated transactions */
		for (i=8; i<15; i++) {
			if (i == transaction_id)
				continue;

			ptrans = trans_find_by_id(msc_a, TRANS_SMS, i);
			if (!ptrans)
				continue;

			LOG_TRANS(ptrans, LOGL_DEBUG, "Implicit CP-ACK for trans_id=%x\n", i);

			/* Finish it for good */
			trans_free(ptrans);
		}
	}

	gsm411_smc_recv(&trans->sms.smc_inst,
		(new_trans) ? GSM411_MMSMS_EST_IND : GSM411_MMSMS_DATA_IND,
		msg, msg_type);

	return rc;
}

void _gsm411_sms_trans_free(struct gsm_trans *trans)
{
	/* cleanup SMS instance */
	gsm411_smr_clear(&trans->sms.smr_inst);
	trans->sms.smr_inst.rl_recv = NULL;
	trans->sms.smr_inst.mn_send = NULL;

	gsm411_smc_clear(&trans->sms.smc_inst);
	trans->sms.smc_inst.mn_recv = NULL;
	trans->sms.smc_inst.mm_send = NULL;

	if (trans->sms.sms) {
		LOG_TRANS(trans, LOGL_ERROR, "Freeing transaction that still contains an SMS -- discarding\n");
		send_signal(S_SMS_UNKNOWN_ERROR, trans, trans->sms.sms, 0);
		sms_free(trans->sms.sms);
		trans->sms.sms = NULL;
	}
}

/* Process incoming SAPI N-REJECT from BSC */
void gsm411_sapi_n_reject(struct msc_a *msc_a)
{
	struct gsm_network *net;
	struct gsm_trans *trans, *tmp;

	net = msc_a_net(msc_a);

	llist_for_each_entry_safe(trans, tmp, &net->trans_list, entry) {
		struct gsm_sms *sms;

		if (trans->msc_a != msc_a)
			continue;
		if (trans->type != TRANS_SMS)
			continue;

		sms = trans->sms.sms;
		if (!sms) {
			LOG_TRANS(trans, LOGL_ERROR, "SAPI Reject but no SMS.\n");
			continue;
		}

		send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
		sms_free(sms);
		trans->sms.sms = NULL;
		trans_free(trans);
	}
}

