aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/libmsc
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-11-08 19:44:08 +0100
committerHarald Welte <laforge@gnumonks.org>2012-11-16 22:00:09 +0100
commitd4bdee79e96906323811ea5832e402855985df88 (patch)
treec5bd16e6181fa2ea9f57eb2baafc046a2f5b760b /openbsc/src/libmsc
parentf1033cc752cfeb5f86e6f2357ce62637646f773f (diff)
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!
Diffstat (limited to 'openbsc/src/libmsc')
-rw-r--r--openbsc/src/libmsc/smpp_openbsc.c50
-rw-r--r--openbsc/src/libmsc/smpp_smsc.c26
-rw-r--r--openbsc/src/libmsc/smpp_smsc.h3
3 files changed, 78 insertions, 1 deletions
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 <openbsc/debug.h>
#include <openbsc/db.h>
#include <openbsc/gsm_04_11.h>
+#include <openbsc/gsm_data.h>
+#include <openbsc/signal.h>
#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);