aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src
diff options
context:
space:
mode:
authorHarald Welte <laforge@gnumonks.org>2012-11-09 12:51:44 +0100
committerHarald Welte <laforge@gnumonks.org>2012-11-16 22:00:10 +0100
commit8a1b056bff391892eef87fcd646bedf4450a5ae8 (patch)
treeaafe2c4b4c2759da486de5b209b77eeff1cc6fb7 /openbsc/src
parent9ad036242982b64862449ca645ac1cba8dca1ffc (diff)
SMPP: Implement ALERT NOTIFICATION on attach/detach of subscribers
Diffstat (limited to 'openbsc/src')
-rw-r--r--openbsc/src/libmsc/smpp_openbsc.c36
-rw-r--r--openbsc/src/libmsc/smpp_smsc.c39
-rw-r--r--openbsc/src/libmsc/smpp_smsc.h5
3 files changed, 78 insertions, 2 deletions
diff --git a/openbsc/src/libmsc/smpp_openbsc.c b/openbsc/src/libmsc/smpp_openbsc.c
index ff61babbd..c2e4c2852 100644
--- a/openbsc/src/libmsc/smpp_openbsc.c
+++ b/openbsc/src/libmsc/smpp_openbsc.c
@@ -238,6 +238,40 @@ static int smpp_sms_cb(unsigned int subsys, unsigned int signal,
return rc;
}
+/*! \brief signal handler for subscriber related signals */
+static int smpp_subscr_cb(unsigned int subsys, unsigned int signal,
+ void *handler_data, void *signal_data)
+{
+ struct gsm_subscriber *subscr = signal_data;
+ struct smsc *smsc = handler_data;
+ struct osmo_esme *esme;
+ uint8_t smpp_avail_status;
+
+ /* determine the smpp_avail_status depending on attach/detach */
+ switch (signal) {
+ case S_SUBSCR_ATTACHED:
+ smpp_avail_status = 0;
+ break;
+ case S_SUBSCR_DETACHED:
+ smpp_avail_status = 2;
+ break;
+ default:
+ return 0;
+ }
+
+ llist_for_each_entry(esme, &smsc->esme_list, list) {
+ /* we currently send an alert notification to each ESME that is
+ * connected, and do not require a (non-existant) delivery
+ * pending flag to be set before, FIXME: make this VTY
+ * configurable */
+ smpp_tx_alert(esme, TON_Subscriber_Number,
+ NPI_Land_Mobile_E212, subscr->imsi,
+ smpp_avail_status);
+ }
+
+ return 0;
+}
+
/*! \brief Initialize the OpenBSC SMPP interface */
int smpp_openbsc_init(struct gsm_network *net, uint16_t port)
{
@@ -251,7 +285,7 @@ int smpp_openbsc_init(struct gsm_network *net, uint16_t port)
talloc_free(smsc);
osmo_signal_register_handler(SS_SMS, smpp_sms_cb, net);
+ osmo_signal_register_handler(SS_SUBSCR, smpp_subscr_cb, smsc);
return rc;
}
-
diff --git a/openbsc/src/libmsc/smpp_smsc.c b/openbsc/src/libmsc/smpp_smsc.c
index 765cb517a..6bfd0c9b7 100644
--- a/openbsc/src/libmsc/smpp_smsc.c
+++ b/openbsc/src/libmsc/smpp_smsc.c
@@ -341,11 +341,47 @@ int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr,
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);
+ 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;
+
+ memset(&alert, 0, sizeof(alert));
+ alert.command_length = 0;
+ alert.command_id = ALERT_NOTIFICATION;
+ alert.command_status = ESME_ROK;
+ alert.sequence_number = esme->own_seq_nr++;
+ alert.source_addr_ton = ton;
+ alert.source_addr_npi = npi;
+ snprintf(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);
+
+ LOGP(DSMPP, LOGL_DEBUG, "[%s] Tx ALERT_NOTIFICATION (%s/%u/%u): %s\n",
+ esme->system_id, alert.source_addr, alert.source_addr_ton,
+ alert.source_addr_npi,
+ get_value_string(smpp_avail_strs, avail_status));
+
+ return PACK_AND_SEND(esme, &alert);
+}
+
/*! \brief handle an incoming SMPP SUBMIT-SM */
static int smpp_handle_submit(struct osmo_esme *esme, struct msgb *msg)
{
@@ -524,6 +560,7 @@ static int link_accept_cb(struct smsc *smsc, int fd,
return -ENOMEM;
smpp_esme_get(esme);
+ esme->own_seq_nr = rand();
esme->smsc = smsc;
osmo_wqueue_init(&esme->wqueue, 10);
esme->wqueue.bfd.fd = fd;
diff --git a/openbsc/src/libmsc/smpp_smsc.h b/openbsc/src/libmsc/smpp_smsc.h
index e93ae30c2..b1617e600 100644
--- a/openbsc/src/libmsc/smpp_smsc.h
+++ b/openbsc/src/libmsc/smpp_smsc.h
@@ -23,6 +23,8 @@ struct osmo_esme {
int use;
+ uint32_t own_seq_nr;
+
struct osmo_wqueue wqueue;
struct sockaddr_storage sa;
socklen_t sa_len;
@@ -54,6 +56,9 @@ void smpp_esme_put(struct osmo_esme *esme);
int smpp_tx_submit_r(struct osmo_esme *esme, uint32_t sequence_nr,
uint32_t command_status, char *msg_id);
+int smpp_tx_alert(struct osmo_esme *esme, uint8_t ton, uint8_t npi,
+ const char *addr, uint8_t avail_status);
+
int handle_smpp_submit(struct osmo_esme *esme, struct submit_sm_t *submit,
struct submit_sm_resp_t *submit_r);