/* OpenBSC SMPP 3.4 interface, SMSC-side implementation */

/* (C) 2012-2013 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */


#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <errno.h>

#include <smpp34.h>
#include <smpp34_structs.h>
#include <smpp34_params.h>

#include <osmocom/core/utils.h>
#include <osmocom/core/msgb.h>
#include <osmocom/core/logging.h>
#include <osmocom/core/talloc.h>
#include <osmocom/gsm/protocol/gsm_04_11.h>
#include <osmocom/gsm/protocol/smpp34_osmocom.h>

#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/debug.h>
#include <osmocom/msc/db.h>
#include <osmocom/msc/gsm_04_11.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/msc/signal.h>
#include <osmocom/msc/transaction.h>
#include <osmocom/msc/gsm_subscriber.h>
#include <osmocom/msc/vlr.h>

#include "smpp_smsc.h"

#define VSUB_USE_SMPP "SMPP"
#define VSUB_USE_SMPP_CMD "SMPP-cmd"

/*! \brief find vlr_subscr for a given SMPP NPI/TON/Address */
static struct vlr_subscr *subscr_by_dst(struct gsm_network *net,
					    uint8_t npi, uint8_t ton,
					    const char *addr)
{
	struct vlr_subscr *vsub = NULL;

	switch (npi) {
	case NPI_Land_Mobile_E212:
		vsub = vlr_subscr_find_by_imsi(net->vlr, addr, VSUB_USE_SMPP);
		break;
	case NPI_ISDN_E163_E164:
	case NPI_Private:
		vsub = vlr_subscr_find_by_msisdn(net->vlr, addr, VSUB_USE_SMPP);
		break;
	default:
		LOGP(DSMPP, LOGL_NOTICE, "Unsupported NPI: %u\n", npi);
		break;
	}

	log_set_context(LOG_CTX_VLR_SUBSCR, vsub);
	return vsub;
}

static int smpp34_submit_tlv_msg_payload(const struct tlv_t *t,
					 const struct submit_sm_t *submit,
					 const uint8_t **sms_msg,
					 unsigned int *sms_msg_len)
{
	if (submit->sm_length) {
		LOGP(DLSMS, LOGL_ERROR,
		     "SMPP cannot have payload in TLV _and_ in the header\n");
		return -1;
	}
	*sms_msg = t->value.octet;
	*sms_msg_len = t->length;

	return 0;
}

/*! \brief convert from submit_sm_t to gsm_sms */
static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
			 const struct submit_sm_t *submit)
{
	const uint8_t *sms_msg = NULL;
	unsigned int sms_msg_len = 0;
	struct vlr_subscr *dest;
	uint16_t msg_ref = 0;
	struct gsm_sms *sms;
	struct tlv_t *t;
	int mode;
	int can_store_sms = ((submit->esm_class & SMPP34_MSG_MODE_MASK) != 2); /* != forward mode */

	dest = subscr_by_dst(net, submit->dest_addr_npi,
			     submit->dest_addr_ton,
			     (const char *)submit->destination_addr);
	if (!dest && !can_store_sms) {
		LOGP(DLSMS, LOGL_NOTICE, "SMPP SUBMIT-SM for unknown subscriber: "
		     "%s (NPI=%u)\n", submit->destination_addr,
		     submit->dest_addr_npi);
		return ESME_RINVDSTADR;
	}

	smpp34_tlv_for_each(t, submit->tlv) {
		switch (t->tag) {
		case TLVID_message_payload:
			if (smpp34_submit_tlv_msg_payload(t, submit, &sms_msg,
							  &sms_msg_len) < 0) {
				if (dest)
					vlr_subscr_put(dest, VSUB_USE_SMPP);
				return ESME_ROPTPARNOTALLWD;
			}
			break;
		case TLVID_user_message_reference:
			msg_ref = t->value.val16;
			break;
		default:
			break;
		}
	}

	if (!sms_msg) {
		if (submit->sm_length > 0 && submit->sm_length < 255) {
			sms_msg = submit->short_message;
			sms_msg_len = submit->sm_length;
		} else {
			LOGP(DLSMS, LOGL_ERROR,
			     "SMPP neither message payload nor valid sm_length.\n");
			if (dest)
				vlr_subscr_put(dest, VSUB_USE_SMPP);
			return ESME_RINVPARLEN;
		}
	}

	sms = sms_alloc();
	sms->source = SMS_SOURCE_SMPP;
	sms->smpp.sequence_nr = submit->sequence_number;
	sms->status_rep_req = submit->registered_delivery;
	sms->msg_ref = msg_ref;

	/* fill in the destination address */
	sms->receiver = dest;
	if (dest) {
		/* Replace use count from above subscr_by_dst (VSUB_USE_SMPP) by the sms->receiver use count
		 * (VSUB_USE_SMS_RECEIVER) */
		vlr_subscr_get(sms->receiver, VSUB_USE_SMS_RECEIVER);
		vlr_subscr_put(dest, VSUB_USE_SMPP);
	}
	sms->dst.ton = submit->dest_addr_ton;
	sms->dst.npi = submit->dest_addr_npi;
	if (dest)
		OSMO_STRLCPY_ARRAY(sms->dst.addr, dest->msisdn);
	else
		OSMO_STRLCPY_ARRAY(sms->dst.addr,
				   (const char *)submit->destination_addr);

	/* fill in the source address */
	sms->src.ton = submit->source_addr_ton;
	sms->src.npi = submit->source_addr_npi;
	OSMO_STRLCPY_ARRAY(sms->src.addr, (char *)submit->source_addr);

	if (submit->esm_class == SMPP34_DELIVERY_ACK)
		sms->is_report = true;

	if (submit->esm_class & SMPP34_UDHI_IND)
		sms->ud_hdr_ind = 1;

	if (submit->esm_class & SMPP34_REPLY_PATH) {
		sms->reply_path_req = 1;
#warning Implement reply path
	}

	if (submit->data_coding == 0x00 ||	/* SMSC default */
	    submit->data_coding == 0x01) {	/* GSM default alphabet */
		sms->data_coding_scheme = GSM338_DCS_1111_7BIT;
		mode = MODE_7BIT;
	} else if ((submit->data_coding & 0xFC) == 0xF0) { /* 03.38 DCS default */
		/* pass DCS 1:1 through from SMPP to GSM */
		sms->data_coding_scheme = submit->data_coding;
		mode = MODE_7BIT;
	} else if (submit->data_coding == 0x02 ||
		   submit->data_coding == 0x04) {
		/* 8-bit binary */
		sms->data_coding_scheme = GSM338_DCS_1111_8BIT_DATA;
		mode = MODE_8BIT;
	} else if ((submit->data_coding & 0xFC) == 0xF4) { /* 03.38 DCS 8bit */
		/* pass DCS 1:1 through from SMPP to GSM */
		sms->data_coding_scheme = submit->data_coding;
		mode = MODE_8BIT;
	} else if (submit->data_coding == 0x08) {
		/* UCS-2 */
		sms->data_coding_scheme = (2 << 2);
		mode = MODE_8BIT;
	} else {
		sms_free(sms);
		LOGP(DLSMS, LOGL_ERROR, "SMPP Unknown Data Coding 0x%02x\n",
			submit->data_coding);
		return ESME_RUNKNOWNERR;
	}

	if (mode == MODE_7BIT) {
		uint8_t ud_len = 0, padbits = 0;
		sms->data_coding_scheme = GSM338_DCS_1111_7BIT;
		if (sms->ud_hdr_ind) {
			ud_len = *sms_msg + 1;
			printf("copying %u bytes user data...\n", ud_len);
			memcpy(sms->user_data, sms_msg,
				OSMO_MIN(ud_len, sizeof(sms->user_data)));
			sms_msg += ud_len;
			sms_msg_len -= ud_len;
			padbits = 7 - (ud_len % 7);
		}
		gsm_septets2octets(sms->user_data+ud_len, sms_msg,
				   sms_msg_len, padbits);
		sms->user_data_len = (ud_len*8 + padbits)/7 + sms_msg_len;/* SEPTETS */
		/* FIXME: sms->text */
	} else {
		memcpy(sms->user_data, sms_msg, sms_msg_len);
		sms->user_data_len = sms_msg_len;
	}

	*psms = sms;
	return ESME_ROK;
}

/*! \brief handle incoming libsmpp34 ssubmit_sm_t from remote ESME */
int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit,
		       struct submit_sm_resp_t *submit_r)
{
	struct gsm_sms *sms;
	struct gsm_network *net = esme->smsc->priv;
	struct sms_signal_data sig;
	int rc = -1;

	rc = submit_to_sms(&sms, net, submit);
	if (rc != ESME_ROK) {
		submit_r->command_status = rc;
		return 0;
	}
	smpp_esme_get(esme);
	sms->smpp.esme = esme;
	sms->protocol_id = submit->protocol_id;

	switch (submit->esm_class & SMPP34_MSG_MODE_MASK) {
	case 0: /* default */
	case 1: /* datagram */
	case 3: /* store-and-forward */
		rc = db_sms_store(sms);
		sms_free(sms);
		sms = NULL;
		if (rc < 0) {
			LOGP(DLSMS, LOGL_ERROR, "SMPP SUBMIT-SM: Unable to "
				"store SMS in database\n");
			submit_r->command_status = ESME_RSYSERR;
			return 0;
		}
		strcpy((char *)submit_r->message_id, "msg_id_not_implemented");
		LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Stored in DB\n");

		memset(&sig, 0, sizeof(sig));
		osmo_signal_dispatch(SS_SMS, S_SMS_SUBMITTED, &sig);
		rc = 0;
		break;
	case 2: /* forward (i.e. transaction) mode */
		LOGP(DLSMS, LOGL_DEBUG, "SMPP SUBMIT-SM: Forwarding in "
			"real time (Transaction/Forward mode)\n");
		sms->smpp.transaction_mode = 1;
		gsm411_send_sms(net, sms->receiver, sms);
		rc = 1; /* don't send any response yet */
		break;
	}
	return rc;
}

static void alert_all_esme(struct smsc *smsc, struct vlr_subscr *vsub,
			   uint8_t smpp_avail_status)
{
	struct osmo_esme *esme;

	llist_for_each_entry(esme, &smsc->esme_list, list) {
		/* we currently send an alert notification to each ESME that is
		 * connected, and do not require a (non-existant) delivery
		 * pending flag to be set before. */
		if (!esme->bind_flags) {
			LOGP(DSMPP, LOGL_DEBUG,
				"ESME is not (yet) bound, skipping alert\n");
			continue;
		}
		if (!esme->acl->alert_notifications) {
			LOGP(DSMPP, LOGL_DEBUG,
				"[%s] is not set to receive Alert Notifications\n",
					esme->system_id);
			continue;
		}
		if (esme->acl && esme->acl->deliver_src_imsi) {
			smpp_tx_alert(esme, TON_Subscriber_Number,
				      NPI_Land_Mobile_E212,
				      vsub->imsi, smpp_avail_status);
		} else {
			smpp_tx_alert(esme, TON_Network_Specific,
				      NPI_ISDN_E163_E164,
				      vsub->msisdn, smpp_avail_status);
		}
	}
}


/*! \brief signal handler for status of attempted SMS deliveries */
static int smpp_sms_cb(unsigned int subsys, unsigned int signal,
			void *handler_data, void *signal_data)
{
	struct sms_signal_data *sig_sms = signal_data;
	struct gsm_sms *sms = sig_sms->sms;
	struct smsc *smsc = handler_data;
	int rc = 0;

	if (!sms)
		return 0;

	if (sms->source != SMS_SOURCE_SMPP)
		return 0;

	switch (signal) {
	case S_SMS_MEM_EXCEEDED:
		/* fall-through: There is no ESME_Rxxx result code to
		 * indicate a MEMORY EXCEEDED in transaction mode back
		 * to the ESME */
	case S_SMS_UNKNOWN_ERROR:
		if (sms->smpp.transaction_mode) {
			/* Send back the SUBMIT-SM response with apropriate error */
			LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Error\n");
			rc = smpp_tx_submit_r(sms->smpp.esme,
					      sms->smpp.sequence_nr,
					      ESME_RDELIVERYFAILURE,
					      sms->smpp.msg_id);
		}
		break;
	case S_SMS_DELIVERED:
		/* SMS layer tells us the delivery has been completed */
		if (sms->smpp.transaction_mode) {
			/* Send back the SUBMIT-SM response */
			LOGP(DLSMS, LOGL_INFO, "SMPP SUBMIT-SM: Success\n");
			rc = smpp_tx_submit_r(sms->smpp.esme,
					      sms->smpp.sequence_nr,
					      ESME_ROK, sms->smpp.msg_id);
		}
		break;
	case S_SMS_SMMA:
		if (!sig_sms->trans || !sig_sms->trans->vsub) {
			/* SMMA without a subscriber? strange... */
			LOGP(DLSMS, LOGL_NOTICE, "SMMA without subscriber?\n");
			break;
		}

		/* There's no real 1:1 match for SMMA in SMPP.  However,
		 * an ALERT NOTIFICATION seems to be the most logical
		 * choice */
		alert_all_esme(smsc, sig_sms->trans->vsub, 0);
		break;
	}

	return rc;
}

/*! \brief signal handler for subscriber related signals */
static int smpp_subscr_cb(unsigned int subsys, unsigned int signal,
			  void *handler_data, void *signal_data)
{
	struct vlr_subscr *vsub = signal_data;
	struct smsc *smsc = handler_data;
	uint8_t smpp_avail_status;

	/* determine the smpp_avail_status depending on attach/detach */
	switch (signal) {
	case S_SUBSCR_ATTACHED:
		smpp_avail_status = 0;
		break;
	case S_SUBSCR_DETACHED:
		smpp_avail_status = 2;
		break;
	default:
		return 0;
	}

	alert_all_esme(smsc, vsub, smpp_avail_status);

	return 0;
}

/* GSM 03.38 6.2.1 Character expanding (no decode!) */
static int gsm_7bit_expand(char *text, const uint8_t *user_data, uint8_t septet_l, uint8_t ud_hdr_ind)
{
	int i = 0;
	int shift = 0;
	uint8_t c;

	/* skip the user data header */
	if (ud_hdr_ind) {
		/* get user data header length + 1 (for the 'user data header length'-field) */
		shift = ((user_data[0] + 1) * 8) / 7;
		if ((((user_data[0] + 1) * 8) % 7) != 0)
			shift++;
		septet_l = septet_l - shift;
	}

	for (i = 0; i < septet_l; i++) {
		c =
			((user_data[((i + shift) * 7 + 7) >> 3] <<
			  (7 - (((i + shift) * 7 + 7) & 7))) |
			 (user_data[((i + shift) * 7) >> 3] >>
			  (((i + shift) * 7) & 7))) & 0x7f;

		*(text++) = c;
	}

	*text = '\0';

	return i;
}


/* FIXME: libsmpp34 helpers, they should  be part of libsmpp34! */
void append_tlv(tlv_t **req_tlv, uint16_t tag,
	        const uint8_t *data, uint16_t len)
{
	tlv_t tlv;

	memset(&tlv, 0, sizeof(tlv));
	tlv.tag = tag;
	tlv.length = len;
	memcpy(tlv.value.octet, data, tlv.length);
	build_tlv(req_tlv, &tlv);
}
void append_tlv_u8(tlv_t **req_tlv, uint16_t tag, uint8_t val)
{
	tlv_t tlv;

	memset(&tlv, 0, sizeof(tlv));
	tlv.tag = tag;
	tlv.length = 1;
	tlv.value.val08 = val;
	build_tlv(req_tlv, &tlv);
}
void append_tlv_u16(tlv_t **req_tlv, uint16_t tag, uint16_t val)
{
	tlv_t tlv;

	memset(&tlv, 0, sizeof(tlv));
	tlv.tag = tag;
	tlv.length = 2;
	tlv.value.val16 = val;
	build_tlv(req_tlv, &tlv);
}

#if BEFORE_MSCSPLIT
/* We currently have no lchan information. Re-add after A-interface, see OS#2390. */
/* Append the Osmocom vendor-specific additional TLVs to a SMPP msg */
static void append_osmo_tlvs(tlv_t **req_tlv, const struct gsm_lchan *lchan)
{
	int idx = calc_initial_idx(ARRAY_SIZE(lchan->meas_rep),
				   lchan->meas_rep_idx, 1);
	const struct gsm_meas_rep *mr = &lchan->meas_rep[idx];
	const struct gsm_meas_rep_unidir *ul_meas = &mr->ul;
	const struct gsm_meas_rep_unidir *dl_meas = &mr->dl;

	/* Osmocom vendor-specific SMPP34 extensions */
	append_tlv_u16(req_tlv, TLVID_osmo_arfcn, lchan->ts->trx->arfcn);
	if (mr->flags & MEAS_REP_F_MS_L1) {
		uint8_t ms_dbm;
		append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_l1.ta);
		ms_dbm = ms_pwr_dbm(lchan->ts->trx->bts->band, mr->ms_l1.pwr);
		append_tlv_u8(req_tlv, TLVID_osmo_ms_l1_txpwr, ms_dbm);
	} else if (mr->flags & MEAS_REP_F_MS_TO) /* Save Timing Offset field = MS Timing Offset + 63 */
		append_tlv_u8(req_tlv, TLVID_osmo_ta, mr->ms_timing_offset + 63);

	append_tlv_u16(req_tlv, TLVID_osmo_rxlev_ul,
		       rxlev2dbm(ul_meas->full.rx_lev));
	append_tlv_u8(req_tlv, TLVID_osmo_rxqual_ul, ul_meas->full.rx_qual);

	if (mr->flags & MEAS_REP_F_DL_VALID) {
		append_tlv_u16(req_tlv, TLVID_osmo_rxlev_dl,
			       rxlev2dbm(dl_meas->full.rx_lev));
		append_tlv_u8(req_tlv, TLVID_osmo_rxqual_dl,
			      dl_meas->full.rx_qual);
	}

	if (lchan->conn && lchan->conn->vsub) {
		struct vlr_subscr *vsub = lchan->conn->vsub;
		size_t imei_len = strlen(vsub->imei);
		if (imei_len)
			append_tlv(req_tlv, TLVID_osmo_imei,
				   (uint8_t *)vsub->imei, imei_len+1);
	}
}
#endif

struct {
	uint32_t smpp_status_code;
	uint8_t gsm411_cause;
} smpp_to_gsm411_err_array[] = {

	/* Seems like most phones don't care about the failure cause,
	 * although some will display a different notification for
	 * GSM411_RP_CAUSE_MO_NUM_UNASSIGNED
	 * Some provoke a display of "Try again later"
	 * while others a more definitive "Message sending failed"
	 */

	{ ESME_RSYSERR, 	GSM411_RP_CAUSE_MO_DEST_OUT_OF_ORDER	},
	{ ESME_RINVDSTADR,	GSM411_RP_CAUSE_MO_NUM_UNASSIGNED	},
	{ ESME_RMSGQFUL,	GSM411_RP_CAUSE_MO_CONGESTION		},
	{ ESME_RINVSRCADR,	GSM411_RP_CAUSE_MO_SMS_REJECTED		},
	{ ESME_RINVMSGID,	GSM411_RP_CAUSE_INV_TRANS_REF		}
};

static int smpp_to_gsm411_err(uint32_t smpp_status_code, int *gsm411_cause)
{
	int i;
	for (i = 0; i < ARRAY_SIZE(smpp_to_gsm411_err_array); i++) {
		if (smpp_to_gsm411_err_array[i].smpp_status_code != smpp_status_code)
			continue;
		*gsm411_cause = smpp_to_gsm411_err_array[i].gsm411_cause;
		return 0;
	}
	return -1;
}

static void smpp_cmd_free(struct osmo_smpp_cmd *cmd)
{
	osmo_timer_del(&cmd->response_timer);
	llist_del(&cmd->list);
	vlr_subscr_put(cmd->vsub, VSUB_USE_SMPP_CMD);
	talloc_free(cmd);
}

void smpp_cmd_flush_pending(struct osmo_esme *esme)
{
	struct osmo_smpp_cmd *cmd, *next;

	llist_for_each_entry_safe(cmd, next, &esme->smpp_cmd_list, list)
		smpp_cmd_free(cmd);
}

void smpp_cmd_ack(struct osmo_smpp_cmd *cmd)
{
	struct ran_conn *conn;
	struct gsm_trans *trans;

	if (cmd->is_report)
		goto out;

	conn = connection_for_subscr(cmd->vsub);
	if (!conn) {
		LOGP(DSMPP, LOGL_ERROR, "No connection to subscriber anymore\n");
		goto out;
	}

	trans = trans_find_by_id(conn, GSM48_PDISC_SMS, cmd->gsm411_trans_id);
	if (!trans) {
		LOGP(DSMPP, LOGL_ERROR, "GSM transaction %u is gone\n",
		     cmd->gsm411_trans_id);
		goto out;
	}

	gsm411_send_rp_ack(trans, cmd->gsm411_msg_ref);
out:
	smpp_cmd_free(cmd);
}

void smpp_cmd_err(struct osmo_smpp_cmd *cmd, uint32_t status)
{
	struct ran_conn *conn;
	struct gsm_trans *trans;
	int gsm411_cause;

	if (cmd->is_report)
		goto out;

	conn = connection_for_subscr(cmd->vsub);
	if (!conn) {
		LOGP(DSMPP, LOGL_ERROR, "No connection to subscriber anymore\n");
		goto out;
	}

	trans = trans_find_by_id(conn, GSM48_PDISC_SMS, cmd->gsm411_trans_id);
	if (!trans) {
		LOGP(DSMPP, LOGL_ERROR, "GSM transaction %u is gone\n",
		     cmd->gsm411_trans_id);
		goto out;
	}

	if (smpp_to_gsm411_err(status, &gsm411_cause) < 0)
		gsm411_cause = GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;

	gsm411_send_rp_error(trans, cmd->gsm411_msg_ref, gsm411_cause);
out:
	smpp_cmd_free(cmd);
}

static void smpp_deliver_sm_cb(void *data)
{
	smpp_cmd_err(data, ESME_RSYSERR);
}

static int smpp_cmd_enqueue(struct osmo_esme *esme,
			    struct vlr_subscr *vsub, struct gsm_sms *sms,
			    uint32_t sequence_number)
{
	struct osmo_smpp_cmd *cmd;

	cmd = talloc_zero(esme, struct osmo_smpp_cmd);
	if (!cmd)
		return -1;

	cmd->sequence_nr	= sequence_number;
	cmd->is_report		= sms->is_report;
	cmd->gsm411_msg_ref	= sms->gsm411.msg_ref;
	cmd->gsm411_trans_id	= sms->gsm411.transaction_id;
	vlr_subscr_get(vsub, VSUB_USE_SMPP_CMD);
	cmd->vsub = vsub;

	/* FIXME: No predefined value for this response_timer as specified by
	 * SMPP 3.4 specs, section 7.2. Make this configurable? Don't forget
	 * lchan keeps busy until we get a reply to this SMPP command. Too high
	 * value may exhaust resources.
	 */
	osmo_timer_setup(&cmd->response_timer, smpp_deliver_sm_cb, cmd);
	osmo_timer_schedule(&cmd->response_timer, 5, 0);
	llist_add_tail(&cmd->list, &esme->smpp_cmd_list);

	return 0;
}

struct osmo_smpp_cmd *smpp_cmd_find_by_seqnum(struct osmo_esme *esme,
					      uint32_t sequence_nr)
{
	struct osmo_smpp_cmd *cmd;

	llist_for_each_entry(cmd, &esme->smpp_cmd_list, list) {
		if (cmd->sequence_nr == sequence_nr)
			return cmd;
	}
	return NULL;
}

static int deliver_to_esme(struct osmo_esme *esme, struct gsm_sms *sms,
			   struct ran_conn *conn)
{
	struct deliver_sm_t deliver;
	int mode, ret;
	uint8_t dcs;

	memset(&deliver, 0, sizeof(deliver));
	deliver.command_length	= 0;
	deliver.command_id	= DELIVER_SM;
	deliver.command_status	= ESME_ROK;

	strcpy((char *)deliver.service_type, "CMT");
	if (esme->acl && esme->acl->deliver_src_imsi) {
		deliver.source_addr_ton	= TON_Subscriber_Number;
		deliver.source_addr_npi = NPI_Land_Mobile_E212;
		snprintf((char *)deliver.source_addr,
			sizeof(deliver.source_addr), "%s",
			conn->vsub->imsi);
	} else {
		deliver.source_addr_ton = TON_Network_Specific;
		deliver.source_addr_npi = NPI_ISDN_E163_E164;
		snprintf((char *)deliver.source_addr,
			 sizeof(deliver.source_addr), "%s",
			 conn->vsub->msisdn);
	}

	deliver.dest_addr_ton	= sms->dst.ton;
	deliver.dest_addr_npi	= sms->dst.npi;
	memcpy(deliver.destination_addr, sms->dst.addr,
		sizeof(deliver.destination_addr));

	if (sms->is_report)
		deliver.esm_class = SMPP34_DELIVERY_RECEIPT;
	else
		deliver.esm_class = SMPP34_DATAGRAM_MODE;

	if (sms->ud_hdr_ind)
		deliver.esm_class |= SMPP34_UDHI_IND;
	if (sms->reply_path_req)
		deliver.esm_class |= SMPP34_REPLY_PATH;

	deliver.protocol_id 	= sms->protocol_id;
	deliver.priority_flag	= 0;
	if (sms->status_rep_req)
		deliver.registered_delivery = SMPP34_DELIVERY_RECEIPT_ON;

	/* Figure out SMPP DCS from TP-DCS */
	dcs = sms->data_coding_scheme;
	if (smpp_determine_scheme(dcs, &deliver.data_coding, &mode) == -1)
		return -1;

	/* Transparently pass on DCS via SMPP if requested */
	if (esme->acl && esme->acl->dcs_transparent)
		deliver.data_coding = dcs;

	if (mode == MODE_7BIT) {
		uint8_t *dst = deliver.short_message;

		/* SMPP has this strange notion of putting 7bit SMS in
		 * an octet-aligned mode */
		if (sms->ud_hdr_ind) {
			/* length (bytes) of UDH inside UD */
			uint8_t udh_len = sms->user_data[0] + 1;

			/* copy over the UDH */
			memcpy(dst, sms->user_data, udh_len);
			dst += udh_len;
			deliver.sm_length = udh_len;
		}
		/* add decoded text */
		deliver.sm_length += gsm_7bit_expand((char *)dst, sms->user_data, sms->user_data_len, sms->ud_hdr_ind);
	} else {
		deliver.sm_length = sms->user_data_len;
		memcpy(deliver.short_message, sms->user_data, deliver.sm_length);
	}

#if BEFORE_MSCSPLIT
	/* We currently have no lchan information. Re-add after A-interface, see OS#2390. */
	if (esme->acl && esme->acl->osmocom_ext && conn->lchan)
		append_osmo_tlvs(&deliver.tlv, conn->lchan);
#endif

	append_tlv_u16(&deliver.tlv, TLVID_user_message_reference,
		       sms->msg_ref);

	ret = smpp_tx_deliver(esme, &deliver);
	if (ret < 0)
		return ret;

	return smpp_cmd_enqueue(esme, conn->vsub, sms,
				deliver.sequence_number);
}

static struct smsc *g_smsc;

int smpp_route_smpp_first(struct gsm_sms *sms, struct ran_conn *conn)
{
	return g_smsc->smpp_first;
}

int smpp_try_deliver(struct gsm_sms *sms,
		     struct ran_conn *conn)
{
	struct osmo_esme *esme;
	struct osmo_smpp_addr dst;
	int rc;

	memset(&dst, 0, sizeof(dst));
	dst.ton = sms->dst.ton;
	dst.npi = sms->dst.npi;
	memcpy(dst.addr, sms->dst.addr, sizeof(dst.addr));

	rc = smpp_route(g_smsc, &dst, &esme);
	if (!rc)
		rc = deliver_to_esme(esme, sms, conn);

	return rc;
}

struct smsc *smsc_from_vty(struct vty *v)
{
	/* FIXME: this is ugly */
	return g_smsc;
}

/*! \brief Allocate the OpenBSC SMPP interface struct and init VTY. */
int smpp_openbsc_alloc_init(void *ctx)
{
	g_smsc = smpp_smsc_alloc_init(ctx);
	if (!g_smsc) {
		LOGP(DSMPP, LOGL_FATAL, "Cannot allocate smsc struct\n");
		return -1;
	}
	return smpp_vty_init();
}

/*! \brief Launch the OpenBSC SMPP interface with the parameters set from VTY.
 */
int smpp_openbsc_start(struct gsm_network *net)
{
	int rc;
	g_smsc->priv = net;

	/* If a VTY configuration has taken place, the values have been stored
	 * in the smsc struct. Otherwise, use the defaults (NULL -> any, 0 ->
	 * default SMPP port, see smpp_smsc_bind()). */
	rc = smpp_smsc_start(g_smsc, g_smsc->bind_addr, g_smsc->listen_port);
	if (rc < 0)
		return rc;

	rc = osmo_signal_register_handler(SS_SMS, smpp_sms_cb, g_smsc);
	if (rc < 0)
		return rc;
	rc = osmo_signal_register_handler(SS_SUBSCR, smpp_subscr_cb, g_smsc);
	if (rc < 0)
		return rc;

	return 0;
}

