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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">gprs_bssgp: agregate RIM related code in gprs_bssgp_rim.c<br><br>gprs_bssgp and gprs_bssgp_util.c also contains code related to send and<br>receive RIM PDUs via BSSGP and also code to encode and decode RAN<br>INFORMATION PDUs. Lets move this to gprs_bssgp_rim.c<br><br>Change-Id: Icda279452962b06e552cb1361d2a27b7dc8a6b04<br>Related: SYS#5103<br>---<br>M include/osmocom/gprs/gprs_bssgp.h<br>M include/osmocom/gprs/gprs_bssgp_rim.h<br>M src/gb/gprs_bssgp.c<br>M src/gb/gprs_bssgp_internal.h<br>M src/gb/gprs_bssgp_rim.c<br>M src/gb/gprs_bssgp_util.c<br>6 files changed, 307 insertions(+), 293 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/gprs/gprs_bssgp.h b/include/osmocom/gprs/gprs_bssgp.h</span><br><span>index a7b363b..e55fa52 100644</span><br><span>--- a/include/osmocom/gprs/gprs_bssgp.h</span><br><span>+++ b/include/osmocom/gprs/gprs_bssgp.h</span><br><span>@@ -42,39 +42,6 @@</span><br><span> /* Chapter 10.4.14: Status */</span><br><span> int bssgp_tx_status(uint8_t cause, uint16_t *bvci, struct msgb *orig_msg);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-/* Chapter 10.6.1: RAN-INFORMATION-REQUEST */</span><br><span style="color: hsl(0, 100%, 40%);">-struct bssgp_ran_information_pdu {</span><br><span style="color: hsl(0, 100%, 40%);">-        struct bssgp_rim_routing_info routing_info_dest;</span><br><span style="color: hsl(0, 100%, 40%);">-        struct bssgp_rim_routing_info routing_info_src;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Encoded variant of the RIM container */</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t rim_cont_iei;</span><br><span style="color: hsl(0, 100%, 40%);">-   const uint8_t *rim_cont;</span><br><span style="color: hsl(0, 100%, 40%);">-        unsigned int rim_cont_len;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Decoded variant of the RIM container */</span><br><span style="color: hsl(0, 100%, 40%);">-      bool decoded_present;</span><br><span style="color: hsl(0, 100%, 40%);">-   union {</span><br><span style="color: hsl(0, 100%, 40%);">-         struct bssgp_ran_inf_req_rim_cont req_rim_cont;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct bssgp_ran_inf_rim_cont rim_cont;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct bssgp_ran_inf_ack_rim_cont ack_rim_cont;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct bssgp_ran_inf_err_rim_cont err_rim_cont;</span><br><span style="color: hsl(0, 100%, 40%);">-         struct bssgp_ran_inf_app_err_rim_cont app_err_rim_cont;</span><br><span style="color: hsl(0, 100%, 40%);">- } decoded;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* When receiving a PDU from BSSGP the encoded variant of the RIM</span><br><span style="color: hsl(0, 100%, 40%);">-        * container will always be present. The decoded variant will be</span><br><span style="color: hsl(0, 100%, 40%);">-         * present in addition whenever BSSGP was able to decode the container.</span><br><span style="color: hsl(0, 100%, 40%);">-  *</span><br><span style="color: hsl(0, 100%, 40%);">-       * When sending a PDU to BSSGP, then the decoded variant is used when</span><br><span style="color: hsl(0, 100%, 40%);">-    * it is available. The encoded variant (if present) will be ignored</span><br><span style="color: hsl(0, 100%, 40%);">-     * then. */</span><br><span style="color: hsl(0, 100%, 40%);">-};</span><br><span style="color: hsl(0, 100%, 40%);">-int bssgp_tx_rim(const struct bssgp_ran_information_pdu *pdu, uint16_t nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-int bssgp_parse_rim_pdu(struct bssgp_ran_information_pdu *pdu, const struct msgb *msg);</span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb *bssgp_encode_rim_pdu(const struct bssgp_ran_information_pdu *pdu);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> enum bssgp_prim {</span><br><span>        PRIM_BSSGP_DL_UD,</span><br><span>    PRIM_BSSGP_UL_UD,</span><br><span>diff --git a/include/osmocom/gprs/gprs_bssgp_rim.h b/include/osmocom/gprs/gprs_bssgp_rim.h</span><br><span>index 418c1bd..5f397c9 100644</span><br><span>--- a/include/osmocom/gprs/gprs_bssgp_rim.h</span><br><span>+++ b/include/osmocom/gprs/gprs_bssgp_rim.h</span><br><span>@@ -236,3 +236,37 @@</span><br><span> </span><br><span> int bssgp_dec_ran_inf_app_err_rim_cont(struct bssgp_ran_inf_app_err_rim_cont *cont, const uint8_t *buf, size_t len);</span><br><span> int bssgp_enc_ran_inf_app_err_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_app_err_rim_cont *cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Chapter 10.6.1: RAN-INFORMATION-REQUEST */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_information_pdu {</span><br><span style="color: hsl(120, 100%, 40%);">+    struct bssgp_rim_routing_info routing_info_dest;</span><br><span style="color: hsl(120, 100%, 40%);">+      struct bssgp_rim_routing_info routing_info_src;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Encoded variant of the RIM container */</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t rim_cont_iei;</span><br><span style="color: hsl(120, 100%, 40%);">+ const uint8_t *rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+      unsigned int rim_cont_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Decoded variant of the RIM container */</span><br><span style="color: hsl(120, 100%, 40%);">+    bool decoded_present;</span><br><span style="color: hsl(120, 100%, 40%);">+ union {</span><br><span style="color: hsl(120, 100%, 40%);">+               struct bssgp_ran_inf_req_rim_cont req_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct bssgp_ran_inf_rim_cont rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct bssgp_ran_inf_ack_rim_cont ack_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct bssgp_ran_inf_err_rim_cont err_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct bssgp_ran_inf_app_err_rim_cont app_err_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+       } decoded;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* When receiving a PDU from BSSGP the encoded variant of the RIM</span><br><span style="color: hsl(120, 100%, 40%);">+      * container will always be present. The decoded variant will be</span><br><span style="color: hsl(120, 100%, 40%);">+       * present in addition whenever BSSGP was able to decode the container.</span><br><span style="color: hsl(120, 100%, 40%);">+        *</span><br><span style="color: hsl(120, 100%, 40%);">+     * When sending a PDU to BSSGP, then the decoded variant is used when</span><br><span style="color: hsl(120, 100%, 40%);">+  * it is available. The encoded variant (if present) will be ignored</span><br><span style="color: hsl(120, 100%, 40%);">+   * then. */</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%);">+int bssgp_parse_rim_pdu(struct bssgp_ran_information_pdu *pdu, const struct msgb *msg);</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *bssgp_encode_rim_pdu(const struct bssgp_ran_information_pdu *pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_tx_rim(const struct bssgp_ran_information_pdu *pdu, uint16_t nsei);</span><br><span>diff --git a/src/gb/gprs_bssgp.c b/src/gb/gprs_bssgp.c</span><br><span>index 4154c4b..926b0ef 100644</span><br><span>--- a/src/gb/gprs_bssgp.c</span><br><span>+++ b/src/gb/gprs_bssgp.c</span><br><span>@@ -41,6 +41,7 @@</span><br><span> #include <osmocom/gprs/gprs_ns.h></span><br><span> </span><br><span> #include "osmocom/gsm/gsm48.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "gprs_bssgp_internal.h"</span><br><span> </span><br><span> void *bssgp_tall_ctx = NULL;</span><br><span> </span><br><span>@@ -647,46 +648,6 @@</span><br><span>      return bssgp_prim_cb(&nmp.oph, NULL);</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int bssgp_rx_rim(struct msgb *msg, struct tlv_parsed *tp, uint16_t bvci)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct osmo_bssgp_prim nmp;</span><br><span style="color: hsl(0, 100%, 40%);">-     uint16_t nsei = msgb_nsei(msg);</span><br><span style="color: hsl(0, 100%, 40%);">- struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *)msgb_bssgph(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-    enum bssgp_prim prim;</span><br><span style="color: hsl(0, 100%, 40%);">-   char ri_src_str[64];</span><br><span style="color: hsl(0, 100%, 40%);">-    char ri_dest_str[64];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Specify PRIM type based on the RIM PDU */</span><br><span style="color: hsl(0, 100%, 40%);">-    switch (bgph->pdu_type) {</span><br><span style="color: hsl(0, 100%, 40%);">-    case BSSGP_PDUT_RAN_INFO:</span><br><span style="color: hsl(0, 100%, 40%);">-       case BSSGP_PDUT_RAN_INFO_REQ:</span><br><span style="color: hsl(0, 100%, 40%);">-   case BSSGP_PDUT_RAN_INFO_ACK:</span><br><span style="color: hsl(0, 100%, 40%);">-   case BSSGP_PDUT_RAN_INFO_ERROR:</span><br><span style="color: hsl(0, 100%, 40%);">- case BSSGP_PDUT_RAN_INFO_APP_ERROR:</span><br><span style="color: hsl(0, 100%, 40%);">-             prim = PRIM_BSSGP_RIM_PDU_TRANSFER;</span><br><span style="color: hsl(0, 100%, 40%);">-             break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Caller already makes sure that this can't happen. */</span><br><span style="color: hsl(0, 100%, 40%);">-             OSMO_ASSERT(false);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Send BSSGP RIM indication to NM */</span><br><span style="color: hsl(0, 100%, 40%);">-   memset(&nmp, 0, sizeof(nmp));</span><br><span style="color: hsl(0, 100%, 40%);">-       nmp.nsei = nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-        nmp.bvci = bvci;</span><br><span style="color: hsl(0, 100%, 40%);">-        nmp.tp = tp;</span><br><span style="color: hsl(0, 100%, 40%);">-    if (bssgp_parse_rim_pdu(&nmp.u.rim_pdu, msg) < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);</span><br><span style="color: hsl(0, 100%, 40%);">- DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx RIM-PDU:%s, src=%s, dest=%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-            bvci, bssgp_pdu_str(bgph->pdu_type),</span><br><span style="color: hsl(0, 100%, 40%);">-         bssgp_rim_ri_name_buf(ri_src_str, sizeof(ri_src_str), &nmp.u.rim_pdu.routing_info_src),</span><br><span style="color: hsl(0, 100%, 40%);">-             bssgp_rim_ri_name_buf(ri_dest_str, sizeof(ri_dest_str), &nmp.u.rim_pdu.routing_info_dest));</span><br><span style="color: hsl(0, 100%, 40%);">-  osmo_prim_init(&nmp.oph, SAP_BSSGP_RIM, prim, PRIM_OP_INDICATION, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-     bssgp_prim_cb(&nmp.oph, NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* One element (msgb) in a BSSGP Flow Control queue */</span><br><span> struct bssgp_fc_queue_element {</span><br><span>      /* linked list of queue elements */</span><br><span>diff --git a/src/gb/gprs_bssgp_internal.h b/src/gb/gprs_bssgp_internal.h</span><br><span>index 2ada027..5022d32 100644</span><br><span>--- a/src/gb/gprs_bssgp_internal.h</span><br><span>+++ b/src/gb/gprs_bssgp_internal.h</span><br><span>@@ -5,3 +5,5 @@</span><br><span> </span><br><span> extern bssgp_bvc_send bssgp_ns_send;</span><br><span> extern void *bssgp_ns_send_data;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_rx_rim(struct msgb *msg, struct tlv_parsed *tp, uint16_t bvci);</span><br><span>diff --git a/src/gb/gprs_bssgp_rim.c b/src/gb/gprs_bssgp_rim.c</span><br><span>index 25f9406..63b303e 100644</span><br><span>--- a/src/gb/gprs_bssgp_rim.c</span><br><span>+++ b/src/gb/gprs_bssgp_rim.c</span><br><span>@@ -27,6 +27,7 @@</span><br><span> #include <osmocom/gprs/gprs_bssgp.h></span><br><span> #include <osmocom/gprs/gprs_bssgp_rim.h></span><br><span> #include <osmocom/gsm/gsm0808_utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include "gprs_bssgp_internal.h"</span><br><span> </span><br><span> /* TVLV IEs use a variable length field. To be sure we will do all buffer</span><br><span>  * length checks with the maximum possible header length, which is</span><br><span>@@ -949,3 +950,272 @@</span><br><span> </span><br><span>  return (int)(buf_ptr - buf);</span><br><span> }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Parse a given message buffer into a rim-pdu struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] pdu user provided memory for the resulting RAN INFORMATION PDU.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] msg BSSGP message buffer that contains the encoded RAN INFORMATION PDU.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on sccess, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_parse_rim_pdu(struct bssgp_ran_information_pdu *pdu, const struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct tlv_parsed tp[2];</span><br><span style="color: hsl(120, 100%, 40%);">+      struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *)msgb_bssgph(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  int data_len;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t nsei = msgb_nsei(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     memset(pdu, 0, sizeof(*pdu));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       data_len = msgb_bssgp_len(msg) - sizeof(*bgph);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (data_len < 0)</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%);">+     rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, tp, ARRAY_SIZE(tp), bgph->pdu_type, bgph->data, data_len, 0, 0,</span><br><span style="color: hsl(120, 100%, 40%);">+                           DLBSSGP, __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc < 0)</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%);">+     if (TLVP_PRESENT(&tp[0], BSSGP_IE_RIM_ROUTING_INFO)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = bssgp_parse_rim_ri(&pdu->routing_info_dest, TLVP_VAL(&tp[0], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(120, 100%, 40%);">+                                      TLVP_LEN(&tp[0], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(120, 100%, 40%);">+             if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) invalid Destination Cell Identifier IE\n", nsei);</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%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing Destination Cell Identifier IE\n", nsei);</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%);">+   if (TLVP_PRESENT(&tp[1], BSSGP_IE_RIM_ROUTING_INFO)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            rc = bssgp_parse_rim_ri(&pdu->routing_info_src, TLVP_VAL(&tp[1], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(120, 100%, 40%);">+                                       TLVP_LEN(&tp[1], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(120, 100%, 40%);">+             if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) invalid Destination Cell Identifier IE\n", nsei);</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%);">+     } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing Source Cell Identifier IE\n", nsei);</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%);">+   if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_REQ_RIM_CONTAINER))</span><br><span style="color: hsl(120, 100%, 40%);">+          pdu->rim_cont_iei = BSSGP_IE_RI_REQ_RIM_CONTAINER;</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_RIM_CONTAINER))</span><br><span style="color: hsl(120, 100%, 40%);">+         pdu->rim_cont_iei = BSSGP_IE_RI_RIM_CONTAINER;</span><br><span style="color: hsl(120, 100%, 40%);">+     else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_APP_ERROR_RIM_CONT))</span><br><span style="color: hsl(120, 100%, 40%);">+            pdu->rim_cont_iei = BSSGP_IE_RI_APP_ERROR_RIM_CONT;</span><br><span style="color: hsl(120, 100%, 40%);">+        else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_ACK_RIM_CONTAINER))</span><br><span style="color: hsl(120, 100%, 40%);">+             pdu->rim_cont_iei = BSSGP_IE_RI_ACK_RIM_CONTAINER;</span><br><span style="color: hsl(120, 100%, 40%);">+ else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_ERROR_RIM_COINTAINER))</span><br><span style="color: hsl(120, 100%, 40%);">+          pdu->rim_cont_iei = BSSGP_IE_RI_ERROR_RIM_COINTAINER;</span><br><span style="color: hsl(120, 100%, 40%);">+      else {</span><br><span style="color: hsl(120, 100%, 40%);">+                LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing or wrong RIM Container IE\n", nsei);</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%);">+   pdu->rim_cont = TLVP_VAL(&tp[0], pdu->rim_cont_iei);</span><br><span style="color: hsl(120, 100%, 40%);">+        pdu->rim_cont_len = TLVP_LEN(&tp[0], pdu->rim_cont_iei);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  /* Make sure the rim container field is not empty */</span><br><span style="color: hsl(120, 100%, 40%);">+  if (pdu->rim_cont_len < 1)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!pdu->rim_cont)</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%);">+     /* Note: It is not an error if we fail to parse the RIM container,</span><br><span style="color: hsl(120, 100%, 40%);">+     * since there are applications where parsing the RIM container</span><br><span style="color: hsl(120, 100%, 40%);">+        * is not necessary (routing). It is up to the API user to check</span><br><span style="color: hsl(120, 100%, 40%);">+       * the results. */</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+           rc = bssgp_dec_ran_inf_req_rim_cont(&pdu->decoded.req_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = bssgp_dec_ran_inf_rim_cont(&pdu->decoded.rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(120, 100%, 40%);">+          rc = bssgp_dec_ran_inf_app_err_rim_cont(&pdu->decoded.app_err_rim_cont, pdu->rim_cont,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                      pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+           rc = bssgp_dec_ran_inf_ack_rim_cont(&pdu->decoded.ack_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = bssgp_dec_ran_inf_err_rim_cont(&pdu->decoded.err_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</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%);">+              LOGP(DLBSSGP, LOGL_DEBUG, "BSSGP RIM (NSEI=%u) cannot parse unknown RIM container.\n", nsei);</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%);">+     if (rc < 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              LOGP(DLBSSGP, LOGL_DEBUG, "BSSGP RIM (NSEI=%u) unable to parse RIM container.\n", nsei);</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%);">+     pdu->decoded_present = true;</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 a given rim-pdu struct into a message buffer.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] pdu user provided memory that contains the RAN INFORMATION PDU to encode.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns BSSGP message buffer on sccess, NULL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb *bssgp_encode_rim_pdu(const struct bssgp_ran_information_pdu *pdu)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct msgb *msg = bssgp_msgb_alloc();</span><br><span style="color: hsl(120, 100%, 40%);">+        struct bssgp_normal_hdr *bgph;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t rim_ri_buf[BSSGP_RIM_ROUTING_INFO_MAXLEN];</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *rim_cont_buf;</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%);">+     if (!msg)</span><br><span style="color: hsl(120, 100%, 40%);">+             return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  bgph = (struct bssgp_normal_hdr *)msgb_put(msg, sizeof(*bgph));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Set PDU type based on RIM container type */</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(120, 100%, 40%);">+       case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+           bgph->pdu_type = BSSGP_PDUT_RAN_INFO_REQ;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+               bgph->pdu_type = BSSGP_PDUT_RAN_INFO;</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(120, 100%, 40%);">+          bgph->pdu_type = BSSGP_PDUT_RAN_INFO_APP_ERROR;</span><br><span style="color: hsl(120, 100%, 40%);">+            break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+           bgph->pdu_type = BSSGP_PDUT_RAN_INFO_ACK;</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+                bgph->pdu_type = BSSGP_PDUT_RAN_INFO_ERROR;</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%);">+              /* The caller must correctly specify the container type! */</span><br><span style="color: hsl(120, 100%, 40%);">+           OSMO_ASSERT(false);</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%);">+   /* Put RIM routing information */</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_create_rim_ri(rim_ri_buf, &pdu->routing_info_dest);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc < 0 || rc > BSSGP_RIM_ROUTING_INFO_MAXLEN)</span><br><span style="color: hsl(120, 100%, 40%);">+               goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_tvlv_put(msg, BSSGP_IE_RIM_ROUTING_INFO, rc, rim_ri_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bssgp_create_rim_ri(rim_ri_buf, &pdu->routing_info_src);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rc < 0 || rc > BSSGP_RIM_ROUTING_INFO_MAXLEN)</span><br><span style="color: hsl(120, 100%, 40%);">+               goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_tvlv_put(msg, BSSGP_IE_RIM_ROUTING_INFO, rc, rim_ri_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* Put RIM container */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (pdu->decoded_present) {</span><br><span style="color: hsl(120, 100%, 40%);">+                rim_cont_buf = talloc_zero_size(msg, msg->data_len);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (!rim_cont_buf)</span><br><span style="color: hsl(120, 100%, 40%);">+                    goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(120, 100%, 40%);">+               case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+                   rc = bssgp_enc_ran_inf_req_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.req_rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+                       rc = bssgp_enc_ran_inf_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(120, 100%, 40%);">+                  rc = bssgp_enc_ran_inf_app_err_rim_cont(rim_cont_buf, msg->data_len,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                               &pdu->decoded.app_err_rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+                   rc = bssgp_enc_ran_inf_ack_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.ack_rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+                       break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(120, 100%, 40%);">+                        rc = bssgp_enc_ran_inf_err_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.err_rim_cont);</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%);">+                      /* The API user must set the iei properly! */</span><br><span style="color: hsl(120, 100%, 40%);">+                 OSMO_ASSERT(false);</span><br><span style="color: hsl(120, 100%, 40%);">+           }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                        goto error;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+         msgb_tvlv_put(msg, pdu->rim_cont_iei, rc, rim_cont_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+           talloc_free(rim_cont_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+    } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              /* Make sure the RIM container is actually present. */</span><br><span style="color: hsl(120, 100%, 40%);">+                OSMO_ASSERT(pdu->rim_cont_iei != 0 && pdu->rim_cont_len > 0 && pdu->rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+            msgb_tvlv_put(msg, pdu->rim_cont_iei, pdu->rim_cont_len, pdu->rim_cont);</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 msg;</span><br><span style="color: hsl(120, 100%, 40%);">+error:</span><br><span style="color: hsl(120, 100%, 40%);">+   talloc_free(rim_cont_buf);</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_free(msg);</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%);">+/*! Send RIM RAN INFORMATION REQUEST via BSSGP (3GPP TS 48.018, section 10.6.1).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] pdu user provided memory for the RAN INFORMATION PDU to be sent.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] nsei BSSGP network service entity identifier (NSEI).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on sccess, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_tx_rim(const struct bssgp_ran_information_pdu *pdu, uint16_t nsei)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct msgb *msg;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct bssgp_normal_hdr *bgph;</span><br><span style="color: hsl(120, 100%, 40%);">+        char ri_src_str[64];</span><br><span style="color: hsl(120, 100%, 40%);">+  char ri_dest_str[64];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Encode RIM PDU into mesage buffer */</span><br><span style="color: hsl(120, 100%, 40%);">+       msg = bssgp_encode_rim_pdu(pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (!msg) {</span><br><span style="color: hsl(120, 100%, 40%);">+           LOGP(DLBSSGP, LOGL_ERROR,</span><br><span style="color: hsl(120, 100%, 40%);">+                  "BSSGP RIM (NSEI=%u) unable to encode BSSGP RIM PDU\n", nsei);</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%);">+   msgb_nsei(msg) = nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+        msgb_bvci(msg) = 0;     /* Signalling */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    bgph = (struct bssgp_normal_hdr *)msgb_bssgph(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+   DEBUGP(DLBSSGP, "BSSGP BVCI=0 Tx RIM-PDU:%s, src=%s, dest=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+           bssgp_pdu_str(bgph->pdu_type),</span><br><span style="color: hsl(120, 100%, 40%);">+             bssgp_rim_ri_name_buf(ri_src_str, sizeof(ri_src_str), &pdu->routing_info_src),</span><br><span style="color: hsl(120, 100%, 40%);">+         bssgp_rim_ri_name_buf(ri_dest_str, sizeof(ri_dest_str), &pdu->routing_info_dest));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return bssgp_ns_send(bssgp_ns_send_data, msg);</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%);">+/* For internal use only (called from gprs_bssgp.c) */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_rx_rim(struct msgb *msg, struct tlv_parsed *tp, uint16_t bvci)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      struct osmo_bssgp_prim nmp;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint16_t nsei = msgb_nsei(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *)msgb_bssgph(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+  enum bssgp_prim prim;</span><br><span style="color: hsl(120, 100%, 40%);">+ char ri_src_str[64];</span><br><span style="color: hsl(120, 100%, 40%);">+  char ri_dest_str[64];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Specify PRIM type based on the RIM PDU */</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (bgph->pdu_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+  case BSSGP_PDUT_RAN_INFO:</span><br><span style="color: hsl(120, 100%, 40%);">+     case BSSGP_PDUT_RAN_INFO_REQ:</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_PDUT_RAN_INFO_ACK:</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSGP_PDUT_RAN_INFO_ERROR:</span><br><span style="color: hsl(120, 100%, 40%);">+       case BSSGP_PDUT_RAN_INFO_APP_ERROR:</span><br><span style="color: hsl(120, 100%, 40%);">+           prim = PRIM_BSSGP_RIM_PDU_TRANSFER;</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%);">+              /* Caller already makes sure that this can't happen. */</span><br><span style="color: hsl(120, 100%, 40%);">+           OSMO_ASSERT(false);</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%);">+   /* Send BSSGP RIM indication to NM */</span><br><span style="color: hsl(120, 100%, 40%);">+ memset(&nmp, 0, sizeof(nmp));</span><br><span style="color: hsl(120, 100%, 40%);">+     nmp.nsei = nsei;</span><br><span style="color: hsl(120, 100%, 40%);">+      nmp.bvci = bvci;</span><br><span style="color: hsl(120, 100%, 40%);">+      nmp.tp = tp;</span><br><span style="color: hsl(120, 100%, 40%);">+  if (bssgp_parse_rim_pdu(&nmp.u.rim_pdu, msg) < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+              return bssgp_tx_status(BSSGP_CAUSE_MISSING_MAND_IE, NULL, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       DEBUGP(DLBSSGP, "BSSGP BVCI=%u Rx RIM-PDU:%s, src=%s, dest=%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+          bvci, bssgp_pdu_str(bgph->pdu_type),</span><br><span style="color: hsl(120, 100%, 40%);">+               bssgp_rim_ri_name_buf(ri_src_str, sizeof(ri_src_str), &nmp.u.rim_pdu.routing_info_src),</span><br><span style="color: hsl(120, 100%, 40%);">+           bssgp_rim_ri_name_buf(ri_dest_str, sizeof(ri_dest_str), &nmp.u.rim_pdu.routing_info_dest));</span><br><span style="color: hsl(120, 100%, 40%);">+        osmo_prim_init(&nmp.oph, SAP_BSSGP_RIM, prim, PRIM_OP_INDICATION, msg);</span><br><span style="color: hsl(120, 100%, 40%);">+   bssgp_prim_cb(&nmp.oph, NULL);</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>diff --git a/src/gb/gprs_bssgp_util.c b/src/gb/gprs_bssgp_util.c</span><br><span>index e00aed9..92896c1 100644</span><br><span>--- a/src/gb/gprs_bssgp_util.c</span><br><span>+++ b/src/gb/gprs_bssgp_util.c</span><br><span>@@ -588,223 +588,3 @@</span><br><span> </span><br><span>        return bssgp_ns_send(bssgp_ns_send_data, msg);</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Chapter 10.6.1: RAN-INFORMATION-REQUEST */</span><br><span style="color: hsl(0, 100%, 40%);">-int bssgp_tx_rim(const struct bssgp_ran_information_pdu *pdu, uint16_t nsei)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-   struct msgb *msg;</span><br><span style="color: hsl(0, 100%, 40%);">-       struct bssgp_normal_hdr *bgph;</span><br><span style="color: hsl(0, 100%, 40%);">-  char ri_src_str[64];</span><br><span style="color: hsl(0, 100%, 40%);">-    char ri_dest_str[64];</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   /* Encode RIM PDU into mesage buffer */</span><br><span style="color: hsl(0, 100%, 40%);">- msg = bssgp_encode_rim_pdu(pdu);</span><br><span style="color: hsl(0, 100%, 40%);">-        if (!msg) {</span><br><span style="color: hsl(0, 100%, 40%);">-             LOGP(DLBSSGP, LOGL_ERROR,</span><br><span style="color: hsl(0, 100%, 40%);">-                    "BSSGP RIM (NSEI=%u) unable to encode BSSGP RIM PDU\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-           return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       msgb_nsei(msg) = nsei;</span><br><span style="color: hsl(0, 100%, 40%);">-  msgb_bvci(msg) = 0;     /* Signalling */</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        bgph = (struct bssgp_normal_hdr *)msgb_bssgph(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-     DEBUGP(DLBSSGP, "BSSGP BVCI=0 Tx RIM-PDU:%s, src=%s, dest=%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">-             bssgp_pdu_str(bgph->pdu_type),</span><br><span style="color: hsl(0, 100%, 40%);">-               bssgp_rim_ri_name_buf(ri_src_str, sizeof(ri_src_str), &pdu->routing_info_src),</span><br><span style="color: hsl(0, 100%, 40%);">-           bssgp_rim_ri_name_buf(ri_dest_str, sizeof(ri_dest_str), &pdu->routing_info_dest));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-        return bssgp_ns_send(bssgp_ns_send_data, msg);</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Parse a given message buffer into a rim-pdu struct */</span><br><span style="color: hsl(0, 100%, 40%);">-int bssgp_parse_rim_pdu(struct bssgp_ran_information_pdu *pdu, const struct msgb *msg)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-  struct tlv_parsed tp[2];</span><br><span style="color: hsl(0, 100%, 40%);">-        struct bssgp_normal_hdr *bgph = (struct bssgp_normal_hdr *)msgb_bssgph(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-    int data_len;</span><br><span style="color: hsl(0, 100%, 40%);">-   int rc;</span><br><span style="color: hsl(0, 100%, 40%);">- uint16_t nsei = msgb_nsei(msg);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- memset(pdu, 0, sizeof(*pdu));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-   data_len = msgb_bssgp_len(msg) - sizeof(*bgph);</span><br><span style="color: hsl(0, 100%, 40%);">- if (data_len < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-            return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- rc = osmo_tlv_prot_parse(&osmo_pdef_bssgp, tp, ARRAY_SIZE(tp), bgph->pdu_type, bgph->data, data_len, 0, 0,</span><br><span style="color: hsl(0, 100%, 40%);">-                             DLBSSGP, __func__);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-          return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (TLVP_PRESENT(&tp[0], BSSGP_IE_RIM_ROUTING_INFO)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              rc = bssgp_parse_rim_ri(&pdu->routing_info_dest, TLVP_VAL(&tp[0], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(0, 100%, 40%);">-                                        TLVP_LEN(&tp[0], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(0, 100%, 40%);">-               if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) invalid Destination Cell Identifier IE\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-                      return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing Destination Cell Identifier IE\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-              return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (TLVP_PRESENT(&tp[1], BSSGP_IE_RIM_ROUTING_INFO)) {</span><br><span style="color: hsl(0, 100%, 40%);">-              rc = bssgp_parse_rim_ri(&pdu->routing_info_src, TLVP_VAL(&tp[1], BSSGP_IE_RIM_ROUTING_INFO),</span><br><span style="color: hsl(0, 100%, 40%);">-                                 TLVP_LEN(&tp[1], BSSGP_IE_RIM_ROUTING_INFO));</span><br><span style="color: hsl(0, 100%, 40%);">-               if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) invalid Destination Cell Identifier IE\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-                      return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-         }</span><br><span style="color: hsl(0, 100%, 40%);">-       } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing Source Cell Identifier IE\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-           return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_REQ_RIM_CONTAINER))</span><br><span style="color: hsl(0, 100%, 40%);">-            pdu->rim_cont_iei = BSSGP_IE_RI_REQ_RIM_CONTAINER;</span><br><span style="color: hsl(0, 100%, 40%);">-   else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_RIM_CONTAINER))</span><br><span style="color: hsl(0, 100%, 40%);">-           pdu->rim_cont_iei = BSSGP_IE_RI_RIM_CONTAINER;</span><br><span style="color: hsl(0, 100%, 40%);">-       else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_APP_ERROR_RIM_CONT))</span><br><span style="color: hsl(0, 100%, 40%);">-              pdu->rim_cont_iei = BSSGP_IE_RI_APP_ERROR_RIM_CONT;</span><br><span style="color: hsl(0, 100%, 40%);">-  else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_ACK_RIM_CONTAINER))</span><br><span style="color: hsl(0, 100%, 40%);">-               pdu->rim_cont_iei = BSSGP_IE_RI_ACK_RIM_CONTAINER;</span><br><span style="color: hsl(0, 100%, 40%);">-   else if (TLVP_PRESENT(&tp[0], BSSGP_IE_RI_ERROR_RIM_COINTAINER))</span><br><span style="color: hsl(0, 100%, 40%);">-            pdu->rim_cont_iei = BSSGP_IE_RI_ERROR_RIM_COINTAINER;</span><br><span style="color: hsl(0, 100%, 40%);">-        else {</span><br><span style="color: hsl(0, 100%, 40%);">-          LOGP(DLBSSGP, LOGL_ERROR, "BSSGP RIM (NSEI=%u) missing or wrong RIM Container IE\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-           return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       pdu->rim_cont = TLVP_VAL(&tp[0], pdu->rim_cont_iei);</span><br><span style="color: hsl(0, 100%, 40%);">-  pdu->rim_cont_len = TLVP_LEN(&tp[0], pdu->rim_cont_iei);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-      /* Make sure the rim container field is not empty */</span><br><span style="color: hsl(0, 100%, 40%);">-    if (pdu->rim_cont_len < 1)</span><br><span style="color: hsl(0, 100%, 40%);">-                return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">- if (!pdu->rim_cont)</span><br><span style="color: hsl(0, 100%, 40%);">-          return -EINVAL;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Note: It is not an error if we fail to parse the RIM container,</span><br><span style="color: hsl(0, 100%, 40%);">-       * since there are applications where parsing the RIM container</span><br><span style="color: hsl(0, 100%, 40%);">-  * is not necessary (routing). It is up to the API user to check</span><br><span style="color: hsl(0, 100%, 40%);">-         * the results. */</span><br><span style="color: hsl(0, 100%, 40%);">-      switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(0, 100%, 40%);">- case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = bssgp_dec_ran_inf_req_rim_cont(&pdu->decoded.req_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(0, 100%, 40%);">-         break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-         rc = bssgp_dec_ran_inf_rim_cont(&pdu->decoded.rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(0, 100%, 40%);">-         break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(0, 100%, 40%);">-            rc = bssgp_dec_ran_inf_app_err_rim_cont(&pdu->decoded.app_err_rim_cont, pdu->rim_cont,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                        pdu->rim_cont_len);</span><br><span style="color: hsl(0, 100%, 40%);">-          break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-             rc = bssgp_dec_ran_inf_ack_rim_cont(&pdu->decoded.ack_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(0, 100%, 40%);">-         break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-          rc = bssgp_dec_ran_inf_err_rim_cont(&pdu->decoded.err_rim_cont, pdu->rim_cont, pdu->rim_cont_len);</span><br><span style="color: hsl(0, 100%, 40%);">-         break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLBSSGP, LOGL_DEBUG, "BSSGP RIM (NSEI=%u) cannot parse unknown RIM container.\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-         return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       if (rc < 0) {</span><br><span style="color: hsl(0, 100%, 40%);">-                LOGP(DLBSSGP, LOGL_DEBUG, "BSSGP RIM (NSEI=%u) unable to parse RIM container.\n", nsei);</span><br><span style="color: hsl(0, 100%, 40%);">-              return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-       pdu->decoded_present = true;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-/* Encode a given rim-pdu struct into a message buffer */</span><br><span style="color: hsl(0, 100%, 40%);">-struct msgb *bssgp_encode_rim_pdu(const struct bssgp_ran_information_pdu *pdu)</span><br><span style="color: hsl(0, 100%, 40%);">-{</span><br><span style="color: hsl(0, 100%, 40%);">-      struct msgb *msg = bssgp_msgb_alloc();</span><br><span style="color: hsl(0, 100%, 40%);">-  struct bssgp_normal_hdr *bgph;</span><br><span style="color: hsl(0, 100%, 40%);">-  uint8_t rim_ri_buf[BSSGP_RIM_ROUTING_INFO_MAXLEN];</span><br><span style="color: hsl(0, 100%, 40%);">-      uint8_t *rim_cont_buf;</span><br><span style="color: hsl(0, 100%, 40%);">-  int rc;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if (!msg)</span><br><span style="color: hsl(0, 100%, 40%);">-               return NULL;</span><br><span style="color: hsl(0, 100%, 40%);">-    bgph = (struct bssgp_normal_hdr *)msgb_put(msg, sizeof(*bgph));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- /* Set PDU type based on RIM container type */</span><br><span style="color: hsl(0, 100%, 40%);">-  switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(0, 100%, 40%);">- case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-             bgph->pdu_type = BSSGP_PDUT_RAN_INFO_REQ;</span><br><span style="color: hsl(0, 100%, 40%);">-            break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-         bgph->pdu_type = BSSGP_PDUT_RAN_INFO;</span><br><span style="color: hsl(0, 100%, 40%);">-                break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(0, 100%, 40%);">-            bgph->pdu_type = BSSGP_PDUT_RAN_INFO_APP_ERROR;</span><br><span style="color: hsl(0, 100%, 40%);">-              break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-             bgph->pdu_type = BSSGP_PDUT_RAN_INFO_ACK;</span><br><span style="color: hsl(0, 100%, 40%);">-            break;</span><br><span style="color: hsl(0, 100%, 40%);">-  case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-          bgph->pdu_type = BSSGP_PDUT_RAN_INFO_ERROR;</span><br><span style="color: hsl(0, 100%, 40%);">-          break;</span><br><span style="color: hsl(0, 100%, 40%);">-  default:</span><br><span style="color: hsl(0, 100%, 40%);">-                /* The caller must correctly specify the container type! */</span><br><span style="color: hsl(0, 100%, 40%);">-             OSMO_ASSERT(false);</span><br><span style="color: hsl(0, 100%, 40%);">-     }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       /* Put RIM routing information */</span><br><span style="color: hsl(0, 100%, 40%);">-       rc = bssgp_create_rim_ri(rim_ri_buf, &pdu->routing_info_dest);</span><br><span style="color: hsl(0, 100%, 40%);">-   if (rc < 0 || rc > BSSGP_RIM_ROUTING_INFO_MAXLEN)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto error;</span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_tvlv_put(msg, BSSGP_IE_RIM_ROUTING_INFO, rc, rim_ri_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-  rc = bssgp_create_rim_ri(rim_ri_buf, &pdu->routing_info_src);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (rc < 0 || rc > BSSGP_RIM_ROUTING_INFO_MAXLEN)</span><br><span style="color: hsl(0, 100%, 40%);">-         goto error;</span><br><span style="color: hsl(0, 100%, 40%);">-     msgb_tvlv_put(msg, BSSGP_IE_RIM_ROUTING_INFO, rc, rim_ri_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-  /* Put RIM container */</span><br><span style="color: hsl(0, 100%, 40%);">- if (pdu->decoded_present) {</span><br><span style="color: hsl(0, 100%, 40%);">-          rim_cont_buf = talloc_zero_size(msg, msg->data_len);</span><br><span style="color: hsl(0, 100%, 40%);">-         if (!rim_cont_buf)</span><br><span style="color: hsl(0, 100%, 40%);">-                      goto error;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             switch (pdu->rim_cont_iei) {</span><br><span style="color: hsl(0, 100%, 40%);">-         case BSSGP_IE_RI_REQ_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-                     rc = bssgp_enc_ran_inf_req_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.req_rim_cont);</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case BSSGP_IE_RI_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-                 rc = bssgp_enc_ran_inf_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.rim_cont);</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case BSSGP_IE_RI_APP_ERROR_RIM_CONT:</span><br><span style="color: hsl(0, 100%, 40%);">-                    rc = bssgp_enc_ran_inf_app_err_rim_cont(rim_cont_buf, msg->data_len,</span><br><span style="color: hsl(0, 100%, 40%);">-                                                         &pdu->decoded.app_err_rim_cont);</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case BSSGP_IE_RI_ACK_RIM_CONTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-                     rc = bssgp_enc_ran_inf_ack_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.ack_rim_cont);</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case BSSGP_IE_RI_ERROR_RIM_COINTAINER:</span><br><span style="color: hsl(0, 100%, 40%);">-                  rc = bssgp_enc_ran_inf_err_rim_cont(rim_cont_buf, msg->data_len, &pdu->decoded.err_rim_cont);</span><br><span style="color: hsl(0, 100%, 40%);">-                 break;</span><br><span style="color: hsl(0, 100%, 40%);">-          default:</span><br><span style="color: hsl(0, 100%, 40%);">-                        /* The API user must set the iei properly! */</span><br><span style="color: hsl(0, 100%, 40%);">-                   OSMO_ASSERT(false);</span><br><span style="color: hsl(0, 100%, 40%);">-             }</span><br><span style="color: hsl(0, 100%, 40%);">-               if (rc < 0)</span><br><span style="color: hsl(0, 100%, 40%);">-                  goto error;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-             msgb_tvlv_put(msg, pdu->rim_cont_iei, rc, rim_cont_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-             talloc_free(rim_cont_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-      } else {</span><br><span style="color: hsl(0, 100%, 40%);">-                /* Make sure the RIM container is actually present. */</span><br><span style="color: hsl(0, 100%, 40%);">-          OSMO_ASSERT(pdu->rim_cont_iei != 0 && pdu->rim_cont_len > 0 && pdu->rim_cont);</span><br><span style="color: hsl(0, 100%, 40%);">-              msgb_tvlv_put(msg, pdu->rim_cont_iei, pdu->rim_cont_len, pdu->rim_cont);</span><br><span style="color: hsl(0, 100%, 40%);">-       }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">-       return msg;</span><br><span style="color: hsl(0, 100%, 40%);">-error:</span><br><span style="color: hsl(0, 100%, 40%);">-       talloc_free(rim_cont_buf);</span><br><span style="color: hsl(0, 100%, 40%);">-      msgb_free(msg);</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">-}</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/22442">change 22442</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/+/22442"/><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: Icda279452962b06e552cb1361d2a27b7dc8a6b04 </div>
<div style="display:none"> Gerrit-Change-Number: 22442 </div>
<div style="display:none"> Gerrit-PatchSet: 6 </div>
<div style="display:none"> Gerrit-Owner: dexter <pmaier@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: laforge <laforge@osmocom.org> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>