Make esme struct shared

This helps to merge similar code from smpp_mirror and smpp_* in follow-up patches.

Related: OS#5568
Change-Id: I8f7ac2c00d16660925dd0b03aa1a0973edf9eb70
This commit is contained in:
Max 2022-07-29 23:11:58 +07:00
parent 796c5561e7
commit 84b655bed5
6 changed files with 86 additions and 91 deletions

View File

@ -11,6 +11,20 @@ enum esme_read_state {
READ_ST_IN_MSG = 1,
};
struct esme {
uint32_t own_seq_nr;
struct osmo_wqueue wqueue;
enum esme_read_state read_state;
uint32_t read_len;
uint32_t read_idx;
struct msgb *read_msg;
uint8_t smpp_version;
char system_id[SMPP_SYS_ID_LEN + 1];
char password[SMPP_SYS_ID_LEN + 1];
};
#define LOGPESME(ESME, LEVEL, FMT, ARGS...) \
LOGP(DSMPP, LEVEL, "[%s] " FMT, (ESME)->system_id, ##ARGS)

View File

@ -342,7 +342,7 @@ static void alert_all_esme(struct smsc *smsc, struct vlr_subscr *vsub,
continue;
}
if (esme->acl && !esme->acl->alert_notifications) {
LOGPESME(esme, LOGL_DEBUG, "is not set to receive Alert Notifications\n");
LOGPESME(esme->esme, LOGL_DEBUG, "is not set to receive Alert Notifications\n");
continue;
}
if (esme->acl && esme->acl->deliver_src_imsi) {

View File

@ -160,12 +160,12 @@ void smpp_acl_delete(struct osmo_smpp_acl *acl)
/* kill any active ESMEs */
if (acl->esme) {
struct osmo_esme *esme = acl->esme;
struct esme *esme = acl->esme->esme;
osmo_fd_unregister(&esme->wqueue.bfd);
close(esme->wqueue.bfd.fd);
esme->wqueue.bfd.fd = -1;
esme->acl = NULL;
smpp_esme_put(esme);
acl->esme = NULL;
smpp_esme_put(acl->esme);
}
/* delete all routes for this ACL */
@ -239,10 +239,10 @@ void smpp_esme_get(struct osmo_esme *esme)
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);
osmo_wqueue_clear(&esme->esme->wqueue);
if (esme->esme->wqueue.bfd.fd >= 0) {
osmo_fd_unregister(&esme->esme->wqueue.bfd);
close(esme->esme->wqueue.bfd.fd);
}
smpp_cmd_flush_pending(esme);
llist_del(&esme->list);
@ -251,7 +251,7 @@ static void esme_destroy(struct osmo_esme *esme)
talloc_free(esme);
}
static uint32_t esme_inc_seq_nr(struct osmo_esme *esme)
static uint32_t esme_inc_seq_nr(struct esme *esme)
{
esme->own_seq_nr++;
if (esme->own_seq_nr > 0x7fffffff)
@ -316,7 +316,7 @@ int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struc
*pesme = esme;
return 0;
} else
LOGPESME(esme, LOGL_NOTICE, "is matching route, but not bound for Rx, discarding MO SMS\n");
LOGPESME(esme->esme, LOGL_NOTICE, "is matching route, but not bound for Rx, discarding MO SMS\n");
}
*pesme = NULL;
@ -327,7 +327,7 @@ int smpp_route(const struct smsc *smsc, const struct osmo_smpp_addr *dest, struc
}
/*! \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)
static int pack_and_send(struct esme *esme, uint32_t type, void *ptr)
{
struct msgb *msg;
int rc, rlen;
@ -358,7 +358,7 @@ static int pack_and_send(struct osmo_esme *esme, uint32_t type, void *ptr)
}
/*! \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)
static int smpp_tx_gen_nack(struct esme *esme, uint32_t seq, uint32_t status)
{
struct generic_nack_t nack;
char buf[SMALL_BUFF];
@ -390,11 +390,11 @@ static int smpp_handle_gen_nack(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, GENERIC_NACK, &nack, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
LOGPESMERR(esme, "in smpp34_unpack()\n");
LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
LOGPESME(esme, LOGL_ERROR, "Rx GENERIC NACK: %s\n", str_command_status(nack.command_status, buf));
LOGPESME(esme->esme, LOGL_ERROR, "Rx GENERIC NACK: %s\n", str_command_status(nack.command_status, buf));
return 0;
}
@ -412,9 +412,9 @@ static int _process_bind(struct osmo_esme *esme, uint8_t if_version,
return ESME_RALYBND;
esme->smpp_version = if_version;
snprintf(esme->system_id, sizeof(esme->system_id), "%s", sys_id);
snprintf(esme->esme->system_id, sizeof(esme->esme->system_id), "%s", sys_id);
acl = smpp_acl_by_system_id(esme->smsc, esme->system_id);
acl = smpp_acl_by_system_id(esme->smsc, esme->esme->system_id);
if (!esme->smsc->accept_all) {
if (!acl) {
/* This system is unknown */
@ -447,7 +447,7 @@ static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, BIND_RECEIVER, &bind, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
LOGPESMERR(esme, "in smpp34_unpack()\n");
LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
@ -460,7 +460,7 @@ static int smpp_handle_bind_rx(struct osmo_esme *esme, struct msgb *msg)
(const char *)bind.system_id, (const char *)bind.password);
bind_r.command_status = rc;
return PACK_AND_SEND(esme, &bind_r);
return PACK_AND_SEND(esme->esme, &bind_r);
}
/*! \brief handle an incoming SMPP BIND TRANSMITTER */
@ -474,7 +474,7 @@ static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, BIND_TRANSMITTER, &bind, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
LOGPESMERR(esme, "in smpp34_unpack()\n");
LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
@ -496,7 +496,7 @@ static int smpp_handle_bind_tx(struct osmo_esme *esme, struct msgb *msg)
tlv.value.val16 = esme->smpp_version;
build_tlv(&bind_r.tlv, &tlv);
rc = PACK_AND_SEND(esme, &bind_r);
rc = PACK_AND_SEND(esme->esme, &bind_r);
destroy_tlv(bind_r.tlv);
return rc;
}
@ -511,7 +511,7 @@ static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, BIND_TRANSCEIVER, &bind, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
LOGPESMERR(esme, "in smpp34_unpack()\n");
LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
@ -524,7 +524,7 @@ static int smpp_handle_bind_trx(struct osmo_esme *esme, struct msgb *msg)
(const char *)bind.system_id, (const char *)bind.password);
bind_r.command_status = rc;
return PACK_AND_SEND(esme, &bind_r);
return PACK_AND_SEND(esme->esme, &bind_r);
}
/*! \brief handle an incoming SMPP UNBIND */
@ -537,13 +537,13 @@ static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, UNBIND, &unbind, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
LOGPESMERR(esme, "in smpp34_unpack()\n");
LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
INIT_RESP(UNBIND_RESP, &unbind_r, &unbind);
LOGPESME(esme, LOGL_INFO, "Rx UNBIND\n");
LOGPESME(esme->esme, LOGL_INFO, "Rx UNBIND\n");
if (esme->bind_flags == 0) {
unbind_r.command_status = ESME_RINVBNDSTS;
@ -552,7 +552,7 @@ static int smpp_handle_unbind(struct osmo_esme *esme, struct msgb *msg)
esme->bind_flags = 0;
err:
return PACK_AND_SEND(esme, &unbind_r);
return PACK_AND_SEND(esme->esme, &unbind_r);
}
/*! \brief handle an incoming SMPP ENQUIRE LINK */
@ -565,17 +565,17 @@ static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, ENQUIRE_LINK, &enq, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
LOGPESMERR(esme, "in smpp34_unpack()\n");
LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
LOGPESME(esme, LOGL_DEBUG, "Rx Enquire Link\n");
LOGPESME(esme->esme, LOGL_DEBUG, "Rx Enquire Link\n");
INIT_RESP(ENQUIRE_LINK_RESP, &enq_r, &enq);
LOGPESME(esme, LOGL_DEBUG, "Tx Enquire Link Response\n");
LOGPESME(esme->esme, LOGL_DEBUG, "Tx Enquire Link Response\n");
return PACK_AND_SEND(esme, &enq_r);
return PACK_AND_SEND(esme->esme, &enq_r);
}
/*! \brief send a SUBMIT-SM RESPONSE to a remote ESME */
@ -591,7 +591,7 @@ int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr,
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);
return PACK_AND_SEND(esme->esme, &submit_r);
}
static const struct value_string smpp_avail_strs[] = {
@ -613,7 +613,7 @@ int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
alert.command_length = 0;
alert.command_id = ALERT_NOTIFICATION;
alert.command_status = ESME_ROK;
alert.sequence_number = esme_inc_seq_nr(esme);
alert.sequence_number = esme_inc_seq_nr(esme->esme);
alert.source_addr_ton = ton;
alert.source_addr_npi = npi;
snprintf((char *)alert.source_addr, sizeof(alert.source_addr), "%s", addr);
@ -623,12 +623,12 @@ int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
tlv.value.val08 = avail_status;
build_tlv(&alert.tlv, &tlv);
LOGPESME(esme, LOGL_DEBUG, "Tx ALERT_NOTIFICATION (%s/%u/%u): %s\n",
LOGPESME(esme->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);
rc = PACK_AND_SEND(esme->esme, &alert);
destroy_tlv(alert.tlv);
return rc;
}
@ -636,11 +636,11 @@ int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
/* \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);
deliver->sequence_number = esme_inc_seq_nr(esme->esme);
LOGPESME(esme, LOGL_DEBUG, "Tx DELIVER-SM (from %s)\n", deliver->source_addr);
LOGPESME(esme->esme, LOGL_DEBUG, "Tx DELIVER-SM (from %s)\n", deliver->source_addr);
return PACK_AND_SEND(esme, deliver);
return PACK_AND_SEND(esme->esme, deliver);
}
/*! \brief handle an incoming SMPP DELIVER-SM RESPONSE */
@ -654,13 +654,13 @@ static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, DELIVER_SM_RESP, &deliver_r, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
LOGPESMERR(esme, "in smpp34_unpack()\n");
LOGPESMERR(esme->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",
LOGPESME(esme->esme, LOGL_ERROR, "Rx DELIVER-SM RESP !? (%s)\n",
get_value_string(smpp_status_strs, deliver_r.command_status));
return -1;
}
@ -670,7 +670,7 @@ static int smpp_handle_deliver_resp(struct osmo_esme *esme, struct msgb *msg)
else
smpp_cmd_err(cmd, deliver_r.command_status);
LOGPESME(esme, LOGL_INFO, "Rx DELIVER-SM RESP (%s)\n",
LOGPESME(esme->esme, LOGL_INFO, "Rx DELIVER-SM RESP (%s)\n",
get_value_string(smpp_status_strs, deliver_r.command_status));
return 0;
@ -687,7 +687,7 @@ static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg)
SMPP34_UNPACK(rc, SUBMIT_SM, &submit, msgb_data(msg),
msgb_length(msg));
if (rc < 0) {
LOGPESMERR(esme, "in smpp34_unpack()\n");
LOGPESMERR(esme->esme, "in smpp34_unpack()\n");
return rc;
}
@ -695,17 +695,17 @@ static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg)
if (!(esme->bind_flags & ESME_BIND_TX)) {
submit_r.command_status = ESME_RINVBNDSTS;
return PACK_AND_SEND(esme, &submit_r);
return PACK_AND_SEND(esme->esme, &submit_r);
}
LOGPESME(esme, LOGL_INFO, "Rx SUBMIT-SM (%s/%u/%u)\n",
LOGPESME(esme->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 PACK_AND_SEND(esme->esme, &submit_r);
return rc;
}
@ -716,7 +716,7 @@ 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));
LOGPESME(esme->esme, LOGL_DEBUG, "smpp_pdu_rx(%s)\n", msgb_hexdump(msg));
switch (cmd_id) {
case GENERIC_NACK:
@ -751,11 +751,11 @@ static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses)
case QUERY_SM:
case REPLACE_SM:
case SUBMIT_MULTI:
LOGPESME(esme, LOGL_NOTICE, "Unimplemented PDU Command 0x%08x\n", cmd_id);
LOGPESME(esme->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);
LOGPESME(esme->esme, LOGL_ERROR, "Unknown PDU Command 0x%08x\n", cmd_id);
rc = smpp_tx_gen_nack(esme->esme, smpp_msgb_seq(msg), ESME_RINVCMDID);
break;
}
@ -782,7 +782,8 @@ static int smpp_pdu_rx(struct osmo_esme *esme, struct msgb *msg __uses)
/* !\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;
struct osmo_esme *e = ofd->data;
struct esme *esme = e->esme;
uint32_t len;
uint8_t *lenptr = (uint8_t *) &len;
uint8_t *cur;
@ -829,7 +830,7 @@ static int esme_link_read_cb(struct osmo_fd *ofd)
msgb_put(msg, rc);
if (esme->read_idx >= esme->read_len) {
rc = smpp_pdu_rx(esme, esme->read_msg);
rc = smpp_pdu_rx(e, esme->read_msg);
msgb_free(esme->read_msg);
esme->read_msg = NULL;
esme->read_idx = 0;
@ -845,9 +846,9 @@ dead_socket:
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);
if (e->acl)
e->acl->esme = NULL;
smpp_esme_put(e);
return -EBADF;
}
@ -860,14 +861,14 @@ static int esme_link_write_cb(struct osmo_fd *ofd, struct msgb *msg)
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;
osmo_fd_unregister(&esme->esme->wqueue.bfd);
close(esme->esme->wqueue.bfd.fd);
esme->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");
LOGPESME(esme->esme, LOGL_ERROR, "Short write\n");
return -1;
}
@ -883,23 +884,28 @@ static int link_accept_cb(struct smsc *smsc, int fd,
close(fd);
return -ENOMEM;
}
esme->esme = talloc_zero(esme, struct esme);
if (!esme->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->esme->own_seq_nr = rand();
esme_inc_seq_nr(esme->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);
osmo_wqueue_init(&esme->esme->wqueue, 10);
osmo_fd_setup(&esme->esme->wqueue.bfd, fd, OSMO_FD_READ, osmo_wqueue_bfd_cb, esme, 0);
if (osmo_fd_register(&esme->wqueue.bfd) != 0) {
if (osmo_fd_register(&esme->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;
esme->esme->wqueue.read_cb = esme_link_read_cb;
esme->esme->wqueue.write_cb = esme_link_write_cb;
llist_add_tail(&esme->list, &smsc->esme_list);

View File

@ -30,23 +30,13 @@ struct osmo_smpp_addr {
struct osmo_esme {
struct llist_head list;
struct smsc *smsc;
struct esme *esme;
struct osmo_smpp_acl *acl;
int use;
struct llist_head smpp_cmd_list;
uint32_t own_seq_nr;
struct osmo_wqueue wqueue;
enum esme_read_state read_state;
uint32_t read_len;
uint32_t read_idx;
struct msgb *read_msg;
uint8_t smpp_version;
char system_id[SMPP_SYS_ID_LEN+1];
uint8_t bind_flags;
};

View File

@ -526,9 +526,9 @@ DEFUN(cfg_esme_no_alert_notif, cfg_esme_no_alert_notif_cmd,
static void dump_one_esme(struct vty *vty, struct osmo_esme *esme)
{
vty_out(vty, "ESME System ID: %s, Password: %s, SMPP Version %02x%s",
esme->system_id, esme->acl ? esme->acl->passwd : "",
esme->esme->system_id, esme->acl ? esme->acl->passwd : "",
esme->smpp_version, VTY_NEWLINE);
vty_out(vty, " Connection %s%s", osmo_sock_get_name(tall_vty_ctx, esme->wqueue.bfd.fd), VTY_NEWLINE);
vty_out(vty, " Connection %s%s", osmo_sock_get_name(tall_vty_ctx, esme->esme->wqueue.bfd.fd), VTY_NEWLINE);
if (esme->smsc->def_route == esme->acl)
vty_out(vty, " Is current default route%s", VTY_NEWLINE);
}

View File

@ -21,21 +21,6 @@
#include <osmocom/msc/debug.h>
#include <osmocom/msc/smpp.h>
/* FIXME: merge with smpp_smsc.c */
struct esme {
uint32_t own_seq_nr;
struct osmo_wqueue wqueue;
enum esme_read_state read_state;
uint32_t read_len;
uint32_t read_idx;
struct msgb *read_msg;
uint8_t smpp_version;
char system_id[SMPP_SYS_ID_LEN+1];
char password[SMPP_SYS_ID_LEN+1];
};
/* FIXME: merge with smpp_smsc.c */
static uint32_t esme_inc_seq_nr(struct esme *esme)