<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/16189">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add osmo_gsup_make_response() and osmo_gsup_message_name_*()<br><br>As I am implementing GSUP proxy forwarding between osmo-hlr instances, it<br>becomes apparent that many code paths omit to copy back essential information<br>in replies to GSUP requests.<br><br>Provide a definitive common function that ensures a response is routed back to<br>the sender with all message fields reflecting the same subscriber, session<br>identification and message realm.<br><br>It is up to osmo-hlr's GSUP server and all clients to use this function in all<br>relevant GSUP message composition. The most important user is osmo-hlr, which<br>for now does all proxy routing tasks for directly attached clients.<br><br>However, if a core network entity other than the home HLR of a subscriber<br>launches an MT request, client programs like osmo-msc should also ensure to use<br>this function, so that responses are sure to reach the requesting peer.<br><br>osmo_gsup_message_name_*() are useful to check the osmo_gsup_make_response()<br>results in gsup_test.c, and are also otherwise useful for debug logging. So far<br>it prints exactly those elements required to be copied to a response.<br><br>Change-Id: Id9692880079ea0f219f52d81b1923a76fc640566<br>---<br>M include/osmocom/gsm/gsup.h<br>M src/gsm/gsup.c<br>M src/gsm/libosmogsm.map<br>M tests/gsup/gsup_test.c<br>M tests/gsup/gsup_test.ok<br>5 files changed, 244 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/89/16189/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gsm/gsup.h b/include/osmocom/gsm/gsup.h</span><br><span>index c883dfb..bf7b99d 100644</span><br><span>--- a/include/osmocom/gsm/gsup.h</span><br><span>+++ b/include/osmocom/gsm/gsup.h</span><br><span>@@ -203,6 +203,7 @@</span><br><span> </span><br><span> #define OSMO_GSUP_IS_MSGT_REQUEST(msgt) (((msgt) & 0b00000011) == 0b00)</span><br><span> #define OSMO_GSUP_IS_MSGT_ERROR(msgt)   (((msgt) & 0b00000011) == 0b01)</span><br><span style="color: hsl(120, 100%, 40%);">+#define OSMO_GSUP_TO_MSGT_RESULT(msgt)  (((msgt) & 0b11111100) | 0b10)</span><br><span> #define OSMO_GSUP_TO_MSGT_ERROR(msgt)   (((msgt) & 0b11111100) | 0b01)</span><br><span> </span><br><span> extern const struct value_string osmo_gsup_message_type_names[];</span><br><span>@@ -390,4 +391,10 @@</span><br><span> int osmo_gsup_get_err_msg_type(enum osmo_gsup_message_type type_in)</span><br><span>  OSMO_DEPRECATED("Use OSMO_GSUP_TO_MSGT_ERROR() instead");</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_make_response(struct osmo_gsup_message *reply,</span><br><span style="color: hsl(120, 100%, 40%);">+                     const struct osmo_gsup_message *rx, bool error, bool final_response);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+size_t osmo_gsup_message_name_buf(char *buf, size_t bufsize, const struct osmo_gsup_message *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+char *osmo_gsup_message_name_c(void *ctx, const struct osmo_gsup_message *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! @} */</span><br><span>diff --git a/src/gsm/gsup.c b/src/gsm/gsup.c</span><br><span>index ad7a2a4..b6cfcae 100644</span><br><span>--- a/src/gsm/gsup.c</span><br><span>+++ b/src/gsm/gsup.c</span><br><span>@@ -903,4 +903,140 @@</span><br><span>         {}</span><br><span> };</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Set fields that need to be copied from a received message over to its response message.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Note that fields like reply->destination_name may reference the same memory as rx and are not deep-copied, as usual</span><br><span style="color: hsl(120, 100%, 40%);">+ * when using this GSUP API.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * These fields are copied to the reply message, iff they are still unset:</span><br><span style="color: hsl(120, 100%, 40%);">+ * - Set reply->message_type to the rx's matching RESULT code (or ERROR code if error == true).</span><br><span style="color: hsl(120, 100%, 40%);">+ * - IMSI,</span><br><span style="color: hsl(120, 100%, 40%);">+ * - Set reply->destination_name to rx->source_name (for proxy routing),</span><br><span style="color: hsl(120, 100%, 40%);">+ * - sm_rp_mr (for SMS),</span><br><span style="color: hsl(120, 100%, 40%);">+ * - session_id (for SS/USSD),</span><br><span style="color: hsl(120, 100%, 40%);">+ * - if rx->session_state is not NONE, set tx->session_state depending on the final_response argument:</span><br><span style="color: hsl(120, 100%, 40%);">+ *   If false, set to OSMO_GSUP_SESSION_STATE_CONTINUE, else OSMO_GSUP_SESSION_STATE_END.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * If values in reply are already set, they will not be overwritten. The return code is an optional way of finding out</span><br><span style="color: hsl(120, 100%, 40%);">+ * whether all values that were already set in 'reply' are indeed matching the 'rx' values that would have been set.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] rx  Received GSUP message that is being replied to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[inout] reply  The message that should be the response to rx, either empty or with some values already set up.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return 0 if the resulting message is a valid response for rx, nonzero otherwise. If rc is nonzero, the reply message</span><br><span style="color: hsl(120, 100%, 40%);">+ *         will have all fields set as if zero were returned, so it is possible to compose invalid responses by</span><br><span style="color: hsl(120, 100%, 40%);">+ *         ignoring the return value (for flexibility). The rc is intended to warn if the reply message already</span><br><span style="color: hsl(120, 100%, 40%);">+ *         contained data that is incompatible with rx, e.g. a mismatching IMSI.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_gsup_make_response(struct osmo_gsup_message *reply,</span><br><span style="color: hsl(120, 100%, 40%);">+                          const struct osmo_gsup_message *rx, bool error, bool final_response)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!reply->message_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+                if (error)</span><br><span style="color: hsl(120, 100%, 40%);">+                    reply->message_type = OSMO_GSUP_TO_MSGT_ERROR(rx->message_type);</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  reply->message_type = OSMO_GSUP_TO_MSGT_RESULT(rx->message_type);</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 (!reply->imsi[0])</span><br><span style="color: hsl(120, 100%, 40%);">+               OSMO_STRLCPY_ARRAY(reply->imsi, rx->imsi);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (reply->message_class == OSMO_GSUP_MESSAGE_CLASS_UNSET)</span><br><span style="color: hsl(120, 100%, 40%);">+         reply->message_class = rx->message_class;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!reply->destination_name || !reply->destination_name_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+         reply->destination_name = rx->source_name;</span><br><span style="color: hsl(120, 100%, 40%);">+              reply->destination_name_len = rx->source_name_len;</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%);">+   /* RP-Message-Reference is mandatory for SM Service */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!reply->sm_rp_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+              reply->sm_rp_mr = rx->sm_rp_mr;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* For SS/USSD, it's important to keep both session state and ID IEs */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!reply->session_id)</span><br><span style="color: hsl(120, 100%, 40%);">+            reply->session_id = rx->session_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rx->session_state != OSMO_GSUP_SESSION_STATE_NONE</span><br><span style="color: hsl(120, 100%, 40%);">+          && reply->session_state == OSMO_GSUP_SESSION_STATE_NONE) {</span><br><span style="color: hsl(120, 100%, 40%);">+             if (final_response || rx->session_state == OSMO_GSUP_SESSION_STATE_END)</span><br><span style="color: hsl(120, 100%, 40%);">+                    reply->session_state = OSMO_GSUP_SESSION_STATE_END;</span><br><span style="color: hsl(120, 100%, 40%);">+                else</span><br><span style="color: hsl(120, 100%, 40%);">+                  reply->session_state = OSMO_GSUP_SESSION_STATE_CONTINUE;</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 (strcmp(reply->imsi, rx->imsi))</span><br><span style="color: hsl(120, 100%, 40%);">+              rc |= 1 << 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (reply->message_class != rx->message_class)</span><br><span style="color: hsl(120, 100%, 40%);">+          rc |= 1 << 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (rx->sm_rp_mr && (!reply->sm_rp_mr || *rx->sm_rp_mr != *reply->sm_rp_mr))</span><br><span style="color: hsl(120, 100%, 40%);">+              rc |= 1 << 2;</span><br><span style="color: hsl(120, 100%, 40%);">+   if (reply->session_id != rx->session_id)</span><br><span style="color: hsl(120, 100%, 40%);">+                rc |= 1 << 3;</span><br><span style="color: hsl(120, 100%, 40%);">+   return rc;</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%);">+/*! Print the most important value of a GSUP message to a string buffer in human readable form.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] buf  The buffer to write to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] buflen  sizeof(buf).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] msg  GSUP message to print.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+size_t osmo_gsup_message_name_buf(char *buf, size_t buflen, const struct osmo_gsup_message *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_strbuf sb = { .buf = buf, .len = buflen };</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!msg) {</span><br><span style="color: hsl(120, 100%, 40%);">+           OSMO_STRBUF_PRINTF(sb, "NULL");</span><br><span style="color: hsl(120, 100%, 40%);">+             return sb.chars_needed;</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 (msg->message_class)</span><br><span style="color: hsl(120, 100%, 40%);">+            OSMO_STRBUF_PRINTF(sb, "%s ", osmo_gsup_message_class_name(msg->message_class));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_STRBUF_PRINTF(sb, "%s:", osmo_gsup_message_type_name(msg->message_type));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_STRBUF_PRINTF(sb, " imsi=");</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_STRBUF_APPEND(sb, osmo_quote_cstr_buf, msg->imsi, strnlen(msg->imsi, sizeof(msg->imsi)));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (msg->cause)</span><br><span style="color: hsl(120, 100%, 40%);">+            OSMO_STRBUF_PRINTF(sb, " cause=%s", get_value_string(gsm48_gmm_cause_names, msg->cause));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      switch (msg->cn_domain) {</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_GSUP_CN_DOMAIN_CS:</span><br><span style="color: hsl(120, 100%, 40%);">+          OSMO_STRBUF_PRINTF(sb, " cn_domain=CS");</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case OSMO_GSUP_CN_DOMAIN_PS:</span><br><span style="color: hsl(120, 100%, 40%);">+          OSMO_STRBUF_PRINTF(sb, " cn_domain=PS");</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              if (msg->cn_domain)</span><br><span style="color: hsl(120, 100%, 40%);">+                        OSMO_STRBUF_PRINTF(sb, " cn_domain=?(%d)", msg->cn_domain);</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (msg->source_name_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+                OSMO_STRBUF_PRINTF(sb, " source_name=");</span><br><span style="color: hsl(120, 100%, 40%);">+            OSMO_STRBUF_APPEND(sb, osmo_quote_cstr_buf, (char*)msg->source_name, msg->source_name_len);</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 (msg->destination_name_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+           OSMO_STRBUF_PRINTF(sb, " destination_name=");</span><br><span style="color: hsl(120, 100%, 40%);">+               OSMO_STRBUF_APPEND(sb, osmo_quote_cstr_buf, (char*)msg->destination_name, msg->destination_name_len);</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 (msg->session_id)</span><br><span style="color: hsl(120, 100%, 40%);">+               OSMO_STRBUF_PRINTF(sb, " session_id=%u", msg->session_id);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (msg->session_state)</span><br><span style="color: hsl(120, 100%, 40%);">+            OSMO_STRBUF_PRINTF(sb, " session_state=%s", osmo_gsup_session_state_name(msg->session_state));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (msg->sm_rp_mr)</span><br><span style="color: hsl(120, 100%, 40%);">+         OSMO_STRBUF_PRINTF(sb, " sm_rp_mr=%u", *msg->sm_rp_mr);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        return sb.chars_needed;</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%);">+char *osmo_gsup_message_name_c(void *ctx, const struct osmo_gsup_message *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_NAME_C_IMPL(ctx, 64, "ERROR", osmo_gsup_message_name_buf, msg)</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! @} */</span><br><span>diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map</span><br><span>index a0e3b32..2eb0120 100644</span><br><span>--- a/src/gsm/libosmogsm.map</span><br><span>+++ b/src/gsm/libosmogsm.map</span><br><span>@@ -602,6 +602,9 @@</span><br><span> osmo_gsup_session_state_names;</span><br><span> osmo_gsup_message_class_names;</span><br><span> osmo_gsup_get_err_msg_type;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gsup_make_response;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gsup_message_name_buf;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_gsup_message_name_c;</span><br><span> </span><br><span> osmo_gsup_sms_encode_sm_rp_da;</span><br><span> osmo_gsup_sms_decode_sm_rp_da;</span><br><span>diff --git a/tests/gsup/gsup_test.c b/tests/gsup/gsup_test.c</span><br><span>index b84c88f..14ba8f9 100644</span><br><span>--- a/tests/gsup/gsup_test.c</span><br><span>+++ b/tests/gsup/gsup_test.c</span><br><span>@@ -20,6 +20,8 @@</span><br><span> #define TEST_SOURCE_NAME_IE 0x60, 0x05, 'M', 'S', 'C', '-', 'A'</span><br><span> #define TEST_DESTINATION_NAME_IE 0x61, 0x05, 'M', 'S', 'C', '-', 'B'</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+void *ctx;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void test_gsup_messages_dec_enc(void)</span><br><span> {</span><br><span>   int test_idx;</span><br><span>@@ -727,6 +729,69 @@</span><br><span>         }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void test_gsup_make_response(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      char *source_name = "incoming-source-name";</span><br><span style="color: hsl(120, 100%, 40%);">+ char *destination_name = "preset-destination-name";</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t sm_rp_mr = 23;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t other_sm_rp_mr = 17;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct osmo_gsup_message rx = {</span><br><span style="color: hsl(120, 100%, 40%);">+               .message_type = OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST,</span><br><span style="color: hsl(120, 100%, 40%);">+               .imsi = "1234567",</span><br><span style="color: hsl(120, 100%, 40%);">+          .message_class = OSMO_GSUP_MESSAGE_CLASS_SUBSCRIBER_MANAGEMENT,</span><br><span style="color: hsl(120, 100%, 40%);">+               .source_name = (uint8_t*)source_name,</span><br><span style="color: hsl(120, 100%, 40%);">+         .source_name_len = strlen(source_name) + 1,</span><br><span style="color: hsl(120, 100%, 40%);">+           .sm_rp_mr = &sm_rp_mr,</span><br><span style="color: hsl(120, 100%, 40%);">+            .session_id = 42,</span><br><span style="color: hsl(120, 100%, 40%);">+             .session_state = OSMO_GSUP_SESSION_STATE_BEGIN,</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_gsup_message nonempty = {</span><br><span style="color: hsl(120, 100%, 40%);">+         .message_type = OSMO_GSUP_MSGT_ROUTING_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+         .imsi = "987654321",</span><br><span style="color: hsl(120, 100%, 40%);">+                .message_class = OSMO_GSUP_MESSAGE_CLASS_INTER_MSC,</span><br><span style="color: hsl(120, 100%, 40%);">+           .destination_name = (uint8_t*)destination_name,</span><br><span style="color: hsl(120, 100%, 40%);">+               .destination_name_len = strlen(destination_name) + 1,</span><br><span style="color: hsl(120, 100%, 40%);">+         .sm_rp_mr = &other_sm_rp_mr,</span><br><span style="color: hsl(120, 100%, 40%);">+              .session_id = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+             .session_state = OSMO_GSUP_SESSION_STATE_END,</span><br><span style="color: hsl(120, 100%, 40%);">+ };</span><br><span style="color: hsl(120, 100%, 40%);">+    void *name_ctx = talloc_named_const(ctx, 0, __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+        int error;</span><br><span style="color: hsl(120, 100%, 40%);">+    int final;</span><br><span style="color: hsl(120, 100%, 40%);">+    char *nonempty_str;</span><br><span style="color: hsl(120, 100%, 40%);">+   int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("\n%s()\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("rx = %s\n", osmo_gsup_message_name_c(name_ctx, &rx));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("\nwriting to an empty struct osmo_gsup_message should populate values as needed:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       for (error = 0; error <= 1; error++) {</span><br><span style="color: hsl(120, 100%, 40%);">+             for (final = 0; final <= 1; final++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct osmo_gsup_message target = {};</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf("- args (error=%d, final=%d)\n", error, final);</span><br><span style="color: hsl(120, 100%, 40%);">+                      rc = osmo_gsup_make_response(&target, &rx, error, final);</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("  %s\n", osmo_gsup_message_name_c(name_ctx, &target));</span><br><span style="color: hsl(120, 100%, 40%);">+                  printf("  rc = %d\n", rc);</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%);">+   printf("\nwriting to an already populated struct osmo_gsup_message, should have no effect:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+     nonempty_str = osmo_gsup_message_name_c(name_ctx, &nonempty);</span><br><span style="color: hsl(120, 100%, 40%);">+     for (error = 0; error <= 1; error++) {</span><br><span style="color: hsl(120, 100%, 40%);">+             for (final = 0; final <= 1; final++) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     struct osmo_gsup_message target = nonempty;</span><br><span style="color: hsl(120, 100%, 40%);">+                   char *result;</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf("- args (error=%d, final=%d)\n", error, final);</span><br><span style="color: hsl(120, 100%, 40%);">+                      rc = osmo_gsup_make_response(&target, &rx, error, final);</span><br><span style="color: hsl(120, 100%, 40%);">+                     result = osmo_gsup_message_name_c(name_ctx, &target);</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("  %s\n", result);</span><br><span style="color: hsl(120, 100%, 40%);">+                   if (strcmp(result, nonempty_str))</span><br><span style="color: hsl(120, 100%, 40%);">+                             printf("  ERROR: expected: %s\n", nonempty_str);</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf("  rc = %d\n", rc);</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%);">+</span><br><span> const struct log_info_cat default_categories[] = {</span><br><span> };</span><br><span> </span><br><span>@@ -737,7 +802,7 @@</span><br><span> </span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">-        void *ctx = talloc_named_const(NULL, 0, "gsup_test");</span><br><span style="color: hsl(120, 100%, 40%);">+       ctx = talloc_named_const(NULL, 0, "gsup_test");</span><br><span>    osmo_init_logging2(ctx, &info);</span><br><span>  log_set_print_filename(osmo_stderr_target, 0);</span><br><span>       log_set_print_timestamp(osmo_stderr_target, 0);</span><br><span>@@ -745,6 +810,7 @@</span><br><span>        log_set_print_category(osmo_stderr_target, 1);</span><br><span> </span><br><span>   test_gsup_messages_dec_enc();</span><br><span style="color: hsl(120, 100%, 40%);">+ test_gsup_make_response();</span><br><span> </span><br><span>       printf("Done.\n");</span><br><span>         return EXIT_SUCCESS;</span><br><span>diff --git a/tests/gsup/gsup_test.ok b/tests/gsup/gsup_test.ok</span><br><span>index db8bc2f..cdbf23f 100644</span><br><span>--- a/tests/gsup/gsup_test.ok</span><br><span>+++ b/tests/gsup/gsup_test.ok</span><br><span>@@ -77,4 +77,35 @@</span><br><span>           E Abort OK</span><br><span>   Testing E Routing Error</span><br><span>           E Routing Error OK</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+test_gsup_make_response()</span><br><span style="color: hsl(120, 100%, 40%);">+rx = Subscriber-Management OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: imsi="1234567" source_name="incoming-source-name\0" session_id=42 session_state=BEGIN sm_rp_mr=23</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+writing to an empty struct osmo_gsup_message should populate values as needed:</span><br><span style="color: hsl(120, 100%, 40%);">+- args (error=0, final=0)</span><br><span style="color: hsl(120, 100%, 40%);">+  Subscriber-Management OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: imsi="1234567" destination_name="incoming-source-name\0" session_id=42 session_state=CONTINUE sm_rp_mr=23</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = 0</span><br><span style="color: hsl(120, 100%, 40%);">+- args (error=0, final=1)</span><br><span style="color: hsl(120, 100%, 40%);">+  Subscriber-Management OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: imsi="1234567" destination_name="incoming-source-name\0" session_id=42 session_state=END sm_rp_mr=23</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = 0</span><br><span style="color: hsl(120, 100%, 40%);">+- args (error=1, final=0)</span><br><span style="color: hsl(120, 100%, 40%);">+  Subscriber-Management OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: imsi="1234567" destination_name="incoming-source-name\0" session_id=42 session_state=CONTINUE sm_rp_mr=23</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = 0</span><br><span style="color: hsl(120, 100%, 40%);">+- args (error=1, final=1)</span><br><span style="color: hsl(120, 100%, 40%);">+  Subscriber-Management OSMO_GSUP_MSGT_UPDATE_LOCATION_ERROR: imsi="1234567" destination_name="incoming-source-name\0" session_id=42 session_state=END sm_rp_mr=23</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = 0</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+writing to an already populated struct osmo_gsup_message, should have no effect:</span><br><span style="color: hsl(120, 100%, 40%);">+- args (error=0, final=0)</span><br><span style="color: hsl(120, 100%, 40%);">+  Inter-MSC OSMO_GSUP_MSGT_ROUTING_ERROR: imsi="987654321" destination_name="preset-destination-name\0" session_id=11 session_state=END sm_rp_mr=17</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = 15</span><br><span style="color: hsl(120, 100%, 40%);">+- args (error=0, final=1)</span><br><span style="color: hsl(120, 100%, 40%);">+  Inter-MSC OSMO_GSUP_MSGT_ROUTING_ERROR: imsi="987654321" destination_name="preset-destination-name\0" session_id=11 session_state=END sm_rp_mr=17</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = 15</span><br><span style="color: hsl(120, 100%, 40%);">+- args (error=1, final=0)</span><br><span style="color: hsl(120, 100%, 40%);">+  Inter-MSC OSMO_GSUP_MSGT_ROUTING_ERROR: imsi="987654321" destination_name="preset-destination-name\0" session_id=11 session_state=END sm_rp_mr=17</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = 15</span><br><span style="color: hsl(120, 100%, 40%);">+- args (error=1, final=1)</span><br><span style="color: hsl(120, 100%, 40%);">+  Inter-MSC OSMO_GSUP_MSGT_ROUTING_ERROR: imsi="987654321" destination_name="preset-destination-name\0" session_id=11 session_state=END sm_rp_mr=17</span><br><span style="color: hsl(120, 100%, 40%);">+  rc = 15</span><br><span> Done.</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/16189">change 16189</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/c/libosmocore/+/16189"/><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-Change-Id: Id9692880079ea0f219f52d81b1923a76fc640566 </div>
<div style="display:none"> Gerrit-Change-Number: 16189 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>