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);