From d4bdee79e96906323811ea5832e402855985df88 Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Thu, 8 Nov 2012 19:44:08 +0100 Subject: SMPP: Implement transaction mode for SUBMIT-SM WARNING: if the ESME disconnects, osmo_esme gets freed, and sms->smpp.esme might point to invalid/unallocated memory! --- openbsc/src/libmsc/smpp_openbsc.c | 50 ++++++++++++++++++++++++++++++++++++++- openbsc/src/libmsc/smpp_smsc.c | 26 ++++++++++++++++++++ openbsc/src/libmsc/smpp_smsc.h | 3 +++ 3 files changed, 78 insertions(+), 1 deletion(-) (limited to 'openbsc/src/libmsc') diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c index cd3ab3a32..32dac61b3 100644 --- a/openbsc/src/libmsc/smpp_openbsc.c +++ b/openbsc/src/libmsc/smpp_openbsc.c @@ -38,6 +38,8 @@ #include #include #include +#include +#include #include "smpp_smsc.h" @@ -111,6 +113,8 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net, } sms = sms_alloc(); + sms->source = SMS_SOURCE_SMPP; + sms->smpp.sequence_nr = submit->sequence_number; sms->receiver = subscr_get(dest); strncpy(sms->dest_addr, dest->extension, sizeof(sms->dest_addr)-1); sms->sender = subscr_get_by_id(net, 1); @@ -163,6 +167,7 @@ int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit, submit_r->command_status = rc; return 0; } + sms->smpp.esme = esme; /* FIXME: TP-PID */ switch (submit->esm_class & 3) { @@ -182,13 +187,54 @@ int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit, rc = 0; break; case 2: /* forward (i.e. transaction) mode */ - /* FIXME */ + sms->smpp.transaction_mode = 1; + gsm411_send_sms_subscr(sms->receiver, sms); rc = 1; /* don't send any response yet */ break; } return rc; } +static int smpp_sms_cb(unsigned int subsys, unsigned int signal, + void *handler_data, void *signal_data) +{ + struct gsm_network *network = handler_data; + struct sms_signal_data *sig_sms = signal_data; + struct gsm_sms *sms = sig_sms->sms; + int rc = 0; + + if (!sms) + return 0; + + if (sms->source != SMS_SOURCE_SMPP) + return 0; + + switch (signal) { + case S_SMS_UNKNOWN_ERROR: + if (sms->smpp.transaction_mode) { + /* Send back the SUBMIT-SM response with apropriate error */ + LOGP(DSMS, 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(DSMS, 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; + } + + return rc; +} + int smpp_openbsc_init(struct gsm_network *net, uint16_t port) { @@ -201,6 +247,8 @@ int smpp_openbsc_init(struct gsm_network *net, uint16_t port) if (rc < 0) talloc_free(smsc); + osmo_signal_register_handler(SS_SMS, smpp_sms_cb, net); + return rc; } diff --git a/openbsc/src/libmsc/smpp_smsc.c b/openbsc/src/libmsc/smpp_smsc.c index ff6b1f9e5..dd6a2f9e3 100644 --- a/openbsc/src/libmsc/smpp_smsc.c +++ b/openbsc/src/libmsc/smpp_smsc.c @@ -46,6 +46,17 @@ enum emse_bind { ESME_BIND_TX = 0x02, }; +static struct osmo_esme * +esme_by_system_id(const struct smsc *smsc, char *system_id) +{ + struct osmo_esme *e; + + llist_for_each_entry(e, &smsc->esme_list, list) { + if (!strcmp(e->system_id, system_id)) + return e; + } + return NULL; +} #define INIT_RESP(type, resp, req) { \ @@ -280,6 +291,21 @@ static int smpp_handle_enq_link(struct osmo_esme *esme, struct msgb *msg) return PACK_AND_SEND(esme, &enq_r); } +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(submit_r.message_id, sizeof(submit_r.message_id), "%s", msg_id); + + return PACK_AND_SEND(esme, &submit_r); +} + static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg) { struct submit_sm_t submit; diff --git a/openbsc/src/libmsc/smpp_smsc.h b/openbsc/src/libmsc/smpp_smsc.h index 500fbc35a..8cdd2e7db 100644 --- a/openbsc/src/libmsc/smpp_smsc.h +++ b/openbsc/src/libmsc/smpp_smsc.h @@ -46,6 +46,9 @@ struct smsc { int smpp_smsc_init(struct smsc *smsc, uint16_t port); +int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr, + uint32_t command_status, char *msg_id); + int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit, struct submit_sm_resp_t *submit_r); -- cgit v1.2.3