libmsc: handle delivery ack via SMPP SUBMIT SM / send GSM 03.40 status report

This patch adds gsm340_sms_send_status_report_tpdu() to build a
status-report. Moreover, set sms->report field if we see a SMPP
SUBMIT_SM with Delivery Acknowledgment esm_class, so this identifies
that this is a delivery report.

    MS        GSM 03.40           SMSC       SMPP 3.4               ESME
     |                             |                                |
     |                             |           SUBMIT-SM            |
     |                             |    esm_class = Delivery Ack    |
     |                             |<-------------------------------|
     |                             |         SUBMIT-SM-RESP         |
     |                             |------------------------------->|
     |                             |                                |
     |     SMS-STATUS-REPORT       |                                |
     |<----------------------------|                                |
     |     GSM 04.11 RP-ACK        |                                |
     |---------------------------->|                                |
     |                             |                                |

There is a FIXME message in this patch, that I just copied from
gsm340_gen_sms_deliver_tpdu() since TP-MMS is not supported by OpenBSC.

Change-Id: Ib70e534840308ed315f7add440351e649de3f907
This commit is contained in:
Pablo Neira Ayuso 2017-08-07 14:01:40 +01:00 committed by Neels Hofmeyr
parent eacb4007fb
commit bd71d32dca
2 changed files with 54 additions and 2 deletions

View File

@ -279,6 +279,49 @@ static int gsm340_gen_sms_deliver_tpdu(struct msgb *msg, struct gsm_sms *sms)
return msg->len - old_msg_len;
}
/* As defined by GSM 03.40, Section 9.2.2.3. */
static int gsm340_gen_sms_status_report_tpdu(struct msgb *msg,
struct gsm_sms *sms)
{
unsigned int old_msg_len = msg->len;
uint8_t oa_len = 0;
uint8_t oa[12]; /* max len per 03.40 */
uint8_t *smsp;
/* generate first octet with masked bits */
smsp = msgb_put(msg, 1);
/* TP-MTI (message type indicator) */
*smsp = GSM340_SMS_STATUS_REP_SC2MS;
/* TP-MMS (more messages to send) */
if (0 /* FIXME */)
*smsp |= 0x04;
/* TP-MR (message reference) */
smsp = msgb_put(msg, 1);
*smsp = sms->msg_ref;
/* generate recipient address */
oa_len = gsm340_gen_oa_sub(oa, sizeof(oa), &sms->dst);
smsp = msgb_put(msg, oa_len);
memcpy(smsp, oa, oa_len);
/* generate TP-SCTS (Service centre timestamp) */
smsp = msgb_put(msg, 7);
gsm340_gen_scts(smsp, time(NULL));
/* generate TP-DT (Discharge time, in TP-SCTS format). */
smsp = msgb_put(msg, 7);
gsm340_gen_scts(smsp, time(NULL));
/* TP-ST (status) */
smsp = msgb_put(msg, 1);
/* From GSM 03.40, Section 9.2.3.15, 0x00 means OK. */
*smsp = 0x00;
LOGP(DLSMS, LOGL_INFO, "sending status report for SMS reference %x\n",
sms->msg_ref);
return msg->len - old_msg_len;
}
static int sms_route_mt_sms(struct gsm_subscriber_connection *conn,
struct gsm_sms *gsms)
{
@ -993,8 +1036,13 @@ int gsm411_send_sms(struct gsm_subscriber_connection *conn, struct gsm_sms *sms)
/* obtain a pointer for the rp_ud_len, so we can fill it later */
rp_ud_len = (uint8_t *)msgb_put(msg, 1);
/* generate the 03.40 SMS-DELIVER TPDU */
rc = gsm340_gen_sms_deliver_tpdu(msg, sms);
if (sms->is_report) {
/* generate the 03.40 SMS-STATUS-REPORT TPDU */
rc = gsm340_gen_sms_status_report_tpdu(msg, sms);
} else {
/* generate the 03.40 SMS-DELIVER TPDU */
rc = gsm340_gen_sms_deliver_tpdu(msg, sms);
}
if (rc < 0) {
send_signal(S_SMS_UNKNOWN_ERROR, trans, sms, 0);
sms_free(sms);

View File

@ -144,6 +144,10 @@ static int submit_to_sms(struct gsm_sms **psms, struct gsm_network *net,
osmo_strlcpy(sms->src.addr, (char *)submit->source_addr,
sizeof(sms->src.addr));
/* This is a Delivery Acknowledgment. */
if (submit->esm_class == 0x08)
sms->is_report = true;
if (submit->esm_class & 0x40)
sms->ud_hdr_ind = 1;