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!
This commit is contained in:
parent
f1033cc752
commit
d4bdee79e9
|
@ -271,12 +271,29 @@ struct gsm_network {
|
|||
struct ctrl_handle *ctrl;
|
||||
};
|
||||
|
||||
struct osmo_esme;
|
||||
|
||||
enum gsm_sms_source_id {
|
||||
SMS_SOURCE_UNKNOWN = 0,
|
||||
SMS_SOURCE_MS, /* received from MS */
|
||||
SMS_SOURCE_VTY, /* received from VTY */
|
||||
SMS_SOURCE_SMPP, /* received via SMPP */
|
||||
};
|
||||
|
||||
#define SMS_HDR_SIZE 128
|
||||
#define SMS_TEXT_SIZE 256
|
||||
struct gsm_sms {
|
||||
unsigned long long id;
|
||||
struct gsm_subscriber *sender;
|
||||
struct gsm_subscriber *receiver;
|
||||
enum gsm_sms_source_id source;
|
||||
|
||||
struct {
|
||||
struct osmo_esme *esme;
|
||||
uint32_t sequence_nr;
|
||||
int transaction_mode;
|
||||
char msg_id[16];
|
||||
} smpp;
|
||||
|
||||
unsigned long validity_minutes;
|
||||
uint8_t reply_path_req;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue