/* SMPP 3.4 interface, SMSC-side implementation */
/* (C) 2012 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 <limits.h>

#include <sys/socket.h>
#include <netinet/in.h>

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

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

#include <osmocom/msc/debug.h>
#include <osmocom/msc/gsm_data.h>
#include <osmocom/smpp/smpp_smsc.h>

enum emse_bind {
	ESME_BIND_RX = 0x01,
	ESME_BIND_TX = 0x02,
};

const struct value_string smpp_status_strs[] = {
	{ ESME_ROK,		"No Error" },
	{ ESME_RINVMSGLEN,	"Message Length is invalid" },
	{ ESME_RINVCMDLEN,	"Command Length is invalid" },
	{ ESME_RINVCMDID,	"Invalid Command ID" },
	{ ESME_RINVBNDSTS,	"Incorrect BIND Status for given command" },
	{ ESME_RALYBND,		"ESME Already in Bound State" },
	{ ESME_RINVPRTFLG,	"Invalid Priority Flag" },
	{ ESME_RINVREGDLVFLG,	"Invalid Registered Delivery Flag" },
	{ ESME_RSYSERR,		"System Error" },
	{ ESME_RINVSRCADR,	"Invalid Source Address" },
	{ ESME_RINVDSTADR,	"Invalid Destination Address" },
	{ ESME_RINVMSGID,	"Message ID is invalid" },
	{ ESME_RBINDFAIL,	"Bind failed" },
	{ ESME_RINVPASWD,	"Invalid Password" },
	{ ESME_RINVSYSID,	"Invalid System ID" },
	{ ESME_RCANCELFAIL,	"Cancel SM Failed" },
	{ ESME_RREPLACEFAIL,	"Replace SM Failed" },
	{ ESME_RMSGQFUL,	"Message Queue Full" },
	{ ESME_RINVSERTYP,	"Invalid Service Type" },
	{ ESME_RINVNUMDESTS,	"Invalid number of destinations" },
	{ ESME_RINVDLNAME,	"Invalid Distribution List name" },
	{ ESME_RINVDESTFLAG,	"Destination flag is invalid" },
	{ ESME_RINVSUBREP,	"Invalid submit with replace request" },
	{ ESME_RINVESMCLASS,	"Invalid esm_class field data" },
	{ ESME_RCNTSUBDL,	"Cannot Submit to Distribution List" },
	{ ESME_RSUBMITFAIL,	"submit_sm or submit_multi failed" },
	{ ESME_RINVSRCTON,	"Invalid Source address TON" },
	{ ESME_RINVSRCNPI,	"Invalid Sourec address NPI" },
	{ ESME_RINVDSTTON,	"Invalid Destination address TON" },
	{ ESME_RINVDSTNPI,	"Invalid Desetination address NPI" },
	{ ESME_RINVSYSTYP,	"Invalid system_type field" },
	{ ESME_RINVREPFLAG,	"Invalid replace_if_present field" },
	{ ESME_RINVNUMMSGS,	"Invalid number of messages" },
	{ ESME_RTHROTTLED,	"Throttling error (ESME has exceeded message limits)" },
	{ ESME_RINVSCHED,	"Invalid Scheduled Delivery Time" },
	{ ESME_RINVEXPIRY,	"Invalid message validity period (Expiry time)" },
	{ ESME_RINVDFTMSGID,	"Predefined Message Invalid or Not Found" },
	{ ESME_RX_T_APPN,	"ESME Receiver Temporary App Error Code" },
	{ ESME_RX_P_APPN,	"ESME Receiver Permanent App Error Code" },
	{ ESME_RX_R_APPN,	"ESME Receiver Reject Message Error Code" },
	{ ESME_RQUERYFAIL,	"query_sm request failed" },
	{ ESME_RINVOPTPARSTREAM,"Error in the optional part of the PDU Body" },
	{ ESME_ROPTPARNOTALLWD,	"Optional Parameter not allowed" },
	{ ESME_RINVPARLEN,	"Invalid Parameter Length" },
	{ ESME_RMISSINGOPTPARAM,"Expected Optional Parameter missing" },
	{ ESME_RINVOPTPARAMVAL,	"Invalid Optional Parameter Value" },
	{ ESME_RDELIVERYFAILURE,"Delivery Failure (used for data_sm_resp)" },
	{ ESME_RUNKNOWNERR,	"Unknown Error" },
	{ 0, NULL }
};

/*! \brief compare if two SMPP addresses are equal */
int smpp_addr_eq(const struct osmo_smpp_addr *a,
		 const struct osmo_smpp_addr *b)
{
	if (a->ton == b->ton &&
	    a->npi == b->npi &&
	    !strcmp(a->addr, b->addr))
		return 1;

	return 0;
}


struct osmo_smpp_acl *smpp_acl_by_system_id(struct smsc *smsc,
					    const char *sys_id)
{
	struct osmo_smpp_acl *acl;

	llist_for_each_entry(acl, &smsc->acl_list, list) {
		if (!strcmp(acl->system_id, sys_id))
			return acl;
	}

	return NULL;
}

struct osmo_smpp_acl *smpp_acl_alloc(struct smsc *smsc, const char *sys_id)
{
	struct osmo_smpp_acl *acl;

	if (strlen(sys_id) > SMPP_SYS_ID_LEN)
		return NULL;

	if (smpp_acl_by_system_id(smsc, sys_id))
		return NULL;

	acl = talloc_zero(smsc, struct osmo_smpp_acl);
	if (!acl)
		return NULL;

	acl->smsc = smsc;
	strcpy(acl->system_id, sys_id);
	acl->alert_notifications = 1;
	INIT_LLIST_HEAD(&acl->route_list);

	llist_add_tail(&acl->list, &smsc->acl_list);

	return acl;
}

void smpp_acl_delete(struct osmo_smpp_acl *acl)
{
	struct osmo_smpp_route *r, *r2;

	llist_del(&acl->list);

	/* kill any active ESMEs */
	if (acl->esme) {
		struct osmo_esme *esme = acl->esme;
		osmo_fd_unregister(&esme->wqueue.bfd);
		close(esme->wqueue.bfd.fd);
		esme->wqueue.bfd.fd = -1;
		esme->acl = NULL;
		smpp_esme_put(esme);
	}

	/* delete all routes for this ACL */
	llist_for_each_entry_safe(r, r2, &acl->route_list, list) {
		llist_del(&r->list);
		llist_del(&r->global_list);
		talloc_free(r);
	}

	talloc_free(acl);
}

static struct osmo_smpp_route *route_alloc(struct osmo_smpp_acl *acl)
{
	struct osmo_smpp_route *r;

	r = talloc_zero(acl, struct osmo_smpp_route);
	if (!r)
		return NULL;

	llist_add_tail(&r->list, &acl->route_list);
	llist_add_tail(&r->global_list, &acl->smsc->route_list);

	return r;
}

int smpp_route_pfx_add(struct osmo_smpp_acl *acl,
			const struct osmo_smpp_addr *pfx)
{
	struct osmo_smpp_route *r;

	llist_for_each_entry(r, &acl->route_list, list) {
		if (r->type == SMPP_ROUTE_PREFIX &&
		    smpp_addr_eq(&r->u.prefix, pfx))
			return -EEXIST;
	}

	r = route_alloc(acl);
	if (!r)
		return -ENOMEM;
	r->type = SMPP_ROUTE_PREFIX;
	r->acl = acl;
	memcpy(&r->u.prefix, pfx, sizeof(r->u.prefix));

	return 0;
}

int smpp_route_pfx_del(struct osmo_smpp_acl *acl,
		       const struct osmo_smpp_addr *pfx)
{
	struct osmo_smpp_route *r, *r2;

	llist_for_each_entry_safe(r, r2, &acl->route_list, list) {
		if (r->type == SMPP_ROUTE_PREFIX &&
		    smpp_addr_eq(&r->u.prefix, pfx)) {
			llist_del(&r->list);
			talloc_free(r);
			return 0;
		}
	}

	return -ENODEV;
}


/*! \brief increaes the use/reference count */
void smpp_esme_get(struct osmo_esme *esme)
{
	esme->use++;
}

static void esme_destroy(struct osmo_esme *esme)
{
	osmo_wqueue_clear(&esme->wqueue);
	if (esme->wqueue.bfd.fd >= 0) {
		osmo_fd_unregister(&esme->wqueue.bfd);
		close(esme->wqueue.bfd.fd);
	}
	smpp_cmd_flush_pending(esme);
	llist_del(&esme->list);
	if (esme->acl)
		esme->acl->esme = NULL;
	talloc_free(esme);
}

static uint32_t esme_inc_seq_nr(struct osmo_esme *esme)
{
	esme->own_seq_nr++;
	if (esme->own_seq_nr > 0x7fffffff)
		esme->own_seq_nr = 1;

	return esme->own_seq_nr;
}

/*! \brief decrease the use/reference count, free if it is 0 */
void smpp_esme_put(struct osmo_esme *esme)
{
	esme->use--;
	if (esme->use <= 0)
		esme_destroy(esme);
}

/*! \brief try to find a SMPP route (ESME) for given destination */
int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struct osmo_esme **pesme)
{
	struct osmo_smpp_route *r;
	struct osmo_smpp_acl *acl = NULL;

	DEBUGP(DSMPP, "Looking up route for (%u/%u/%s)\n",
		dest->ton, dest->npi, dest->addr);

	/* search for a specific route */
	llist_for_each_entry(r, &smsc->route_list, global_list) {
		switch (r->type) {
		case SMPP_ROUTE_PREFIX:
			DEBUGP(DSMPP, "Checking prefix route (%u/%u/%s)->%s\n",
				r->u.prefix.ton, r->u.prefix.npi, r->u.prefix.addr,
				r->acl->system_id);
			if (r->u.prefix.ton == dest->ton &&
			    r->u.prefix.npi == dest->npi &&
			    !strncmp(r->u.prefix.addr, dest->addr,
				     strlen(r->u.prefix.addr))) {
				DEBUGP(DSMPP, "Found prefix route ACL\n");
				acl = r->acl;
			}
			break;
		default:
			break;
		}

		if (acl)
			break;
	}

	if (!acl) {
		/* check for default route */
		if (smsc->def_route) {
			DEBUGP(DSMPP, "Using existing default route\n");
			acl = smsc->def_route;
		}
	}

	if (acl && acl->esme) {
		struct osmo_esme *esme;
		DEBUGP(DSMPP, "ACL even has ESME, we can route to it!\n");
		esme = acl->esme;
		if (esme->bind_flags & ESME_BIND_RX) {
			*pesme = esme;
			return 0;
		} else
			LOGPESME(esme, LOGL_NOTICE, "is matching route, but not bound for Rx, discarding MO SMS\n");
	}

	*pesme = NULL;
	if (acl)
		return GSM411_RP_CAUSE_MO_NET_OUT_OF_ORDER;
	else
		return GSM411_RP_CAUSE_MO_NUM_UNASSIGNED;
}

/*! \brief pack a libsmpp34 data strcutrure and send it to the ESME */
static int pack_and_send(struct osmo_esme *esme, uint32_t type, void *ptr)
{
	struct msgb *msg;
	int rc, rlen;

	/* the socket was closed. Avoid allocating + enqueueing msgb, see
	 * https://osmocom.org/issues/3278 */
	if (esme->wqueue.bfd.fd == -1)
		return -EIO;

	msg = msgb_alloc(4096, "SMPP_Tx");
	if (!msg)
		return -ENOMEM;

	rc = smpp34_pack(type, msg->tail, msgb_tailroom(msg), &rlen, ptr);
	if (rc != 0) {
		LOGPESMERR(esme, "during smpp34_pack()\n");
		msgb_free(msg);
		return -EINVAL;
	}
	msgb_put(msg, rlen);

	if (osmo_wqueue_enqueue(&esme->wqueue, msg) != 0) {
		LOGPESME(esme, LOGL_ERROR, "Write queue full. Dropping message\n");
		msgb_free(msg);
		return -EAGAIN;
	}
	return 0;
}

/*! \brief transmit a generic NACK to a remote ESME */
static int smpp_tx_gen_nack(struct osmo_esme *esme, uint32_t seq, uint32_t status)
{
	struct generic_nack_t nack;
	char buf[SMALL_BUFF];

	nack.command_length = 0;
	nack.command_id = GENERIC_NACK;
	nack.sequence_number = seq;
	nack.command_status = status;

	LOGPESME(esme, LOGL_ERROR, "Tx GENERIC NACK: %s\n", str_command_status(status, buf));

	return PACK_AND_SEND(esme, &nack);
}

/*! \brief retrieve SMPP sequence number from a msgb */
static inline uint32_t smpp_msgb_seq(struct msgb *msg)
{
	uint8_t *tmp = msgb_data(msg);
	return ntohl(*(uint32_t *)tmp);
}

/*! \brief handle an incoming SMPP generic NACK */
static int smpp_handle_gen_nack(struct osmo_esme *esme, struct msgb *msg)
{
	struct generic_nack_t nack;
	char buf[SMALL_BUFF];
	int rc;

	SMPP34_UNPACK(rc, GENERIC_NACK, &nack, msgb_data(msg),
			 msgb_length(msg));
	if (rc < 0) {
		LOGPESMERR(esme, "in smpp34_unpack()\n");
		return rc;
	}

	LOGPESME(esme, LOGL_ERROR, "Rx GENERIC NACK: %s\n", str_command_status(nack.command_status, buf));

	return 0;
}

static int _process_bind(struct osmo_esme *esme, uint8_t if_version,
			 uint32_t bind_flags, const char *sys_id,
			 const char *passwd)
{
	struct osmo_smpp_acl *acl;

	if (if_version != SMPP_VERSION)
		return ESME_RSYSERR;

	if (esme->bind_flags)
		return ESME_RALYBND;

	esme->smpp_version = if_version;
	snprintf(esme->system_id, sizeof(esme->system_id), "%s", sys_id);

	acl = smpp_acl_by_system_id(esme->smsc, esme->system_id);
	if (!esme->smsc->accept_all) {
		if (!acl) {
			/* This system is unknown */
			return ESME_RINVSYSID;
		} else {
			if (strlen(acl->passwd) &&
			    strcmp(acl->passwd, passwd)) {
				return ESME_RINVPASWD;
			}
		}
	}
	if (acl) {
		esme->acl = acl;
		acl->esme = esme;
	}

	esme->bind_flags = bind_flags;

	return ESME_ROK;
}


/*! \brief handle an incoming SMPP BIND RECEIVER */
static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg)
{
	struct bind_receiver_t bind;
	struct bind_receiver_resp_t bind_r;
	int rc;

	SMPP34_UNPACK(rc, BIND_RECEIVER, &bind, msgb_data(msg),
			   msgb_length(msg));
	if (rc < 0) {
		LOGPESMERR(esme, "in smpp34_unpack()\n");
		return rc;
	}

	INIT_RESP(BIND_TRANSMITTER_RESP, &bind_r, &bind);

	LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Rx from (Version %02x)\n",
		bind.system_id, bind.interface_version);

	rc = _process_bind(esme, bind.interface_version, ESME_BIND_RX,
			   (const char *)bind.system_id, (const char *)bind.password);
	bind_r.command_status = rc;

	return PACK_AND_SEND(esme, &bind_r);
}

/*! \brief handle an incoming SMPP BIND TRANSMITTER */
static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg)
{
	struct bind_transmitter_t bind;
	struct bind_transmitter_resp_t bind_r;
	struct tlv_t tlv;
	int rc;

	SMPP34_UNPACK(rc, BIND_TRANSMITTER, &bind, msgb_data(msg),
			   msgb_length(msg));
	if (rc < 0) {
		LOGPESMERR(esme, "in smpp34_unpack()\n");
		return rc;
	}

	INIT_RESP(BIND_TRANSMITTER_RESP, &bind_r, &bind);

	LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Tx (Version %02x)\n",
		bind.system_id, bind.interface_version);

	rc = _process_bind(esme, bind.interface_version, ESME_BIND_TX,
			   (const char *)bind.system_id, (const char *)bind.password);
	bind_r.command_status = rc;

	/* build response */
	osmo_strlcpy((char*)bind_r.system_id, esme->smsc->system_id, sizeof(bind_r.system_id));

	/* add interface version TLV */
	tlv.tag = TLVID_sc_interface_version;
	tlv.length = sizeof(uint8_t);
	tlv.value.val16 = esme->smpp_version;
	build_tlv(&bind_r.tlv, &tlv);

	rc = PACK_AND_SEND(esme, &bind_r);
	destroy_tlv(bind_r.tlv);
	return rc;
}

/*! \brief handle an incoming SMPP BIND TRANSCEIVER */
static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg)
{
	struct bind_transceiver_t bind;
	struct bind_transceiver_resp_t bind_r;
	int rc;

	SMPP34_UNPACK(rc, BIND_TRANSCEIVER, &bind, msgb_data(msg),
			   msgb_length(msg));
	if (rc < 0) {
		LOGPESMERR(esme, "in smpp34_unpack()\n");
		return rc;
	}

	INIT_RESP(BIND_TRANSCEIVER_RESP, &bind_r, &bind);

	LOGP(DSMPP, LOGL_INFO, "[%s] Rx BIND Trx (Version %02x)\n",
		bind.system_id, bind.interface_version);

	rc = _process_bind(esme, bind.interface_version, ESME_BIND_RX|ESME_BIND_TX,
			   (const char *)bind.system_id, (const char *)bind.password);
	bind_r.command_status = rc;

	return PACK_AND_SEND(esme, &bind_r);
}

/*! \brief handle an incoming SMPP UNBIND */
static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg)
{
	struct unbind_t unbind;
	struct unbind_resp_t unbind_r;
	int rc;

	SMPP34_UNPACK(rc, UNBIND, &unbind, msgb_data(msg),
			   msgb_length(msg));
	if (rc < 0) {
		LOGPESMERR(esme, "in smpp34_unpack()\n");
		return rc;
	}

	INIT_RESP(UNBIND_RESP, &unbind_r, &unbind);

	LOGPESME(esme, LOGL_INFO, "Rx UNBIND\n");

	if (esme->bind_flags == 0) {
		unbind_r.command_status = ESME_RINVBNDSTS;
		goto err;
	}

	esme->bind_flags = 0;
err:
	return PACK_AND_SEND(esme, &unbind_r);
}

/*! \brief handle an incoming SMPP ENQUIRE LINK */
static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg)
{
	struct enquire_link_t enq;
	struct enquire_link_resp_t enq_r;
	int rc;

	SMPP34_UNPACK(rc, ENQUIRE_LINK, &enq, msgb_data(msg),
			   msgb_length(msg));
	if (rc < 0) {
		LOGPESMERR(esme, "in smpp34_unpack()\n");
		return rc;
	}

	LOGPESME(esme, LOGL_DEBUG, "Rx Enquire Link\n");

	INIT_RESP(ENQUIRE_LINK_RESP, &enq_r, &enq);

	LOGPESME(esme, LOGL_DEBUG, "Tx Enquire Link Response\n");

	return PACK_AND_SEND(esme, &enq_r);
}

/*! \brief send a SUBMIT-SM RESPONSE to a remote ESME */
int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr,
		     uint32_t command_status, char *msg_id)
{
	struct submit_sm_resp_t submit_r;

	memset(&submit_r, 0, sizeof(submit_r));
	submit_r.command_length	= 0;
	submit_r.command_id	= SUBMIT_SM_RESP;
	submit_r.command_status	= command_status;
	submit_r.sequence_number= sequence_nr;
	snprintf((char *) submit_r.message_id, sizeof(submit_r.message_id), "%s", msg_id);

	return PACK_AND_SEND(esme, &submit_r);
}

static const struct value_string smpp_avail_strs[] = {
	{ 0,	"Available" },
	{ 1,	"Denied" },
	{ 2,	"Unavailable" },
	{ 0,	NULL }
};

/*! \brief send an ALERT_NOTIFICATION to a remote ESME */
int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
		  const char *addr, uint8_t avail_status)
{
	struct alert_notification_t alert;
	struct tlv_t tlv;
	int rc;

	memset(&alert, 0, sizeof(alert));
	alert.command_length	= 0;
	alert.command_id	= ALERT_NOTIFICATION;
	alert.command_status	= ESME_ROK;
	alert.sequence_number	= esme_inc_seq_nr(esme);
	alert.source_addr_ton 	= ton;
	alert.source_addr_npi	= npi;
	snprintf((char *)alert.source_addr, sizeof(alert.source_addr), "%s", addr);

	tlv.tag = TLVID_ms_availability_status;
	tlv.length = sizeof(uint8_t);
	tlv.value.val08 = avail_status;
	build_tlv(&alert.tlv, &tlv);

	LOGPESME(esme, LOGL_DEBUG, "Tx ALERT_NOTIFICATION (%s/%u/%u): %s\n",
			 alert.source_addr, alert.source_addr_ton,
			 alert.source_addr_npi,
			 get_value_string(smpp_avail_strs, avail_status));

	rc = PACK_AND_SEND(esme, &alert);
	destroy_tlv(alert.tlv);
	return rc;
}

/* \brief send a DELIVER-SM message to given ESME */
int smpp_tx_deliver(struct osmo_esme *esme, struct deliver_sm_t *deliver)
{
	deliver->sequence_number = esme_inc_seq_nr(esme);

	LOGPESME(esme, LOGL_DEBUG, "Tx DELIVER-SM (from %s)\n", deliver->source_addr);

	return PACK_AND_SEND(esme, deliver);
}

/*! \brief handle an incoming SMPP DELIVER-SM RESPONSE */
static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg)
{
	struct deliver_sm_resp_t deliver_r;
	struct osmo_smpp_cmd *cmd;
	int rc;

	memset(&deliver_r, 0, sizeof(deliver_r));
	SMPP34_UNPACK(rc, DELIVER_SM_RESP, &deliver_r, msgb_data(msg),
			   msgb_length(msg));
	if (rc < 0) {
		LOGPESMERR(esme, "in smpp34_unpack()\n");
		return rc;
	}

	cmd = smpp_cmd_find_by_seqnum(esme, deliver_r.sequence_number);
	if (!cmd) {
		LOGPESME(esme, LOGL_ERROR, "Rx DELIVER-SM RESP !? (%s)\n",
				 get_value_string(smpp_status_strs, deliver_r.command_status));
		return -1;
	}

	if (deliver_r.command_status == ESME_ROK)
		smpp_cmd_ack(cmd);
	else
		smpp_cmd_err(cmd, deliver_r.command_status);

	LOGPESME(esme, LOGL_INFO, "Rx DELIVER-SM RESP (%s)\n",
			 get_value_string(smpp_status_strs, deliver_r.command_status));

	return 0;
}

/*! \brief handle an incoming SMPP SUBMIT-SM */
static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg)
{
	struct submit_sm_t submit;
	struct submit_sm_resp_t submit_r;
	int rc;

	memset(&submit, 0, sizeof(submit));
	SMPP34_UNPACK(rc, SUBMIT_SM, &submit, msgb_data(msg),
			   msgb_length(msg));
	if (rc < 0) {
		LOGPESMERR(esme, "in smpp34_unpack()\n");
		return rc;
	}

	INIT_RESP(SUBMIT_SM_RESP, &submit_r, &submit);

	if (!(esme->bind_flags & ESME_BIND_TX)) {
		submit_r.command_status = ESME_RINVBNDSTS;
		return PACK_AND_SEND(esme, &submit_r);
	}

	LOGPESME(esme, LOGL_INFO, "Rx SUBMIT-SM (%s/%u/%u)\n",
			 submit.destination_addr, submit.dest_addr_ton, submit.dest_addr_npi);

	INIT_RESP(SUBMIT_SM_RESP, &submit_r, &submit);

	rc = handle_smpp_submit(esme, &submit, &submit_r);
	if (rc == 0)
		return PACK_AND_SEND(esme, &submit_r);

	return rc;
}

/*! \brief one complete SMPP PDU from the ESME has been received */
static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses)
{
	uint32_t cmd_id = smpp_msgb_cmdid(msg);
	int rc = 0;

	LOGPESME(esme, LOGL_DEBUG, "smpp_pdu_rx(%s)\n", msgb_hexdump(msg));

	switch (cmd_id) {
	case GENERIC_NACK:
		rc = smpp_handle_gen_nack(esme, msg);
		break;
	case BIND_RECEIVER:
		rc = smpp_handle_bind_rx(esme, msg);
		break;
	case BIND_TRANSMITTER:
		rc = smpp_handle_bind_tx(esme, msg);
		break;
	case BIND_TRANSCEIVER:
		rc = smpp_handle_bind_trx(esme, msg);
		break;
	case UNBIND:
		rc = smpp_handle_unbind(esme, msg);
		break;
	case ENQUIRE_LINK:
		rc = smpp_handle_enq_link(esme, msg);
		break;
	case SUBMIT_SM:
		rc = smpp_handle_submit(esme, msg);
		break;
	case DELIVER_SM_RESP:
		rc = smpp_handle_deliver_resp(esme, msg);
		break;
	case DELIVER_SM:
		break;
	case DATA_SM:
		break;
	case CANCEL_SM:
	case QUERY_SM:
	case REPLACE_SM:
	case SUBMIT_MULTI:
		LOGPESME(esme, LOGL_NOTICE, "Unimplemented PDU Command 0x%08x\n", cmd_id);
		break;
	default:
		LOGPESME(esme, LOGL_ERROR, "Unknown PDU Command 0x%08x\n", cmd_id);
		rc = smpp_tx_gen_nack(esme, smpp_msgb_seq(msg), ESME_RINVCMDID);
		break;
	}

	return rc;
}

/* This macro should be called after a call to read() in the read_cb of an
 * osmo_fd to properly check for errors.
 * rc is the return value of read, err_label is the label to jump to in case of
 * an error. The code there should handle closing the connection.
 * FIXME: This code should go in libosmocore utils.h so it can be used by other
 * projects as well.
 * */
#define OSMO_FD_CHECK_READ(rc, err_label) \
	if (rc < 0) { \
		/* EINTR is a non-fatal error, just try again */ \
		if (errno == EINTR) \
			return 0; \
		goto err_label; \
	} else if (rc == 0) { \
		goto err_label; \
	}

/* !\brief call-back when per-ESME TCP socket has some data to be read */
static int esme_link_read_cb(struct osmo_fd *ofd)
{
	struct osmo_esme *esme = ofd->data;
	uint32_t len;
	uint8_t *lenptr = (uint8_t *) &len;
	uint8_t *cur;
	struct msgb *msg;
	ssize_t rdlen, rc;

	switch (esme->read_state) {
	case READ_ST_IN_LEN:
		rdlen = sizeof(uint32_t) - esme->read_idx;
		rc = read(ofd->fd, lenptr + esme->read_idx, rdlen);
		if (rc < 0)
			LOGPESME(esme, LOGL_ERROR, "read returned %zd (%s)\n", rc, strerror(errno));
		OSMO_FD_CHECK_READ(rc, dead_socket);

		esme->read_idx += rc;

		if (esme->read_idx >= sizeof(uint32_t)) {
			esme->read_len = ntohl(len);
			if (esme->read_len < 8 || esme->read_len > UINT16_MAX) {
				LOGPESME(esme, LOGL_ERROR, "length invalid %u\n",  esme->read_len);
				goto dead_socket;
			}

			msg = msgb_alloc(esme->read_len, "SMPP Rx");
			if (!msg)
				return -ENOMEM;
			esme->read_msg = msg;
			cur = msgb_put(msg, sizeof(uint32_t));
			memcpy(cur, lenptr, sizeof(uint32_t));
			esme->read_state = READ_ST_IN_MSG;
			esme->read_idx = sizeof(uint32_t);
		}
		break;
	case READ_ST_IN_MSG:
		msg = esme->read_msg;
		rdlen = esme->read_len - esme->read_idx;
		rc = read(ofd->fd, msg->tail, OSMO_MIN(rdlen, msgb_tailroom(msg)));
		if (rc < 0)
			LOGPESME(esme, LOGL_ERROR, "read returned %zd (%s)\n",
					rc, strerror(errno));
		OSMO_FD_CHECK_READ(rc, dead_socket);

		esme->read_idx += rc;
		msgb_put(msg, rc);

		if (esme->read_idx >= esme->read_len) {
			rc = smpp_pdu_rx(esme, esme->read_msg);
			msgb_free(esme->read_msg);
			esme->read_msg = NULL;
			esme->read_idx = 0;
			esme->read_len = 0;
			esme->read_state = READ_ST_IN_LEN;
		}
		break;
	}

	return 0;
dead_socket:
	msgb_free(esme->read_msg);
	osmo_fd_unregister(&esme->wqueue.bfd);
	close(esme->wqueue.bfd.fd);
	esme->wqueue.bfd.fd = -1;
	if (esme->acl)
		esme->acl->esme = NULL;
	smpp_esme_put(esme);

	return -EBADF;
}

/* call-back of write queue once it wishes to write a message to the socket */
static int esme_link_write_cb(struct osmo_fd *ofd, struct msgb *msg)
{
	struct osmo_esme *esme = ofd->data;
	int rc;

	rc = write(ofd->fd, msgb_data(msg), msgb_length(msg));
	if (rc == 0) {
		osmo_fd_unregister(&esme->wqueue.bfd);
		close(esme->wqueue.bfd.fd);
		esme->wqueue.bfd.fd = -1;
		if (esme->acl)
			esme->acl->esme = NULL;
		smpp_esme_put(esme);
	} else if (rc < msgb_length(msg)) {
		LOGPESME(esme, LOGL_ERROR, "Short write\n");
		return -1;
	}

	return 0;
}

/* callback for already-accepted new TCP socket */
static int link_accept_cb(struct smsc *smsc, int fd,
			  struct sockaddr_storage *s, socklen_t s_len)
{
	struct osmo_esme *esme = talloc_zero(smsc, struct osmo_esme);
	if (!esme) {
		close(fd);
		return -ENOMEM;
	}

	INIT_LLIST_HEAD(&esme->smpp_cmd_list);
	smpp_esme_get(esme);
	esme->own_seq_nr = rand();
	esme_inc_seq_nr(esme);
	esme->smsc = smsc;
	osmo_wqueue_init(&esme->wqueue, 10);
	osmo_fd_setup(&esme->wqueue.bfd, fd, OSMO_FD_READ, osmo_wqueue_bfd_cb, esme, 0);

	if (osmo_fd_register(&esme->wqueue.bfd) != 0) {
		close(fd);
		talloc_free(esme);
		return -EIO;
	}

	esme->wqueue.read_cb = esme_link_read_cb;
	esme->wqueue.write_cb = esme_link_write_cb;

	llist_add_tail(&esme->list, &smsc->esme_list);

	return 0;
}

/* callback of listening TCP socket */
static int smsc_fd_cb(struct osmo_fd *ofd, unsigned int what)
{
	int rc;
	struct sockaddr_storage sa;
	socklen_t sa_len = sizeof(sa);

	rc = accept(ofd->fd, (struct sockaddr *)&sa, &sa_len);
	if (rc < 0) {
		LOGP(DSMPP, LOGL_ERROR, "Accept returns %d (%s)\n",
		     rc, strerror(errno));
		return rc;
	}
	return link_accept_cb(ofd->data, rc, &sa, sa_len);
}

/*! \brief allocate and initialize an smsc struct from talloc context ctx. */
struct smsc *smpp_smsc_alloc_init(void *ctx)
{
	struct smsc *smsc = talloc_zero(ctx, struct smsc);

	INIT_LLIST_HEAD(&smsc->esme_list);
	INIT_LLIST_HEAD(&smsc->acl_list);
	INIT_LLIST_HEAD(&smsc->route_list);

	smsc->listen_ofd.data = smsc;
	smsc->listen_ofd.cb = smsc_fd_cb;

	return smsc;
}

/*! \brief Set the SMPP address and port without binding. */
int smpp_smsc_conf(struct smsc *smsc, const char *bind_addr, uint16_t port)
{
	smsc->listen_port = port;

	/* Avoid use-after-free if bind_addr == smsc->bind_addr */
	if (smsc->bind_addr == bind_addr)
		return 0;
	osmo_talloc_replace_string(smsc, &smsc->bind_addr, bind_addr);

	return 0;
}

/*! \brief Bind to given address and port and accept connections.
 * \param[in] bind_addr Local IP address, may be NULL for any.
 * \param[in] port TCP port number, may be 0 for default SMPP (2775).
 */
int smpp_smsc_start(struct smsc *smsc, const char *bind_addr, uint16_t port)
{
	int rc;

	/* default port for SMPP */
	if (!port)
		port = 2775;

	LOGP(DSMPP, LOGL_NOTICE, "SMPP at %s %d\n",
	     bind_addr? bind_addr : "0.0.0.0", port);

	rc = osmo_sock_init_ofd(&smsc->listen_ofd, AF_UNSPEC, SOCK_STREAM,
				IPPROTO_TCP, bind_addr, port,
				OSMO_SOCK_F_BIND);
	if (rc < 0)
		return rc;

	/* store new address and port */
	rc = smpp_smsc_conf(smsc, bind_addr, port);
	if (rc)
		smpp_smsc_stop(smsc);
	return rc;
}

/*! \brief Change a running connection to a different address/port, and upon
 * error switch back to the running configuration. */
int smpp_smsc_restart(struct smsc *smsc, const char *bind_addr, uint16_t port)
{
	int rc;

	smpp_smsc_stop(smsc);

	rc = smpp_smsc_start(smsc, bind_addr, port);
	if (rc)
		/* if there is an error, try to re-bind to the old port */
		return smpp_smsc_start(smsc, smsc->bind_addr, smsc->listen_port);
	return 0;
}

/*! /brief Close SMPP connection. */
void smpp_smsc_stop(struct smsc *smsc)
{
	if (smsc->listen_ofd.fd > 0) {
		close(smsc->listen_ofd.fd);
		smsc->listen_ofd.fd = 0;
		osmo_fd_unregister(&smsc->listen_ofd);
	}
}
