<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/18231">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  laforge: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gsm0808: Implement helper functions for CONFUSION BSSMAP message decoding.<br><br>Also add a test for an actual CONFUSION message parsing.<br><br>Change-Id: If8afd2d096fb66c6c2f255a08fc1129de3d09cec<br>---<br>M include/osmocom/gsm/gsm0808.h<br>M include/osmocom/gsm/protocol/gsm_08_08.h<br>M src/gsm/gsm0808.c<br>M src/gsm/libosmogsm.map<br>M tests/gsm0808/gsm0808_test.c<br>M tests/gsm0808/gsm0808_test.ok<br>6 files changed, 113 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gsm/gsm0808.h b/include/osmocom/gsm/gsm0808.h</span><br><span>index 5a33f60..34cec3c 100644</span><br><span>--- a/include/osmocom/gsm/gsm0808.h</span><br><span>+++ b/include/osmocom/gsm/gsm0808.h</span><br><span>@@ -319,6 +319,9 @@</span><br><span>  * \returns Cause value */</span><br><span> enum gsm0808_cause gsm0808_get_cause(const struct tlv_parsed *tp);</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+const char *gsm0808_diagnostics_octet_location_str(uint8_t pointer);</span><br><span style="color: hsl(120, 100%, 40%);">+const char *gsm0808_diagnostics_bit_location_str(uint8_t bit_pointer);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> extern const struct value_string gsm0808_lcls_config_names[];</span><br><span> extern const struct value_string gsm0808_lcls_control_names[];</span><br><span> extern const struct value_string gsm0808_lcls_status_names[];</span><br><span>diff --git a/include/osmocom/gsm/protocol/gsm_08_08.h b/include/osmocom/gsm/protocol/gsm_08_08.h</span><br><span>index d8a7773..1390f0e 100644</span><br><span>--- a/include/osmocom/gsm/protocol/gsm_08_08.h</span><br><span>+++ b/include/osmocom/gsm/protocol/gsm_08_08.h</span><br><span>@@ -663,3 +663,16 @@</span><br><span>         GSM0808_LCLS_STS_LOCALLY_SWITCHED       = 0x04,</span><br><span>      GSM0808_LCLS_STS_NA                     = 0xFF</span><br><span> };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.008 3.2.2.32 Diagnostics */</span><br><span style="color: hsl(120, 100%, 40%);">+struct gsm0808_diagnostics {</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t error_pointer_octet;</span><br><span style="color: hsl(120, 100%, 40%);">+#if OSMO_IS_LITTLE_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t error_pointer_bit_spare:4,</span><br><span style="color: hsl(120, 100%, 40%);">+                    error_pointer_bit:4;</span><br><span style="color: hsl(120, 100%, 40%);">+#elif OSMO_IS_BIG_ENDIAN</span><br><span style="color: hsl(120, 100%, 40%);">+/* auto-generated from the little endian part above (libosmocore/contrib/struct_endianess.py) */</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t error_pointer_bit:4, error_pointer_bit_spare:4;</span><br><span style="color: hsl(120, 100%, 40%);">+#endif</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t msg[0]; /*! received message which provoked the error */</span><br><span style="color: hsl(120, 100%, 40%);">+} __attribute__((packed));</span><br><span>diff --git a/src/gsm/gsm0808.c b/src/gsm/gsm0808.c</span><br><span>index 788f6c3..23468c3 100644</span><br><span>--- a/src/gsm/gsm0808.c</span><br><span>+++ b/src/gsm/gsm0808.c</span><br><span>@@ -21,6 +21,8 @@</span><br><span>  *</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> #include <osmocom/core/byteswap.h></span><br><span> #include <osmocom/gsm/gsm0808.h></span><br><span> #include <osmocom/gsm/gsm0808_utils.h></span><br><span>@@ -34,6 +36,9 @@</span><br><span>  *  message generation/encoding.</span><br><span>  */</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Char buffer to return strings from functions */</span><br><span style="color: hsl(120, 100%, 40%);">+static __thread char str_buff[512];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Create "Complete L3 Info" for AoIP, legacy implementation.</span><br><span>  * Instead use gsm0808_create_layer3_aoip2(), which is capable of three-digit MNC with leading zeros.</span><br><span>  *  \param[in] msg_l3 msgb containing Layer 3 Message</span><br><span>@@ -1670,6 +1675,39 @@</span><br><span>  return buf[0];</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+const char *gsm0808_diagnostics_octet_location_str(uint8_t pointer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       switch (pointer) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case 0:</span><br><span style="color: hsl(120, 100%, 40%);">+               return "Error location not determined";</span><br><span style="color: hsl(120, 100%, 40%);">+     case 1:</span><br><span style="color: hsl(120, 100%, 40%);">+               return "The first octet of the message received (i.e. the message type) was found erroneous (unknown)";</span><br><span style="color: hsl(120, 100%, 40%);">+     case 0xfd:</span><br><span style="color: hsl(120, 100%, 40%);">+            return  "The first octet of the BSSAP header (Discrimination) was found erroneous";</span><br><span style="color: hsl(120, 100%, 40%);">+ case 0xfe:</span><br><span style="color: hsl(120, 100%, 40%);">+            return  "(DTAP only) The DLCI (second) octet of the BSSAP header was found erroneous";</span><br><span style="color: hsl(120, 100%, 40%);">+      case 0xff:</span><br><span style="color: hsl(120, 100%, 40%);">+            return  "The last octet of the BSSAP header (length indicator) was found erroneous";</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              snprintf(str_buff, sizeof(str_buff), "The %d octet of the message received was found erroneous", pointer);</span><br><span style="color: hsl(120, 100%, 40%);">+          return str_buff;</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%);">+const char *gsm0808_diagnostics_bit_location_str(uint8_t bit_pointer)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      if (bit_pointer == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return "No particular part of the octet is indicated";</span><br><span style="color: hsl(120, 100%, 40%);">+      } else if (bit_pointer > 8) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return "Reserved value";</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%);">+   snprintf(str_buff, sizeof(str_buff),</span><br><span style="color: hsl(120, 100%, 40%);">+           "An error was provoked by the field whose most significant bit is in bit position %d",</span><br><span style="color: hsl(120, 100%, 40%);">+              bit_pointer);</span><br><span style="color: hsl(120, 100%, 40%);">+        return str_buff;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> const struct value_string gsm0808_lcls_config_names[] = {</span><br><span>   { GSM0808_LCLS_CFG_BOTH_WAY, "Connect both-way" },</span><br><span>         { GSM0808_LCLS_CFG_BOTH_WAY_AND_BICAST_UL,</span><br><span>diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map</span><br><span>index ce55746..70b3916 100644</span><br><span>--- a/src/gsm/libosmogsm.map</span><br><span>+++ b/src/gsm/libosmogsm.map</span><br><span>@@ -159,6 +159,8 @@</span><br><span> gsm0808_cause_name;</span><br><span> gsm0808_cause_class_name;</span><br><span> gsm0808_get_cause;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0808_diagnostics_octet_location_str;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0808_diagnostics_bit_location_str;</span><br><span> gsm0808_create_ass;</span><br><span> gsm0808_create_ass2;</span><br><span> gsm0808_create_assignment_completed;</span><br><span>diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c</span><br><span>index ce73390..d9640aa 100644</span><br><span>--- a/tests/gsm0808/gsm0808_test.c</span><br><span>+++ b/tests/gsm0808/gsm0808_test.c</span><br><span>@@ -379,6 +379,55 @@</span><br><span>   msgb_free(msg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void test_dec_confusion()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ static const uint8_t hex[] =</span><br><span style="color: hsl(120, 100%, 40%);">+          { 0x26, 0x04, 0x01, 0x52, 0x1f, 0x07, 0x00, 0xff, 0x00, 0x03, 0x25, 0x03, 0x25 };</span><br><span style="color: hsl(120, 100%, 40%);">+     struct tlv_parsed tp;</span><br><span style="color: hsl(120, 100%, 40%);">+ int diag_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum gsm0808_cause cause;</span><br><span style="color: hsl(120, 100%, 40%);">+     enum gsm0808_cause_class cause_class;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm0808_diagnostics *diag;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Testing decoding CONFUSION\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   tlv_parse(&tp, gsm0808_att_tlvdef(), hex+1, sizeof(hex)-1, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Check for the Cause and Diagnostic mandatory elements */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!TLVP_PRESENT(&tp, GSM0808_IE_CAUSE) || !TLVP_PRESENT(&tp, GSM0808_IE_DIAGNOSTIC)) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("Either Cause or Diagnostic mandatory IE are not detected\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               return;</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%);">+   diag_len = TLVP_LEN(&tp, GSM0808_IE_DIAGNOSTIC);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (diag_len < 5) {</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("Diagnostic length is too short: %d (expected > 5)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                   diag_len);</span><br><span style="color: hsl(120, 100%, 40%);">+             return;</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%);">+   cause = gsm0808_get_cause(&tp);</span><br><span style="color: hsl(120, 100%, 40%);">+   if ((int)cause < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("ERROR: failed (%s) to extract Cause, aborting\n", strerror(-(int)cause));</span><br><span style="color: hsl(120, 100%, 40%);">+           return;</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+     cause_class = gsm0808_cause_class(cause);</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("  Cause class %d/0x%x (%s)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+             cause_class, cause_class, gsm0808_cause_class_name(cause_class));</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("  Cause %d/0x%x (%s)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           cause, cause, gsm0808_cause_name(cause));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    diag = (struct gsm0808_diagnostics *)TLVP_VAL(&tp, GSM0808_IE_DIAGNOSTIC);</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("  Diagnostics error octet location %d (%s)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+             diag->error_pointer_octet,</span><br><span style="color: hsl(120, 100%, 40%);">+         gsm0808_diagnostics_octet_location_str(diag->error_pointer_octet));</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("  Diagnostics error bit location %d (%s)\n",</span><br><span style="color: hsl(120, 100%, 40%);">+               diag->error_pointer_bit,</span><br><span style="color: hsl(120, 100%, 40%);">+           gsm0808_diagnostics_bit_location_str(diag->error_pointer_bit));</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("  Diagnostics message that provoked the error: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+              osmo_hexdump(diag->msg, diag_len-2));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void test_create_ass()</span><br><span> {</span><br><span>   static const uint8_t res1[] =</span><br><span>@@ -2422,6 +2471,8 @@</span><br><span> </span><br><span>    test_gsm0808_cell_id_to_from_cgi();</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+       test_dec_confusion();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>      printf("Done\n");</span><br><span>  return EXIT_SUCCESS;</span><br><span> }</span><br><span>diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok</span><br><span>index b620e36..eaae7a6 100644</span><br><span>--- a/tests/gsm0808/gsm0808_test.ok</span><br><span>+++ b/tests/gsm0808/gsm0808_test.ok</span><br><span>@@ -910,4 +910,10 @@</span><br><span>   --> gsm0808_cell_id{LAC-CI} = LAC-CI:7777-7777</span><br><span>   --> gsm0808_cell_id{LAI} = LAI:777-007-7777</span><br><span>   --> gsm0808_cell_id{CGI} = CGI:777-007-7777-7777</span><br><span style="color: hsl(120, 100%, 40%);">+Testing decoding CONFUSION</span><br><span style="color: hsl(120, 100%, 40%);">+  Cause class 5/0x5 (Invalid message)</span><br><span style="color: hsl(120, 100%, 40%);">+  Cause 82/0x52 (INFORMATION ELEMENT OR FIELD MISSING)</span><br><span style="color: hsl(120, 100%, 40%);">+  Diagnostics error octet location 0 (Error location not determined)</span><br><span style="color: hsl(120, 100%, 40%);">+  Diagnostics error bit location 15 (Reserved value)</span><br><span style="color: hsl(120, 100%, 40%);">+  Diagnostics message that provoked the error: 00 03 25 03 25 </span><br><span> Done</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/18231">change 18231</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/+/18231"/><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: If8afd2d096fb66c6c2f255a08fc1129de3d09cec </div>
<div style="display:none"> Gerrit-Change-Number: 18231 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: ipse <Alexander.Chemeris@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: ipse <Alexander.Chemeris@gmail.com> </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-CC: Vadim Yanitskiy <axilirator@gmail.com> </div>
<div style="display:none"> Gerrit-CC: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>