<p>Max <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/12020">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  Pau Espin Pedrol: Looks good to me, approved
  Jenkins Builder: Verified

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">LCLS, TS 48.008: add GCR IE encoding/decoding<br><br>* add functions to encode Global Call. Ref. from TS 29.205 as 3GPP TS<br>  48.008 §3.2.2.115 information element<br>* add corresponding tests<br><br>Change-Id: I82ce0207dc8de50689a8806c6471ad7fbae6219d<br>---<br>M include/osmocom/gsm/gsm0808_utils.h<br>M src/gsm/gsm0808_utils.c<br>M src/gsm/libosmogsm.map<br>M tests/gsm0808/gsm0808_test.c<br>M tests/gsm0808/gsm0808_test.ok<br>5 files changed, 123 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gsm/gsm0808_utils.h b/include/osmocom/gsm/gsm0808_utils.h</span><br><span>index 5d5803b..22050b5 100644</span><br><span>--- a/include/osmocom/gsm/gsm0808_utils.h</span><br><span>+++ b/include/osmocom/gsm/gsm0808_utils.h</span><br><span>@@ -27,6 +27,7 @@</span><br><span> </span><br><span> #include <osmocom/gsm/protocol/gsm_08_08.h></span><br><span> #include <osmocom/gsm/protocol/gsm_04_08.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm29205.h></span><br><span> #include <osmocom/gsm/gsm23003.h></span><br><span> #include <osmocom/gsm/gsm_utils.h></span><br><span> #include <osmocom/gsm/tlv.h></span><br><span>@@ -82,6 +83,10 @@</span><br><span>                                 const struct sockaddr_storage *ss);</span><br><span> int gsm0808_dec_aoip_trasp_addr(struct sockaddr_storage *ss,</span><br><span>                              const uint8_t *elem, uint8_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm0808_enc_gcr(struct msgb *msg, const struct osmo_gcr_parsed *g);</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0808_dec_gcr(struct osmo_gcr_parsed *g, const struct tlv_parsed *tp);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> uint8_t gsm0808_enc_speech_codec(struct msgb *msg,</span><br><span>                               const struct gsm0808_speech_codec *sc);</span><br><span> int gsm0808_dec_speech_codec(struct gsm0808_speech_codec *sc,</span><br><span>diff --git a/src/gsm/gsm0808_utils.c b/src/gsm/gsm0808_utils.c</span><br><span>index 38a8664..a04adde 100644</span><br><span>--- a/src/gsm/gsm0808_utils.c</span><br><span>+++ b/src/gsm/gsm0808_utils.c</span><br><span>@@ -508,6 +508,41 @@</span><br><span>    return (int)(elem - old_elem);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+/*! Create BSSMAP Global Call Reference, 3GPP TS 48.008 §3.2.2.115.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] msg Message Buffer for appending IE</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] g Global Call Reference, 3GPP TS 29.205 Table B 2.1.9.1</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns number of bytes added to \a msg or 0 on error */</span><br><span style="color: hsl(120, 100%, 40%);">+uint8_t gsm0808_enc_gcr(struct msgb *msg, const struct osmo_gcr_parsed *g)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t enc, *len = msgb_tl_put(msg, GSM0808_IE_GLOBAL_CALL_REF);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   enc = osmo_enc_gcr(msg, g);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!enc)</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%);">+   *len = enc;</span><br><span style="color: hsl(120, 100%, 40%);">+   return enc + 2; /* type (1 byte) + length (1 byte) */</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 BSSMAP Global Call Reference, 3GPP TS 29.205 Table B 2.1.9.1.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] gcr Caller-provided memory to store Global Call Reference</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] elem IE value to be decoded</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] len Length of \a elem in bytes</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns number of bytes parsed; negative on error */</span><br><span style="color: hsl(120, 100%, 40%);">+int gsm0808_dec_gcr(struct osmo_gcr_parsed *gcr, const struct tlv_parsed *tp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+      const uint8_t *buf = TLVP_VAL_MINLEN(tp, GSM0808_IE_GLOBAL_CALL_REF, OSMO_GCR_MIN_LEN);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!buf)</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%);">+     ret = osmo_dec_gcr(gcr, buf, TLVP_LEN(tp, GSM0808_IE_GLOBAL_CALL_REF));</span><br><span style="color: hsl(120, 100%, 40%);">+       if (ret < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+               return -ENOENT;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return 2 + ret;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> /*! Encode TS 08.08 Encryption Information IE</span><br><span>  *  \param[out] msg Message Buffer to which IE is to be appended</span><br><span>  *  \param[in] ei Encryption Information to be encoded</span><br><span>diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map</span><br><span>index e85ed6d..94ae76a 100644</span><br><span>--- a/src/gsm/libosmogsm.map</span><br><span>+++ b/src/gsm/libosmogsm.map</span><br><span>@@ -219,6 +219,8 @@</span><br><span> gsm0808_lcls_config_names;</span><br><span> gsm0808_lcls_control_names;</span><br><span> gsm0808_lcls_status_names;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0808_enc_gcr;</span><br><span style="color: hsl(120, 100%, 40%);">+gsm0808_dec_gcr;</span><br><span> </span><br><span> gsm29118_msgb_alloc;</span><br><span> gsm29118_create_alert_req;</span><br><span>diff --git a/tests/gsm0808/gsm0808_test.c b/tests/gsm0808/gsm0808_test.c</span><br><span>index 63b8720..f0f3165 100644</span><br><span>--- a/tests/gsm0808/gsm0808_test.c</span><br><span>+++ b/tests/gsm0808/gsm0808_test.c</span><br><span>@@ -22,6 +22,8 @@</span><br><span> #include <osmocom/gsm/gsm0808_utils.h></span><br><span> #include <osmocom/gsm/protocol/gsm_08_08.h></span><br><span> #include <osmocom/gsm/protocol/gsm_08_58.h></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/application.h></span><br><span> </span><br><span> #include <stdio.h></span><br><span> #include <stdlib.h></span><br><span>@@ -597,6 +599,75 @@</span><br><span>         msgb_free(in_msg);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static void test_enc_dec_gcr()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        static const uint8_t res[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+                GSM0808_IE_GLOBAL_CALL_REF,</span><br><span style="color: hsl(120, 100%, 40%);">+           0x0d, /* GCR length */</span><br><span style="color: hsl(120, 100%, 40%);">+                0x03, /* .net_len */</span><br><span style="color: hsl(120, 100%, 40%);">+          0xf1, 0xf2, 0xf3, /* .net */</span><br><span style="color: hsl(120, 100%, 40%);">+          0x02, /* .node length */</span><br><span style="color: hsl(120, 100%, 40%);">+              0xde, 0xad, /* .node */</span><br><span style="color: hsl(120, 100%, 40%);">+               0x05, /* length of Call. Ref. */</span><br><span style="color: hsl(120, 100%, 40%);">+              0x41, 0x42, 0x43, 0x44, 0x45 /* .cr - Call. Ref. */</span><br><span style="color: hsl(120, 100%, 40%);">+   };</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t len;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct osmo_gcr_parsed p = { 0 }, g = {</span><br><span style="color: hsl(120, 100%, 40%);">+               .net_len = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+         .net = { 0xf1, 0xf2, 0xf3 },</span><br><span style="color: hsl(120, 100%, 40%);">+          .node = 0xDEAD,</span><br><span style="color: hsl(120, 100%, 40%);">+               .cr = { 0x41, 0x42, 0x43, 0x44, 0x45 },</span><br><span style="color: hsl(120, 100%, 40%);">+       };</span><br><span style="color: hsl(120, 100%, 40%);">+    int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct tlv_parsed tp;</span><br><span style="color: hsl(120, 100%, 40%);">+ msg = msgb_alloc_headroom(BSSMAP_MSG_SIZE, BSSMAP_MSG_HEADROOM, "global call reference");</span><br><span style="color: hsl(120, 100%, 40%);">+   if (!msg)</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%);">+     len = gsm0808_enc_gcr(msg, &g);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("Testing Global Call Reference IE encoder...\n\t%d bytes added: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+              len, len == ARRAY_SIZE(res) ? "OK" : "FAIL");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!msgb_eq_data_print(msg, res, ARRAY_SIZE(res)))</span><br><span style="color: hsl(120, 100%, 40%);">+           abort();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = osmo_bssap_tlv_parse(&tp, msgb_data(msg), msgb_length(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("parsing failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+              abort();</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%);">+   rc = gsm0808_dec_gcr(&p, &tp);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("decoding failed: %s [%s]\n", strerror(-rc), msgb_hexdump(msg));</span><br><span style="color: hsl(120, 100%, 40%);">+             abort();</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 (p.net_len != g.net_len) {</span><br><span style="color: hsl(120, 100%, 40%);">+         printf("Network ID length parsed wrong: %u != %u\n", p.net_len, g.net_len);</span><br><span style="color: hsl(120, 100%, 40%);">+         abort();</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 (p.node != g.node) {</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("Node ID parsed wrong: 0x%X != 0x%X\n", p.node, g.node);</span><br><span style="color: hsl(120, 100%, 40%);">+             abort();</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 (memcmp(p.net, g.net, g.net_len) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf("Network ID parsed wrong: %s\n", osmo_hexdump(p.net, p.net_len));</span><br><span style="color: hsl(120, 100%, 40%);">+            abort();</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 (memcmp(p.cr, g.cr, 5) != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+             printf("Call ref. ID parsed wrong: %s\n", osmo_hexdump(p.cr, 5));</span><br><span style="color: hsl(120, 100%, 40%);">+           abort();</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("\tdecoded %d bytes: %s\n", rc, rc == len ? "OK" : "FAIL");</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void test_enc_dec_aoip_trasp_addr_v4()</span><br><span> {</span><br><span>   struct sockaddr_storage enc_addr;</span><br><span>@@ -1790,6 +1861,10 @@</span><br><span> </span><br><span> int main(int argc, char **argv)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+        void *ctx = talloc_named_const(NULL, 0, "gsm0808 test");</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_talloc_ctx_init(ctx, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_init_logging2(ctx, NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>     printf("Testing generation of GSM0808 messages\n");</span><br><span>        test_gsm0808_enc_cause();</span><br><span>    test_create_layer3();</span><br><span>@@ -1813,6 +1888,9 @@</span><br><span>        test_create_paging();</span><br><span>        test_create_dtap();</span><br><span>  test_prepend_dtap();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        test_enc_dec_gcr();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>        test_enc_dec_aoip_trasp_addr_v4();</span><br><span>   test_enc_dec_aoip_trasp_addr_v6();</span><br><span>   test_gsm0808_enc_dec_speech_codec();</span><br><span>diff --git a/tests/gsm0808/gsm0808_test.ok b/tests/gsm0808/gsm0808_test.ok</span><br><span>index e5833d0..d5857e3 100644</span><br><span>--- a/tests/gsm0808/gsm0808_test.ok</span><br><span>+++ b/tests/gsm0808/gsm0808_test.ok</span><br><span>@@ -22,6 +22,9 @@</span><br><span> Testing creating Paging Request</span><br><span> Testing creating DTAP</span><br><span> Testing prepend DTAP</span><br><span style="color: hsl(120, 100%, 40%);">+Testing Global Call Reference IE encoder...</span><br><span style="color: hsl(120, 100%, 40%);">+    15 bytes added: OK</span><br><span style="color: hsl(120, 100%, 40%);">+    decoded 15 bytes: OK</span><br><span> test_gsm0808_enc_dec_cell_id_list_lac: encoded: 1a 07 05 01 24 ab cd 56 78 (rc = 9)</span><br><span> ------- test_cell_id_list_add</span><br><span>      cell_id_list == CGI[0]:{}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/12020">change 12020</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/12020"/><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: I82ce0207dc8de50689a8806c6471ad7fbae6219d </div>
<div style="display:none"> Gerrit-Change-Number: 12020 </div>
<div style="display:none"> Gerrit-PatchSet: 19 </div>
<div style="display:none"> Gerrit-Owner: Max <msuraev@sysmocom.de> </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: Max <msuraev@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Pau Espin Pedrol <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-CC: Stefan Sperling <stsp@stsp.name> </div>