<p>Harald Welte <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/11069">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Jenkins Builder: Verified
  Stefan Sperling: Looks good to me, but someone else must approve
  Harald Welte: Looks good to me, approved

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">GSUP/SMS: introduce MO-/MT-FORWARD-SM messages<br><br>According to 3GPP TS 29.002, there are two services:<br><br>  - MAP-MO-FORWARD-SHORT-MESSAGE (see 12.2),<br>  - MAP-MT-FORWARD-SHORT-MESSAGE (see 12.9),<br><br>which are used to forward MO/MT short messages.<br><br>This change replicates both services as GSUP messages:<br><br>  - OSMO_GSUP_MSGT_MO_FORWARD_SM_*,<br>  - OSMO_GSUP_MSGT_MT_FORWARD_SM_*.<br><br>Please note, that only the 'must-have' IEs are introduced<br>by this change, in particular the following:<br><br>  - OSMO_GSUP_SM_RP_MR_IE (see note below),<br>  - OSMO_GSUP_SM_RP_DA_IE (see 7.6.8.1),<br>  - OSMO_GSUP_SM_RP_OA_IE (see 7.6.8.2),<br>  - OSMO_GSUP_SM_RP_UI_IE (see 7.6.8.4),<br>  - OSMO_GSUP_SM_RP_MMS_IE (see 7.6.8.7),<br>  - OSMO_GSUP_SM_RP_CAUSE_IE (see GSM TS 04.11, 8.2.5.4),<br><br>where both SM_RP_DA and SM_RP_OA IEs basically contain<br>a single nested TV of the following format:<br><br>  - T: identity type (see 'osmo_gsup_sms_sm_rp_oda_t'),<br>  - V: encoded identity itself (optional).<br><br>According to GSM TS 04.11, every single message on the SM-RL has<br>an unique message reference (see 8.2.3), that is used to link<br>an RP-ACK or RP-ERROR message to the associated (preceding)<br>RP-DATA or RP-SMMA message transfer attempt.<br><br>In case of TCAP/MAP, this message reference is being mapped to the<br>Invoke ID. But since GSUP has no 'Invoke ID' IE, and it is not<br>required for other applications (other than SMS), this change<br>introduces a special 'SM_RP_MR' IE that doesn't exist in MAP.<br><br>Change-Id: Ibe325c64ae2d6c626b232533bb4cbc65fc2b5d71<br>Related Change-Id: (docs) Ie0150756c33c1352bc4eb49421824542c711175c<br>Related Change-Id: (TTCN) Ibf49474a81235096c032ea21f217170f523bd94e<br>Related: OS#3587<br>---<br>M TODO-RELEASE<br>M include/Makefile.am<br>M include/osmocom/gsm/gsup.h<br>A include/osmocom/gsm/gsup_sms.h<br>M src/gsm/Makefile.am<br>M src/gsm/gsup.c<br>A src/gsm/gsup_sms.c<br>M src/gsm/libosmogsm.map<br>M tests/gsup/gsup_test.c<br>M tests/gsup/gsup_test.err<br>M tests/gsup/gsup_test.ok<br>11 files changed, 527 insertions(+), 15 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/TODO-RELEASE b/TODO-RELEASE</span><br><span>index 00720f6..16d96ec 100644</span><br><span>--- a/TODO-RELEASE</span><br><span>+++ b/TODO-RELEASE</span><br><span>@@ -16,3 +16,6 @@</span><br><span> libosmogsm     gsm0808_cause_ext()     check for cause extended bit</span><br><span> libosmogsm     gsm0808_cause_name()    use enum as parameter</span><br><span> libosmogsm     gsm0808_create_cipher_reject()          use enum as parameter</span><br><span style="color: hsl(120, 100%, 40%);">+libosmogsm    osmo_gsup_message                       extended with SMS related fields</span><br><span style="color: hsl(120, 100%, 40%);">+libosmogsm    osmo_gsup_sms_{en|de}code_sm_rp_da      GSUP SM-RP-DA coding helpers</span><br><span style="color: hsl(120, 100%, 40%);">+libosmogsm        osmo_gsup_sms_{en|de}code_sm_rp_oa      GSUP SM-RP-OA coding helpers</span><br><span>diff --git a/include/Makefile.am b/include/Makefile.am</span><br><span>index ccf9e10..86d8d15 100644</span><br><span>--- a/include/Makefile.am</span><br><span>+++ b/include/Makefile.am</span><br><span>@@ -94,6 +94,7 @@</span><br><span>                        osmocom/gsm/gsm48_ie.h \</span><br><span>                        osmocom/gsm/gsm_utils.h \</span><br><span>                        osmocom/gsm/gsup.h \</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmocom/gsm/gsup_sms.h \</span><br><span>                        osmocom/gsm/ipa.h \</span><br><span>                        osmocom/gsm/lapd_core.h \</span><br><span>                        osmocom/gsm/lapdm.h \</span><br><span>diff --git a/include/osmocom/gsm/gsup.h b/include/osmocom/gsm/gsup.h</span><br><span>index cd6fd31..192b877 100644</span><br><span>--- a/include/osmocom/gsm/gsup.h</span><br><span>+++ b/include/osmocom/gsm/gsup.h</span><br><span>@@ -40,6 +40,7 @@</span><br><span> </span><br><span> #include <stdint.h></span><br><span> #include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsup_sms.h></span><br><span> #include <osmocom/gsm/protocol/gsm_23_003.h></span><br><span> #include <osmocom/gsm/protocol/gsm_04_08_gprs.h></span><br><span> #include <osmocom/crypt/auth.h></span><br><span>@@ -88,6 +89,14 @@</span><br><span> </span><br><span>      /*! Supplementary Services payload */</span><br><span>        OSMO_GSUP_SS_INFO_IE                    = 0x35,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* SM related IEs (see 3GPP TS 29.002, section 7.6.8) */</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_GSUP_SM_RP_MR_IE                   = 0x40,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_SM_RP_DA_IE                   = 0x41,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_SM_RP_OA_IE                   = 0x42,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_SM_RP_UI_IE                   = 0x43,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_SM_RP_CAUSE_IE                = 0x44,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_SM_RP_MMS_IE                  = 0x45,</span><br><span> };</span><br><span> </span><br><span> /*! GSUP message type */</span><br><span>@@ -121,6 +130,14 @@</span><br><span>         OSMO_GSUP_MSGT_PROC_SS_REQUEST          = 0b00100000,</span><br><span>        OSMO_GSUP_MSGT_PROC_SS_ERROR            = 0b00100001,</span><br><span>        OSMO_GSUP_MSGT_PROC_SS_RESULT           = 0b00100010,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST    = 0b00100100,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR      = 0b00100101,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT     = 0b00100110,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST    = 0b00101000,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR      = 0b00101001,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT     = 0b00101010,</span><br><span> };</span><br><span> </span><br><span> #define OSMO_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)</span><br><span>@@ -213,6 +230,26 @@</span><br><span>        /*! ASN.1 encoded MAP payload for Supplementary Services */</span><br><span>  uint8_t                         *ss_info;</span><br><span>    size_t                          ss_info_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /*! SM-RP-MR (see 3GPP TS 29.002, 7.6.1.1), Message Reference.</span><br><span style="color: hsl(120, 100%, 40%);">+         * Please note that there is no SM-RP-MR in TCAP/MAP! SM-RP-MR</span><br><span style="color: hsl(120, 100%, 40%);">+         * is usually mapped to TCAP's InvokeID, but we don't need it. */</span><br><span style="color: hsl(120, 100%, 40%);">+     const uint8_t                   *sm_rp_mr;</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! SM-RP-DA (see 3GPP TS 29.002, 7.6.8.1), Destination Address */</span><br><span style="color: hsl(120, 100%, 40%);">+    enum osmo_gsup_sms_sm_rp_oda_t  sm_rp_da_type;</span><br><span style="color: hsl(120, 100%, 40%);">+        size_t                          sm_rp_da_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t                   *sm_rp_da;</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! SM-RP-OA (see 3GPP TS 29.002, 7.6.8.2), Originating Address */</span><br><span style="color: hsl(120, 100%, 40%);">+    enum osmo_gsup_sms_sm_rp_oda_t  sm_rp_oa_type;</span><br><span style="color: hsl(120, 100%, 40%);">+        size_t                          sm_rp_oa_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t                   *sm_rp_oa;</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! SM-RP-UI (see 3GPP TS 29.002, 7.6.8.4), SMS TPDU */</span><br><span style="color: hsl(120, 100%, 40%);">+       const uint8_t                   *sm_rp_ui;</span><br><span style="color: hsl(120, 100%, 40%);">+    size_t                          sm_rp_ui_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! SM-RP-Cause value (1 oct.) as per GSM TS 04.11, section 8.2.5.4 */</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t                   *sm_rp_cause;</span><br><span style="color: hsl(120, 100%, 40%);">+ /*! SM-RP-MMS (More Messages to Send), section 7.6.8.7 */</span><br><span style="color: hsl(120, 100%, 40%);">+     const uint8_t                   *sm_rp_mms;</span><br><span> };</span><br><span> </span><br><span> int osmo_gsup_decode(const uint8_t *data, size_t data_len,</span><br><span>diff --git a/include/osmocom/gsm/gsup_sms.h b/include/osmocom/gsm/gsup_sms.h</span><br><span>new file mode 100644</span><br><span>index 0000000..521412d</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/gsm/gsup_sms.h</span><br><span>@@ -0,0 +1,38 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \addtogroup gsup</span><br><span style="color: hsl(120, 100%, 40%);">+ *  @{</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ *  This header defines SMS (Short Message Service) extensions for</span><br><span style="color: hsl(120, 100%, 40%);">+ *  Osmocom GSUP (Generic Subscriber Update Protocol). The scope of</span><br><span style="color: hsl(120, 100%, 40%);">+ *  this module is defined by 3GPP TS 29.002, section 12.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \file gsup_sms.h</span><br><span style="color: hsl(120, 100%, 40%);">+ *  SMS (Short Message Service) extensions for Osmocom GSUP. */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Possible identity types for SM-RP-{OA|DA} */</span><br><span style="color: hsl(120, 100%, 40%);">+enum osmo_gsup_sms_sm_rp_oda_t {</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_GSUP_SMS_SM_RP_ODA_NONE            = 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_SMS_SM_RP_ODA_IMSI            = 0x01,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_SMS_SM_RP_ODA_MSISDN          = 0x02,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR       = 0x03,</span><br><span style="color: hsl(120, 100%, 40%);">+       /*! Special value for noSM-RP-DA and noSM-RP-OA */</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_GSUP_SMS_SM_RP_ODA_NULL            = 0xff,</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_gsup_message;</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_sms_encode_sm_rp_da(struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct osmo_gsup_message *gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_sms_decode_sm_rp_da(struct osmo_gsup_message *gsup_msg,</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t *data, size_t data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_sms_encode_sm_rp_oa(struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+       const struct osmo_gsup_message *gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_sms_decode_sm_rp_oa(struct osmo_gsup_message *gsup_msg,</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t *data, size_t data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span>diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am</span><br><span>index ccb38ad..3d2c560 100644</span><br><span>--- a/src/gsm/Makefile.am</span><br><span>+++ b/src/gsm/Makefile.am</span><br><span>@@ -29,7 +29,7 @@</span><br><span>                   auth_milenage.c milenage/aes-encblock.c gea.c \</span><br><span>                      milenage/aes-internal.c milenage/aes-internal-enc.c \</span><br><span>                        milenage/milenage.c gan.c ipa.c gsm0341.c apn.c \</span><br><span style="color: hsl(0, 100%, 40%);">-                       gsup.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \</span><br><span style="color: hsl(120, 100%, 40%);">+                      gsup.c gsup_sms.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \</span><br><span>                  gsm23003.c mncc.c bts_features.c oap_client.c \</span><br><span>                      gsm29118.c</span><br><span> libgsmint_la_LDFLAGS = -no-undefined</span><br><span>diff --git a/src/gsm/gsup.c b/src/gsm/gsup.c</span><br><span>index 18b3580..e433997 100644</span><br><span>--- a/src/gsm/gsup.c</span><br><span>+++ b/src/gsm/gsup.c</span><br><span>@@ -67,6 +67,14 @@</span><br><span>         OSMO_VALUE_STRING(OSMO_GSUP_MSGT_PROC_SS_ERROR),</span><br><span>     OSMO_VALUE_STRING(OSMO_GSUP_MSGT_PROC_SS_RESULT),</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST),</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR),</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MO_FORWARD_SM_RESULT),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST),</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MT_FORWARD_SM_ERROR),</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_VALUE_STRING(OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT),</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>    { 0, NULL }</span><br><span> };</span><br><span> </span><br><span>@@ -434,6 +442,35 @@</span><br><span>                         gsup_msg->ss_info_len = value_len;</span><br><span>                        break;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+            case OSMO_GSUP_SM_RP_MR_IE:</span><br><span style="color: hsl(120, 100%, 40%);">+                   gsup_msg->sm_rp_mr = value;</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              case OSMO_GSUP_SM_RP_DA_IE:</span><br><span style="color: hsl(120, 100%, 40%);">+                   rc = osmo_gsup_sms_decode_sm_rp_da(gsup_msg, value, value_len);</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+                               return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+                    break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              case OSMO_GSUP_SM_RP_OA_IE:</span><br><span style="color: hsl(120, 100%, 40%);">+                   rc = osmo_gsup_sms_decode_sm_rp_oa(gsup_msg, value, value_len);</span><br><span style="color: hsl(120, 100%, 40%);">+                       if (rc)</span><br><span style="color: hsl(120, 100%, 40%);">+                               return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+                    break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              case OSMO_GSUP_SM_RP_UI_IE:</span><br><span style="color: hsl(120, 100%, 40%);">+                   gsup_msg->sm_rp_ui = value;</span><br><span style="color: hsl(120, 100%, 40%);">+                        gsup_msg->sm_rp_ui_len = value_len;</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              case OSMO_GSUP_SM_RP_MMS_IE:</span><br><span style="color: hsl(120, 100%, 40%);">+                  gsup_msg->sm_rp_mms = value;</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              case OSMO_GSUP_SM_RP_CAUSE_IE:</span><br><span style="color: hsl(120, 100%, 40%);">+                        gsup_msg->sm_rp_cause = value;</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>             default:</span><br><span>                     LOGP(DLGSUP, LOGL_NOTICE,</span><br><span>                         "GSUP IE type %d unknown\n", iei);</span><br><span>@@ -529,7 +566,7 @@</span><br><span> int osmo_gsup_encode(struct msgb *msg, const struct osmo_gsup_message *gsup_msg)</span><br><span> {</span><br><span>     uint8_t u8;</span><br><span style="color: hsl(0, 100%, 40%);">-     int idx;</span><br><span style="color: hsl(120, 100%, 40%);">+      int idx, rc;</span><br><span>         uint8_t bcd_buf[GSM48_MI_SIZE] = {0};</span><br><span>        size_t bcd_len;</span><br><span> </span><br><span>@@ -626,6 +663,42 @@</span><br><span>                           gsup_msg->ss_info_len, gsup_msg->ss_info);</span><br><span>     }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+ if (gsup_msg->sm_rp_mr) {</span><br><span style="color: hsl(120, 100%, 40%);">+          msgb_tlv_put(msg, OSMO_GSUP_SM_RP_MR_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+                              sizeof(*gsup_msg->sm_rp_mr), gsup_msg->sm_rp_mr);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (gsup_msg->sm_rp_da_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = osmo_gsup_sms_encode_sm_rp_da(msg, gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGP(DLGSUP, LOGL_ERROR, "Failed to encode SM-RP-DA IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (gsup_msg->sm_rp_oa_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+             rc = osmo_gsup_sms_encode_sm_rp_oa(msg, gsup_msg);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (rc) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGP(DLGSUP, LOGL_ERROR, "Failed to encode SM-RP-OA IE\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (gsup_msg->sm_rp_ui) {</span><br><span style="color: hsl(120, 100%, 40%);">+          msgb_tlv_put(msg, OSMO_GSUP_SM_RP_UI_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+                              gsup_msg->sm_rp_ui_len, gsup_msg->sm_rp_ui);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (gsup_msg->sm_rp_mms) {</span><br><span style="color: hsl(120, 100%, 40%);">+         msgb_tlv_put(msg, OSMO_GSUP_SM_RP_MMS_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+                             sizeof(*gsup_msg->sm_rp_mms), gsup_msg->sm_rp_mms);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (gsup_msg->sm_rp_cause) {</span><br><span style="color: hsl(120, 100%, 40%);">+               msgb_tlv_put(msg, OSMO_GSUP_SM_RP_CAUSE_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+                           sizeof(*gsup_msg->sm_rp_cause), gsup_msg->sm_rp_cause);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>  return 0;</span><br><span> }</span><br><span> </span><br><span>diff --git a/src/gsm/gsup_sms.c b/src/gsm/gsup_sms.c</span><br><span>new file mode 100644</span><br><span>index 0000000..d49cf20</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/gsup_sms.c</span><br><span>@@ -0,0 +1,256 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2018 by Vadim Yanitskiy <axilirator@gmail.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsup.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/tlv.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \addtogroup gsup</span><br><span style="color: hsl(120, 100%, 40%);">+ *  @{</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \file gsup_sms.c</span><br><span style="color: hsl(120, 100%, 40%);">+ *  SMS (Short Message Service) extensions for Osmocom GSUP.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode SM-RP-DA IE (see 7.6.8.1), Destination Address.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] msg      target message buffer (caller-allocated)</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in]  gsup_msg abstract GSUP message structure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns 0 in case of success, negative in case of error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_sms_encode_sm_rp_da(struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+     const struct osmo_gsup_message *gsup_msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *id_enc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (gsup_msg->sm_rp_da_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_SMS_SM_RP_ODA_IMSI:</span><br><span style="color: hsl(120, 100%, 40%);">+    case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Prevent NULL-pointer (or empty) dereference */</span><br><span style="color: hsl(120, 100%, 40%);">+             if (gsup_msg->sm_rp_da == NULL || gsup_msg->sm_rp_da_len == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        LOGP(DLGSUP, LOGL_ERROR, "Empty?!? SM-RP-DA ID "</span><br><span style="color: hsl(120, 100%, 40%);">+                            "(type=0x%02x)!\n", gsup_msg->sm_rp_da_type);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Special case for noSM-RP-DA */</span><br><span style="color: hsl(120, 100%, 40%);">+     case OSMO_GSUP_SMS_SM_RP_ODA_NULL:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_GSUP_SMS_SM_RP_ODA_NONE:</span><br><span style="color: hsl(120, 100%, 40%);">+    default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-DA ID "</span><br><span style="color: hsl(120, 100%, 40%);">+                  "(type=0x%02x)!\n", gsup_msg->sm_rp_da_type);</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* SM-RP-DA tag | len | ... */</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_tv_put(msg, OSMO_GSUP_SM_RP_DA_IE, gsup_msg->sm_rp_da_len + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_v_put(msg, gsup_msg->sm_rp_da_type); /* ... | id_type */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (gsup_msg->sm_rp_da_type == OSMO_GSUP_SMS_SM_RP_ODA_NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* ... | id_enc */</span><br><span style="color: hsl(120, 100%, 40%);">+    id_enc = msgb_put(msg, gsup_msg->sm_rp_da_len);</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(id_enc, gsup_msg->sm_rp_da, gsup_msg->sm_rp_da_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Decode SM-RP-DA IE (see 7.6.8.1), Destination Address.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] gsup_msg abstract GSUP message structure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in]  data     pointer to the raw IE payload</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in]  data_len length of IE pointed by \ref data</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns 0 in case of success, negative in case of error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_sms_decode_sm_rp_da(struct osmo_gsup_message *gsup_msg,</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t *data, size_t data_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *ptr = data;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t id_type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* There should be at least id_type */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (data_len < 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DLGSUP, LOGL_ERROR, "Corrupted SM-RP-DA IE "</span><br><span style="color: hsl(120, 100%, 40%);">+                   "(missing identity type)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* ... | id_type | id_enc (optional) */</span><br><span style="color: hsl(120, 100%, 40%);">+       id_type = *ptr++;</span><br><span style="color: hsl(120, 100%, 40%);">+     data_len--;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parse ID type */</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (id_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case OSMO_GSUP_SMS_SM_RP_ODA_IMSI:</span><br><span style="color: hsl(120, 100%, 40%);">+    case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!data_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* ID shall not be empty (if its type != NULL) */</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGP(DLGSUP, LOGL_ERROR, "Corrupted SM-RP-DA IE "</span><br><span style="color: hsl(120, 100%, 40%);">+                           "(missing encoded identity)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           gsup_msg->sm_rp_da_type = id_type;</span><br><span style="color: hsl(120, 100%, 40%);">+         gsup_msg->sm_rp_da_len = data_len;</span><br><span style="color: hsl(120, 100%, 40%);">+         gsup_msg->sm_rp_da = ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Special case for noSM-RP-DA */</span><br><span style="color: hsl(120, 100%, 40%);">+     case OSMO_GSUP_SMS_SM_RP_ODA_NULL:</span><br><span style="color: hsl(120, 100%, 40%);">+            if (data_len != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-DA ID, "</span><br><span style="color: hsl(120, 100%, 40%);">+                         "(id_len != 0) for noSM-RP-DA!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           gsup_msg->sm_rp_da_type = id_type;</span><br><span style="color: hsl(120, 100%, 40%);">+         gsup_msg->sm_rp_da_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                gsup_msg->sm_rp_da = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_GSUP_SMS_SM_RP_ODA_NONE:</span><br><span style="color: hsl(120, 100%, 40%);">+    default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-DA ID "</span><br><span style="color: hsl(120, 100%, 40%);">+                  "(type=0x%02x)!\n", id_type);</span><br><span style="color: hsl(120, 100%, 40%);">+               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode SM-RP-OA IE (see 7.6.8.2), Originating Address.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] msg      target message buffer (caller-allocated)</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in]  gsup_msg abstract GSUP message structure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns 0 in case of success, negative in case of error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_sms_encode_sm_rp_oa(struct msgb *msg,</span><br><span style="color: hsl(120, 100%, 40%);">+  const struct osmo_gsup_message *gsup_msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *id_enc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (gsup_msg->sm_rp_oa_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+ case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Prevent NULL-pointer (or empty) dereference */</span><br><span style="color: hsl(120, 100%, 40%);">+             if (gsup_msg->sm_rp_oa == NULL || gsup_msg->sm_rp_oa_len == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                        LOGP(DLGSUP, LOGL_ERROR, "Empty?!? SM-RP-OA ID "</span><br><span style="color: hsl(120, 100%, 40%);">+                            "(type=0x%02x)!\n", gsup_msg->sm_rp_oa_type);</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+             break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Special case for noSM-RP-OA */</span><br><span style="color: hsl(120, 100%, 40%);">+     case OSMO_GSUP_SMS_SM_RP_ODA_NULL:</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_GSUP_SMS_SM_RP_ODA_NONE:</span><br><span style="color: hsl(120, 100%, 40%);">+    default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-OA ID "</span><br><span style="color: hsl(120, 100%, 40%);">+                  "(type=0x%02x)!\n", gsup_msg->sm_rp_oa_type);</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* SM-RP-OA tag | len | ... */</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_tv_put(msg, OSMO_GSUP_SM_RP_OA_IE, gsup_msg->sm_rp_oa_len + 1);</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_v_put(msg, gsup_msg->sm_rp_oa_type); /* ... | id_type */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (gsup_msg->sm_rp_oa_type == OSMO_GSUP_SMS_SM_RP_ODA_NULL)</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* ... | id_enc */</span><br><span style="color: hsl(120, 100%, 40%);">+    id_enc = msgb_put(msg, gsup_msg->sm_rp_oa_len);</span><br><span style="color: hsl(120, 100%, 40%);">+    memcpy(id_enc, gsup_msg->sm_rp_oa, gsup_msg->sm_rp_oa_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Decode SM-RP-OA IE (see 7.6.8.2), Originating Address.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] gsup_msg abstract GSUP message structure</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in]  data     pointer to the raw IE payload</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in]  data_len length of IE pointed by \ref data</span><br><span style="color: hsl(120, 100%, 40%);">+ * \returns 0 in case of success, negative in case of error</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_sms_decode_sm_rp_oa(struct osmo_gsup_message *gsup_msg,</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t *data, size_t data_len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *ptr = data;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t id_type;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    /* There should be at least id_type */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (data_len < 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DLGSUP, LOGL_ERROR, "Corrupted SM-RP-OA IE "</span><br><span style="color: hsl(120, 100%, 40%);">+                   "(missing identity type)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* ... | id_type | id_enc (optional) */</span><br><span style="color: hsl(120, 100%, 40%);">+       id_type = *ptr++;</span><br><span style="color: hsl(120, 100%, 40%);">+     data_len--;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Parse ID type */</span><br><span style="color: hsl(120, 100%, 40%);">+   switch (id_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case OSMO_GSUP_SMS_SM_RP_ODA_IMSI:</span><br><span style="color: hsl(120, 100%, 40%);">+    case OSMO_GSUP_SMS_SM_RP_ODA_MSISDN:</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_GSUP_SMS_SM_RP_ODA_SMSC_ADDR:</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!data_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      /* ID shall not be empty (if its type != NULL) */</span><br><span style="color: hsl(120, 100%, 40%);">+                     LOGP(DLGSUP, LOGL_ERROR, "Corrupted SM-RP-OA IE "</span><br><span style="color: hsl(120, 100%, 40%);">+                           "(missing encoded identity)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           gsup_msg->sm_rp_oa_type = id_type;</span><br><span style="color: hsl(120, 100%, 40%);">+         gsup_msg->sm_rp_oa_len = data_len;</span><br><span style="color: hsl(120, 100%, 40%);">+         gsup_msg->sm_rp_oa = ptr;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Special case for noSM-RP-DA */</span><br><span style="color: hsl(120, 100%, 40%);">+     case OSMO_GSUP_SMS_SM_RP_ODA_NULL:</span><br><span style="color: hsl(120, 100%, 40%);">+            if (data_len != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-OA ID, "</span><br><span style="color: hsl(120, 100%, 40%);">+                         "(id_len != 0) for noSM-RP-DA!\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                 return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           gsup_msg->sm_rp_oa_type = id_type;</span><br><span style="color: hsl(120, 100%, 40%);">+         gsup_msg->sm_rp_oa_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+                gsup_msg->sm_rp_oa = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+         break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_GSUP_SMS_SM_RP_ODA_NONE:</span><br><span style="color: hsl(120, 100%, 40%);">+    default:</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLGSUP, LOGL_ERROR, "Unexpected SM-RP-OA ID "</span><br><span style="color: hsl(120, 100%, 40%);">+                  "(type=0x%02x)!\n", id_type);</span><br><span style="color: hsl(120, 100%, 40%);">+               return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span>diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map</span><br><span>index 959d182..90c2195 100644</span><br><span>--- a/src/gsm/libosmogsm.map</span><br><span>+++ b/src/gsm/libosmogsm.map</span><br><span>@@ -523,6 +523,11 @@</span><br><span> osmo_gsup_session_state_names;</span><br><span> osmo_gsup_get_err_msg_type;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gsup_sms_encode_sm_rp_da;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gsup_sms_decode_sm_rp_da;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gsup_sms_encode_sm_rp_oa;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gsup_sms_decode_sm_rp_oa;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> osmo_oap_encode;</span><br><span> osmo_oap_decode;</span><br><span> </span><br><span>diff --git a/tests/gsup/gsup_test.c b/tests/gsup/gsup_test.c</span><br><span>index 9712d77..0936893 100644</span><br><span>--- a/tests/gsup/gsup_test.c</span><br><span>+++ b/tests/gsup/gsup_test.c</span><br><span>@@ -217,6 +217,69 @@</span><br><span>                                 0x02, 0x01, 0x47,</span><br><span>    };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+        static const uint8_t send_mo_forward_sm_req[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+             0x24, /* OSMO_GSUP_MSGT_MO_FORWARD_SM_REQUEST */</span><br><span style="color: hsl(120, 100%, 40%);">+              TEST_IMSI_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* SM related IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+          0x40, 0x01, /* SM-RP-MR (Message Reference) */</span><br><span style="color: hsl(120, 100%, 40%);">+                        0xfa,</span><br><span style="color: hsl(120, 100%, 40%);">+         0x41, 0x08, /* SM-RP-DA (Destination Address) */</span><br><span style="color: hsl(120, 100%, 40%);">+                      0x03, /* SMSC address */</span><br><span style="color: hsl(120, 100%, 40%);">+                              0x91, 0x52, 0x75, 0x47, 0x99, 0x09, 0x82,</span><br><span style="color: hsl(120, 100%, 40%);">+             0x42, 0x01, /* SM-RP-OA (Originating Address) */</span><br><span style="color: hsl(120, 100%, 40%);">+                      0xff, /* Special case: noSM-RP-OA */</span><br><span style="color: hsl(120, 100%, 40%);">+          0x43, 0x04, /* SM-RP-UI (TPDU) */</span><br><span style="color: hsl(120, 100%, 40%);">+                     0xde, 0xad, 0xbe, 0xef,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  static const uint8_t send_mt_forward_sm_req[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+             0x28, /* OSMO_GSUP_MSGT_MT_FORWARD_SM_REQUEST */</span><br><span style="color: hsl(120, 100%, 40%);">+              TEST_IMSI_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* SM related IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+          0x40, 0x01, /* SM-RP-MR (Message Reference) */</span><br><span style="color: hsl(120, 100%, 40%);">+                        0xfa,</span><br><span style="color: hsl(120, 100%, 40%);">+         0x41, 0x09, /* SM-RP-DA (Destination Address) */</span><br><span style="color: hsl(120, 100%, 40%);">+                      0x01, /* IMSI */</span><br><span style="color: hsl(120, 100%, 40%);">+                              0x21, 0x43, 0x65, 0x87, 0x09, 0x21, 0x43, 0xf5,</span><br><span style="color: hsl(120, 100%, 40%);">+               0x42, 0x08, /* SM-RP-OA (Originating Address) */</span><br><span style="color: hsl(120, 100%, 40%);">+                      0x03, /* SMSC address */</span><br><span style="color: hsl(120, 100%, 40%);">+                              0x91, 0x52, 0x75, 0x47, 0x99, 0x09, 0x82,</span><br><span style="color: hsl(120, 100%, 40%);">+             0x43, 0x04, /* SM-RP-UI (TPDU) */</span><br><span style="color: hsl(120, 100%, 40%);">+                     0xde, 0xad, 0xbe, 0xef,</span><br><span style="color: hsl(120, 100%, 40%);">+               0x45, 0x01, /* SM-RP-MMS (More Messages to Send) */</span><br><span style="color: hsl(120, 100%, 40%);">+                   0x01,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  static const uint8_t send_mo_mt_forward_sm_err[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+          0x25, /* OSMO_GSUP_MSGT_MO_FORWARD_SM_ERROR */</span><br><span style="color: hsl(120, 100%, 40%);">+                TEST_IMSI_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* Session related IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+             0x30, 0x04, /* Session ID */</span><br><span style="color: hsl(120, 100%, 40%);">+                  0xde, 0xad, 0xbe, 0xef,</span><br><span style="color: hsl(120, 100%, 40%);">+               0x31, 0x01, /* Session state (END) */</span><br><span style="color: hsl(120, 100%, 40%);">+                 0x03,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* SM related IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+          0x40, 0x01, /* SM-RP-MR (Message Reference) */</span><br><span style="color: hsl(120, 100%, 40%);">+                        0xfa,</span><br><span style="color: hsl(120, 100%, 40%);">+         0x44, 0x01, /* SM-RP-Cause value */</span><br><span style="color: hsl(120, 100%, 40%);">+                   0xaf,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  static const uint8_t send_mo_mt_forward_sm_rsp[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+          0x2a, /* OSMO_GSUP_MSGT_MT_FORWARD_SM_RESULT */</span><br><span style="color: hsl(120, 100%, 40%);">+               TEST_IMSI_IE,</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+               /* SM related IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+          0x40, 0x01, /* SM-RP-MR (Message Reference) */</span><br><span style="color: hsl(120, 100%, 40%);">+                        0xfa,</span><br><span style="color: hsl(120, 100%, 40%);">+         0x43, 0x04, /* SM-RP-UI (TPDU) */</span><br><span style="color: hsl(120, 100%, 40%);">+                     0xde, 0xad, 0xbe, 0xef,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>         static const struct test {</span><br><span>           char *name;</span><br><span>          const uint8_t *data;</span><br><span>@@ -256,6 +319,14 @@</span><br><span>                  send_ussd_req, sizeof(send_ussd_req)},</span><br><span>               {"SS/USSD processUnstructuredSS-Request / ReturnResult",</span><br><span>                   send_ussd_res, sizeof(send_ussd_res)},</span><br><span style="color: hsl(120, 100%, 40%);">+                {"MO-ForwardSM (MSC -> SMSC) Request",</span><br><span style="color: hsl(120, 100%, 40%);">+                   send_mo_forward_sm_req, sizeof(send_mo_forward_sm_req)},</span><br><span style="color: hsl(120, 100%, 40%);">+              {"MT-ForwardSM (MSC -> SMSC) Request",</span><br><span style="color: hsl(120, 100%, 40%);">+                   send_mt_forward_sm_req, sizeof(send_mt_forward_sm_req)},</span><br><span style="color: hsl(120, 100%, 40%);">+              {"MO-/MT-ForwardSM Response",</span><br><span style="color: hsl(120, 100%, 40%);">+                       send_mo_mt_forward_sm_rsp, sizeof(send_mo_mt_forward_sm_rsp)},</span><br><span style="color: hsl(120, 100%, 40%);">+                {"MO-/MT-ForwardSM Error",</span><br><span style="color: hsl(120, 100%, 40%);">+                  send_mo_mt_forward_sm_err, sizeof(send_mo_mt_forward_sm_err)},</span><br><span>       };</span><br><span> </span><br><span>       printf("Test GSUP message decoding/encoding\n");</span><br><span>@@ -323,7 +394,7 @@</span><br><span>                              * FIXME: share the maximal IE value somehow</span><br><span>                                  * in order to avoid manual updating of this</span><br><span>                                  */</span><br><span style="color: hsl(0, 100%, 40%);">-                             OSMO_ASSERT(t->data[j+0] <= OSMO_GSUP_SS_INFO_IE);</span><br><span style="color: hsl(120, 100%, 40%);">+                              OSMO_ASSERT(t->data[j+0] <= OSMO_GSUP_SM_RP_MMS_IE);</span><br><span>                           OSMO_ASSERT(t->data[j+1] <= ie_end - j - 2);</span><br><span> </span><br><span>                               ie_end = j;</span><br><span>diff --git a/tests/gsup/gsup_test.err b/tests/gsup/gsup_test.err</span><br><span>index ac71ac2..4a1357c 100644</span><br><span>--- a/tests/gsup/gsup_test.err</span><br><span>+++ b/tests/gsup/gsup_test.err</span><br><span>@@ -49,6 +49,18 @@</span><br><span>   generated message: 22 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 35 08 a3 06 02 01 01 02 01 47 </span><br><span>   original message:  22 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 35 08 a3 06 02 01 01 02 01 47 </span><br><span>   IMSI:              123456789012345</span><br><span style="color: hsl(120, 100%, 40%);">+  generated message: 24 01 08 21 43 65 87 09 21 43 f5 40 01 fa 41 08 03 91 52 75 47 99 09 82 42 01 ff 43 04 de ad be ef </span><br><span style="color: hsl(120, 100%, 40%);">+  original message:  24 01 08 21 43 65 87 09 21 43 f5 40 01 fa 41 08 03 91 52 75 47 99 09 82 42 01 ff 43 04 de ad be ef </span><br><span style="color: hsl(120, 100%, 40%);">+  IMSI:              123456789012345</span><br><span style="color: hsl(120, 100%, 40%);">+  generated message: 28 01 08 21 43 65 87 09 21 43 f5 40 01 fa 41 09 01 21 43 65 87 09 21 43 f5 42 08 03 91 52 75 47 99 09 82 43 04 de ad be ef 45 01 01 </span><br><span style="color: hsl(120, 100%, 40%);">+  original message:  28 01 08 21 43 65 87 09 21 43 f5 40 01 fa 41 09 01 21 43 65 87 09 21 43 f5 42 08 03 91 52 75 47 99 09 82 43 04 de ad be ef 45 01 01 </span><br><span style="color: hsl(120, 100%, 40%);">+  IMSI:              123456789012345</span><br><span style="color: hsl(120, 100%, 40%);">+  generated message: 2a 01 08 21 43 65 87 09 21 43 f5 40 01 fa 43 04 de ad be ef </span><br><span style="color: hsl(120, 100%, 40%);">+  original message:  2a 01 08 21 43 65 87 09 21 43 f5 40 01 fa 43 04 de ad be ef </span><br><span style="color: hsl(120, 100%, 40%);">+  IMSI:              123456789012345</span><br><span style="color: hsl(120, 100%, 40%);">+  generated message: 25 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 40 01 fa 44 01 af </span><br><span style="color: hsl(120, 100%, 40%);">+  original message:  25 01 08 21 43 65 87 09 21 43 f5 30 04 de ad be ef 31 01 03 40 01 fa 44 01 af </span><br><span style="color: hsl(120, 100%, 40%);">+  IMSI:              123456789012345</span><br><span>   message 0: tested 11 truncations, 11 parse failures</span><br><span>   message 1: tested 14 truncations, 13 parse failures</span><br><span>   message 2: tested 83 truncations, 81 parse failures</span><br><span>@@ -66,21 +78,29 @@</span><br><span>   message 14: tested 20 truncations, 18 parse failures</span><br><span>   message 15: tested 42 truncations, 39 parse failures</span><br><span>   message 16: tested 30 truncations, 27 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 17: tested 33 truncations, 29 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 18: tested 44 truncations, 39 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 19: tested 20 truncations, 18 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 20: tested 26 truncations, 22 parse failures</span><br><span> DLGSUP Stopping DLGSUP logging</span><br><span>   message 0: tested 2816 modifications, 510 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 1: tested 3584 modifications, 768 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 2: tested 21248 modifications, 2571 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 1: tested 3584 modifications, 770 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 2: tested 21248 modifications, 2575 parse failures</span><br><span>   message 3: tested 2816 modifications, 510 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 4: tested 3584 modifications, 768 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 5: tested 20736 modifications, 4010 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 6: tested 3584 modifications, 769 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 7: tested 3584 modifications, 768 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 4: tested 3584 modifications, 770 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 5: tested 20736 modifications, 4022 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 6: tested 3584 modifications, 771 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 7: tested 3584 modifications, 770 parse failures</span><br><span>   message 8: tested 2816 modifications, 510 parse failures</span><br><span>   message 9: tested 2816 modifications, 510 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 10: tested 3584 modifications, 768 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 11: tested 3328 modifications, 767 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 12: tested 54016 modifications, 4622 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 10: tested 3584 modifications, 770 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 11: tested 3328 modifications, 769 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 12: tested 54016 modifications, 4626 parse failures</span><br><span>   message 13: tested 11520 modifications, 1026 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 14: tested 5120 modifications, 1026 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 15: tested 10752 modifications, 1256 parse failures</span><br><span style="color: hsl(0, 100%, 40%);">-  message 16: tested 7680 modifications, 1265 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 14: tested 5120 modifications, 1030 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 15: tested 10752 modifications, 1262 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 16: tested 7680 modifications, 1271 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 17: tested 8448 modifications, 2053 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 18: tested 11264 modifications, 2307 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 19: tested 5120 modifications, 1031 parse failures</span><br><span style="color: hsl(120, 100%, 40%);">+  message 20: tested 6656 modifications, 1546 parse failures</span><br><span>diff --git a/tests/gsup/gsup_test.ok b/tests/gsup/gsup_test.ok</span><br><span>index d63dd2d..7a9455d 100644</span><br><span>--- a/tests/gsup/gsup_test.ok</span><br><span>+++ b/tests/gsup/gsup_test.ok</span><br><span>@@ -33,4 +33,12 @@</span><br><span>           SS/USSD processUnstructuredSS-Request / Invoke OK</span><br><span>   Testing SS/USSD processUnstructuredSS-Request / ReturnResult</span><br><span>           SS/USSD processUnstructuredSS-Request / ReturnResult OK</span><br><span style="color: hsl(120, 100%, 40%);">+  Testing MO-ForwardSM (MSC -> SMSC) Request</span><br><span style="color: hsl(120, 100%, 40%);">+          MO-ForwardSM (MSC -> SMSC) Request OK</span><br><span style="color: hsl(120, 100%, 40%);">+  Testing MT-ForwardSM (MSC -> SMSC) Request</span><br><span style="color: hsl(120, 100%, 40%);">+          MT-ForwardSM (MSC -> SMSC) Request OK</span><br><span style="color: hsl(120, 100%, 40%);">+  Testing MO-/MT-ForwardSM Response</span><br><span style="color: hsl(120, 100%, 40%);">+          MO-/MT-ForwardSM Response OK</span><br><span style="color: hsl(120, 100%, 40%);">+  Testing MO-/MT-ForwardSM Error</span><br><span style="color: hsl(120, 100%, 40%);">+          MO-/MT-ForwardSM Error OK</span><br><span> Done.</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/11069">change 11069</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/11069"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: libosmocore </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: Ibe325c64ae2d6c626b232533bb4cbc65fc2b5d71 </div>
<div style="display:none"> Gerrit-Change-Number: 11069 </div>
<div style="display:none"> Gerrit-PatchSet: 12 </div>
<div style="display:none"> Gerrit-Owner: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder (1000002) </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Stefan Sperling <stsp@stsp.name> </div>
<div style="display:none"> Gerrit-Reviewer: Vadim Yanitskiy <axilirator@gmail.com> </div>