/* 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(&net->msc_ctrs->ctr[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) {
#ifdef BUILD_SMPP
		/* Avoid a second look-up */
		if (smpp_route_smpp_first()) {
			rate_ctr_inc(&net->msc_ctrs->ctr[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(&net->msc_ctrs->ctr[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(&net->msc_ctrs->ctr[MSC_CTR_SMS_DELIVER_UNKNOWN_ERROR]);
		}
#else
		rc = GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
		rate_ctr_inc(&net->msc_ctrs->ctr[MSC_CTR_SMS_NO_RECEIVER]);
#endif
	} else
		rc = 0;

	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(&net->msc_ctrs->ctr[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 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
		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(&net->msc_ctrs->ctr[MSC_CTR_SMS_RP_ERR_MEM]);
	} else {
		send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
		rate_ctr_inc(&net->msc_ctrs->ctr[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(&net->msc_ctrs->ctr[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(&net->msc_ctrs->ctr[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);
	}
}

