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

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">bssgp_rim: add encoder/decoder for NACC related RIM containers<br><br>BSSGP RIM uses a number of nested containers to signal RIM application<br>specific payload information in a generic way. Lets add the container<br>structurs required for NACC.<br><br>Depends: libosmocore If48f412c32e8e5a3e604a78d12b74787a4786374<br>Change-Id: Ibbc7fd67658e3040c12abb5706fe9d1f31894352<br>Related: SYS#5103<br>---<br>M include/Makefile.am<br>A include/osmocom/gprs/gprs_bssgp_rim.h<br>M src/gb/Makefile.am<br>A src/gb/gprs_bssgp_rim.c<br>M src/gb/libosmogb.map<br>M tests/Makefile.am<br>A tests/gb/gprs_bssgp_rim_test.c<br>A tests/gb/gprs_bssgp_rim_test.ok<br>M tests/testsuite.at<br>9 files changed, 1,859 insertions(+), 2 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/Makefile.am b/include/Makefile.am</span><br><span>index c1ae644..10f0221 100644</span><br><span>--- a/include/Makefile.am</span><br><span>+++ b/include/Makefile.am</span><br><span>@@ -69,6 +69,7 @@</span><br><span>                        osmocom/gprs/gprs_bssgp.h \</span><br><span>                        osmocom/gprs/gprs_bssgp2.h \</span><br><span>                        osmocom/gprs/gprs_bssgp_bss.h \</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmocom/gprs/gprs_bssgp_rim.h \</span><br><span>                        osmocom/gprs/gprs_msgb.h \</span><br><span>                        osmocom/gprs/gprs_ns.h \</span><br><span>                        osmocom/gprs/gprs_ns_frgre.h \</span><br><span>diff --git a/include/osmocom/gprs/gprs_bssgp_rim.h b/include/osmocom/gprs/gprs_bssgp_rim.h</span><br><span>new file mode 100644</span><br><span>index 0000000..0612a91</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/gprs/gprs_bssgp_rim.h</span><br><span>@@ -0,0 +1,182 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \file gprs_bssgp.h</span><br><span style="color: hsl(120, 100%, 40%);">+ * GPRS BSSGP RIM protocol implementation as per 3GPP TS 48.018. */</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2020-2021 by sysmocom - s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Philipp Maier <pmaier@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#pragma once</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/protocol/gsm_08_18.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.018, table 11.3.63.1.1: RAN-INFORMATION-REQUEST Application Container coding for NACC */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_inf_req_app_cont_nacc {</span><br><span style="color: hsl(120, 100%, 40%);">+    struct osmo_cell_global_id_ps reprt_cell;</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_dec_ran_inf_req_app_cont_nacc(struct bssgp_ran_inf_req_app_cont_nacc *cont, const uint8_t *buf, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_req_app_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_ran_inf_req_app_cont_nacc *cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Length of NACC system information, see also: 3GPP TS 48.018 11.3.63.2.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define BSSGP_RIM_SI_LEN 21</span><br><span style="color: hsl(120, 100%, 40%);">+#define BSSGP_RIM_PSI_LEN 22</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.018, table 11.3.63.2.1.a: RAN-INFORMATION Application Container coding for NACC */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_inf_app_cont_nacc {</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_cell_global_id_ps reprt_cell;</span><br><span style="color: hsl(120, 100%, 40%);">+     bool type_psi;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t num_si;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Pointer to system information messages */</span><br><span style="color: hsl(120, 100%, 40%);">+  const uint8_t *si[127];</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_dec_ran_inf_app_cont_nacc(struct bssgp_ran_inf_app_cont_nacc *cont, const uint8_t *buf, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_app_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_ran_inf_app_cont_nacc *cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.018, table 11.3.64.1.b, NACC Cause coding */</span><br><span style="color: hsl(120, 100%, 40%);">+enum bssgp_nacc_cause {</span><br><span style="color: hsl(120, 100%, 40%);">+  BSSGP_NACC_CAUSE_UNSPEC,</span><br><span style="color: hsl(120, 100%, 40%);">+      BSSGP_NACC_CAUSE_SYNTAX_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+  BSSGP_NACC_CAUSE_RPRT_CELL_MISSMTCH,</span><br><span style="color: hsl(120, 100%, 40%);">+  BSSGP_NACC_CAUSE_SIPSI_TYPE_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+      BSSGP_NACC_CAUSE_SIPSI_LEN_ERR,</span><br><span style="color: hsl(120, 100%, 40%);">+       BSSGP_NACC_CAUSE_SIPSI_SET_ERR,</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%);">+/* 3GPP TS 48.018, table 11.3.64.1.a, Application Error Container coding for NACC */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_app_err_cont_nacc {</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bssgp_nacc_cause nacc_cause;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Pointer to errornous application container */</span><br><span style="color: hsl(120, 100%, 40%);">+      const uint8_t *err_app_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+  size_t err_app_cont_len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_app_err_cont_nacc(struct bssgp_app_err_cont_nacc *cont, const uint8_t *buf, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_app_err_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_app_err_cont_nacc *cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.018, table 11.3.61.b: RIM Application Identity coding */</span><br><span style="color: hsl(120, 100%, 40%);">+enum bssgp_ran_inf_app_id {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSGP_RAN_INF_APP_ID_NACC = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+        BSSGP_RAN_INF_APP_ID_SI3 = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSGP_RAN_INF_APP_ID_MBMS = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+        BSSGP_RAN_INF_APP_ID_SON = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSGP_RAN_INF_APP_ID_UTRA_SI = 5,</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%);">+/* 3GPP TS 48.018, table 11.3.62a.1.b: RAN-INFORMATION-REQUEST RIM Container Contents */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_inf_req_rim_cont {</span><br><span style="color: hsl(120, 100%, 40%);">+        enum bssgp_ran_inf_app_id app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t seq_num;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct bssgp_rim_pdu_ind pdu_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t prot_ver;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Nested application container */</span><br><span style="color: hsl(120, 100%, 40%);">+    union {</span><br><span style="color: hsl(120, 100%, 40%);">+               struct bssgp_ran_inf_req_app_cont_nacc app_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+         /* TODO: add containers for Si3, MBMS, SON, UTRA-SI */</span><br><span style="color: hsl(120, 100%, 40%);">+        } u;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",</span><br><span style="color: hsl(120, 100%, 40%);">+        * see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t *son_trans_app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t son_trans_app_id_len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_req_rim_cont(struct bssgp_ran_inf_req_rim_cont *cont, const uint8_t *buf, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_req_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_req_rim_cont *cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.018, table 11.3.62a.2.b: RAN-INFORMATION RIM Container Contents */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_inf_rim_cont {</span><br><span style="color: hsl(120, 100%, 40%);">+   enum bssgp_ran_inf_app_id app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t seq_num;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct bssgp_rim_pdu_ind pdu_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t prot_ver;</span><br><span style="color: hsl(120, 100%, 40%);">+     bool app_err;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       /* Nested application container */</span><br><span style="color: hsl(120, 100%, 40%);">+    union {</span><br><span style="color: hsl(120, 100%, 40%);">+               struct bssgp_ran_inf_app_cont_nacc app_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+             struct bssgp_app_err_cont_nacc app_err_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+             /* TODO: add containers for Si3, MBMS, SON, UTRA-SI */</span><br><span style="color: hsl(120, 100%, 40%);">+        } u;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        /* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",</span><br><span style="color: hsl(120, 100%, 40%);">+        * see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t *son_trans_app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t son_trans_app_id_len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_rim_cont(struct bssgp_ran_inf_rim_cont *cont, const uint8_t *buf, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_rim_cont *cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.018, table 11.3.62a.3.b: RAN-INFORMATION-ACK RIM Container Contents */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_inf_ack_rim_cont {</span><br><span style="color: hsl(120, 100%, 40%);">+   enum bssgp_ran_inf_app_id app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t seq_num;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t prot_ver;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",</span><br><span style="color: hsl(120, 100%, 40%);">+        * see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t *son_trans_app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t son_trans_app_id_len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_ack_rim_cont(struct bssgp_ran_inf_ack_rim_cont *cont, const uint8_t *buf, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_ack_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_ack_rim_cont *cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.018, table 11.3.62a.4.b: RAN-INFORMATION-ERROR RIM Container Contents */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_inf_err_rim_cont {</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bssgp_ran_inf_app_id app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t cause;</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t prot_ver;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Pointer to (encoded) errornous PDU,</span><br><span style="color: hsl(120, 100%, 40%);">+         * see also: 3GPP TS 48.018, section 11.3.24 */</span><br><span style="color: hsl(120, 100%, 40%);">+       const uint8_t *err_pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+       size_t err_pdu_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ /* Pointer to SON-transfer application identity, only present if app_id is indicating "son-transfer",</span><br><span style="color: hsl(120, 100%, 40%);">+        * see also 3GPP TS 48.018, section 11.3.108 and 3GPP TS 36.413 annex B.1.1 */</span><br><span style="color: hsl(120, 100%, 40%);">+        const uint8_t *son_trans_app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+      size_t son_trans_app_id_len;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_err_rim_cont(struct bssgp_ran_inf_err_rim_cont *cont, const uint8_t *buf, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_err_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_err_rim_cont *cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.018, table 11.3.62a.5.b: RAN-INFORMATION-APPLICATION-ERROR RIM Container Contents */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_inf_app_err_rim_cont {</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bssgp_ran_inf_app_id app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t seq_num;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct bssgp_rim_pdu_ind pdu_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t prot_ver;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* Nested application container */</span><br><span style="color: hsl(120, 100%, 40%);">+    union {</span><br><span style="color: hsl(120, 100%, 40%);">+               struct bssgp_app_err_cont_nacc app_err_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+             /* TODO: add containers for Si3, MBMS, SON, UTRA-SI */</span><br><span style="color: hsl(120, 100%, 40%);">+        } u;</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_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 style="color: hsl(120, 100%, 40%);">+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>diff --git a/src/gb/Makefile.am b/src/gb/Makefile.am</span><br><span>index cbee333..031971b 100644</span><br><span>--- a/src/gb/Makefile.am</span><br><span>+++ b/src/gb/Makefile.am</span><br><span>@@ -22,7 +22,7 @@</span><br><span>              $(top_builddir)/src/gsm/libosmogsm.la</span><br><span> </span><br><span> libosmogb_la_SOURCES = gprs_ns.c gprs_ns_frgre.c gprs_ns_vty.c gprs_ns_sns.c \</span><br><span style="color: hsl(0, 100%, 40%);">-               gprs_bssgp.c gprs_bssgp_util.c gprs_bssgp_vty.c \</span><br><span style="color: hsl(120, 100%, 40%);">+             gprs_bssgp.c gprs_bssgp_util.c gprs_bssgp_vty.c gprs_bssgp_rim.c \</span><br><span>                   gprs_bssgp_bss.c \</span><br><span>                   gprs_ns2.c gprs_ns2_udp.c gprs_ns2_frgre.c gprs_ns2_fr.c gprs_ns2_vc_fsm.c gprs_ns2_sns.c \</span><br><span>                  gprs_ns2_message.c gprs_ns2_vty.c gprs_ns2_vty2.c \</span><br><span>diff --git a/src/gb/gprs_bssgp_rim.c b/src/gb/gprs_bssgp_rim.c</span><br><span>new file mode 100644</span><br><span>index 0000000..3ac405e</span><br><span>--- /dev/null</span><br><span>+++ b/src/gb/gprs_bssgp_rim.c</span><br><span>@@ -0,0 +1,763 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \file gprs_bssgp.c</span><br><span style="color: hsl(120, 100%, 40%);">+ * GPRS BSSGP RIM protocol implementation as per 3GPP TS 48.018. */</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2020-2021 by sysmocom - s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Philipp Maier <pmaier@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * All Rights Reserved</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.0+</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software; you can redistribute it and/or modify</span><br><span style="color: hsl(120, 100%, 40%);">+ * it under the terms of the GNU General Public License as published by</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Free Software Foundation; either version 2 of the License, or</span><br><span style="color: hsl(120, 100%, 40%);">+ * (at your option) any later version.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is distributed in the hope that it will be useful,</span><br><span style="color: hsl(120, 100%, 40%);">+ * but WITHOUT ANY WARRANTY; without even the implied warranty of</span><br><span style="color: hsl(120, 100%, 40%);">+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</span><br><span style="color: hsl(120, 100%, 40%);">+ * GNU General Public License for more details.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * You should have received a copy of the GNU General Public License</span><br><span style="color: hsl(120, 100%, 40%);">+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_bssgp.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_bssgp_rim.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm0808_utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* TVLV IEs use a variable length field. To be sure we will do all buffer</span><br><span style="color: hsl(120, 100%, 40%);">+ * length checks with the maximum possible header length, which is</span><br><span style="color: hsl(120, 100%, 40%);">+ * 1 octet tag + 2 octets length = 3 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define TVLV_HDR_MAXLEN 3</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Usually RIM application containers and their surrounding RIM containers</span><br><span style="color: hsl(120, 100%, 40%);">+ * are not likely to exceed 128 octets, so the usual header length will be 2 */</span><br><span style="color: hsl(120, 100%, 40%);">+#define TVLV_HDR_LEN 2</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* The reporting cell identifier is encoded as a cell identifier IE</span><br><span style="color: hsl(120, 100%, 40%);">+ * (3GPP TS 48.018, sub-clause 11.3.9) but without IE and length octets. */</span><br><span style="color: hsl(120, 100%, 40%);">+#define REP_CELL_ID_LEN 8</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Decode a RAN Information Request Application Container for NACC (3GPP TS 48.018, section 11.3.63.1.1).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] user provided memory for decoded data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user provided memory with the encoded value data of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_req_app_cont_nacc(struct bssgp_ran_inf_req_app_cont_nacc *cont, const uint8_t *buf, size_t len)</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (len < REP_CELL_ID_LEN)</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 = gsm0808_decode_cell_id_u((union gsm0808_cell_id_u*)&cont->reprt_cell,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   CELL_IDENT_WHOLE_GLOBAL_PS, buf, len);</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%);">+     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 RAN Information Request Application Container for NACC (3GPP TS 48.018, section 11.3.63.1.1).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] buf user provided memory for the generated value part of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cont user provided input data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns length of encoded octets, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_req_app_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_ran_inf_req_app_cont_nacc *cont)</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 gprs_ra_id *raid;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (len < REP_CELL_ID_LEN)</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%);">+     raid = (struct gprs_ra_id *)&cont->reprt_cell.rai;</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_create_cell_id(buf, raid, cont->reprt_cell.cell_identity);</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%);">+       return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Decode a RAN Information Application Container (3GPP TS 48.018, section 11.3.63.2.1).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] user provided memory for decoded data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user provided memory with the encoded value data of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_app_cont_nacc(struct bssgp_ran_inf_app_cont_nacc *cont, const uint8_t *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+       int remaining_buf_len;</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%);">+     /* The given buffer must at least contain a reporting cell identifer</span><br><span style="color: hsl(120, 100%, 40%);">+   * plus one octet that defines number/type of attached sysinfo messages. */</span><br><span style="color: hsl(120, 100%, 40%);">+   if (len < REP_CELL_ID_LEN + 1)</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 = gsm0808_decode_cell_id_u((union gsm0808_cell_id_u*)&cont->reprt_cell,</span><br><span style="color: hsl(120, 100%, 40%);">+                                   CELL_IDENT_WHOLE_GLOBAL_PS, buf, len);</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%);">+     buf += REP_CELL_ID_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     cont->type_psi = buf[0] & 1;</span><br><span style="color: hsl(120, 100%, 40%);">+   cont->num_si = buf[0] >> 1;</span><br><span style="color: hsl(120, 100%, 40%);">+  buf++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      /* The number of sysinfo messages may be zero */</span><br><span style="color: hsl(120, 100%, 40%);">+      if (cont->num_si == 0)</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%);">+   /* Check if the prospected system information messages fit in the</span><br><span style="color: hsl(120, 100%, 40%);">+      * remaining buffer space */</span><br><span style="color: hsl(120, 100%, 40%);">+  remaining_buf_len = len - REP_CELL_ID_LEN - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        if (remaining_buf_len <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       if (cont->type_psi && remaining_buf_len / BSSGP_RIM_PSI_LEN < cont->num_si)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       else if (remaining_buf_len / BSSGP_RIM_SI_LEN < cont->num_si)</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%);">+     for (i = 0; i < cont->num_si; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            cont->si[i] = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+         if (cont->type_psi)</span><br><span style="color: hsl(120, 100%, 40%);">+                        buf += BSSGP_RIM_PSI_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+             else</span><br><span style="color: hsl(120, 100%, 40%);">+                  buf += BSSGP_RIM_SI_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   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 RAN Information Application Container (3GPP TS 48.018, section 11.3.63.2.1).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] buf user provided memory for the generated value part of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cont user provided input data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns length of encoded octets, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_app_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_ran_inf_app_cont_nacc *cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+       int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int silen;</span><br><span style="color: hsl(120, 100%, 40%);">+   unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+       struct gprs_ra_id *raid;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (cont->type_psi)</span><br><span style="color: hsl(120, 100%, 40%);">+                silen = BSSGP_RIM_PSI_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+    else</span><br><span style="color: hsl(120, 100%, 40%);">+          silen = BSSGP_RIM_SI_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* The buffer must accept the reporting cell id, plus 1 byte to define</span><br><span style="color: hsl(120, 100%, 40%);">+         * the type and number of sysinfo messages. */</span><br><span style="color: hsl(120, 100%, 40%);">+        if (len < REP_CELL_ID_LEN + 1 + silen * cont->num_si)</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%);">+     raid = (struct gprs_ra_id *)&cont->reprt_cell.rai;</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_create_cell_id(buf_ptr, raid, cont->reprt_cell.cell_identity);</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%);">+       buf_ptr += rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      buf_ptr[0] = 0x00;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (cont->type_psi)</span><br><span style="color: hsl(120, 100%, 40%);">+                buf_ptr[0] |= 0x01;</span><br><span style="color: hsl(120, 100%, 40%);">+   buf_ptr[0] |= (cont->num_si << 1);</span><br><span style="color: hsl(120, 100%, 40%);">+   buf_ptr++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  for (i = 0; i < cont->num_si; i++) {</span><br><span style="color: hsl(120, 100%, 40%);">+            memcpy(buf_ptr, cont->si[i], silen);</span><br><span style="color: hsl(120, 100%, 40%);">+               buf_ptr += silen;</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 (int)(buf_ptr - buf);</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 a Application Error Container for NACC (3GPP TS 48.018, section 11.3.64.1).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] user provided memory for decoded data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user provided memory with the encoded value data of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_app_err_cont_nacc(struct bssgp_app_err_cont_nacc *cont, const uint8_t *buf, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   /* The buffer must at least contain the NACC cause code, it should also</span><br><span style="color: hsl(120, 100%, 40%);">+        * contain the application container, but we won't error if it is missing. */</span><br><span style="color: hsl(120, 100%, 40%);">+     if (len < 1)</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%);">+     cont->nacc_cause = buf[0];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (len > 1) {</span><br><span style="color: hsl(120, 100%, 40%);">+             cont->err_app_cont = buf + 1;</span><br><span style="color: hsl(120, 100%, 40%);">+              cont->err_app_cont_len = len - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+  } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              cont->err_app_cont = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+         cont->err_app_cont_len = 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%);">+   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 Application Error Container for NACC (3GPP TS 48.018, section 11.3.64.1).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] buf user provided memory for the generated value part of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cont user provided input data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns length of encoded octets, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_app_err_cont_nacc(uint8_t *buf, size_t len, const struct bssgp_app_err_cont_nacc *cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* The buffer must accept the length of the application container and the NACC</span><br><span style="color: hsl(120, 100%, 40%);">+         * cause code, which is one octet in length. */</span><br><span style="color: hsl(120, 100%, 40%);">+       if (len < cont->err_app_cont_len + 1)</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%);">+     buf_ptr[0] = cont->nacc_cause;</span><br><span style="color: hsl(120, 100%, 40%);">+     buf_ptr++;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  memcpy(buf_ptr, cont->err_app_cont, cont->err_app_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+    buf_ptr += cont->err_app_cont_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return (int)(buf_ptr - buf);</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%);">+/* The structs bssgp_ran_inf_req_rim_cont, bssgp_ran_inf_rim_cont and bssgp_ran_inf_app_err_rim_cont *cont</span><br><span style="color: hsl(120, 100%, 40%);">+ * share four common fields at the beginning, we use the following struct as parameter type for the common</span><br><span style="color: hsl(120, 100%, 40%);">+ * encoder/decoder functions. (See also 3GPP TS 48.018 table 11.3.62a.1.b, table 11.3.62a.2.b, and</span><br><span style="color: hsl(120, 100%, 40%);">+ * table 11.3.62a.5.b) */</span><br><span style="color: hsl(120, 100%, 40%);">+struct bssgp_ran_inf_x_cont {</span><br><span style="color: hsl(120, 100%, 40%);">+       enum bssgp_ran_inf_app_id app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint32_t seq_num;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct bssgp_rim_pdu_ind pdu_ind;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t prot_ver;</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int dec_rim_cont_common(struct bssgp_ran_inf_x_cont *cont, struct tlv_parsed *tp)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (TLVP_PRES_LEN(tp, BSSGP_IE_RIM_APP_IDENTITY, sizeof(uint8_t)))</span><br><span style="color: hsl(120, 100%, 40%);">+            cont->app_id = TLVP_VAL(tp, BSSGP_IE_RIM_APP_IDENTITY)[0];</span><br><span style="color: hsl(120, 100%, 40%);">+ else</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_PRES_LEN(tp, BSSGP_IE_RIM_SEQ_NR, sizeof(cont->seq_num)))</span><br><span style="color: hsl(120, 100%, 40%);">+         cont->seq_num = tlvp_val32be(tp, BSSGP_IE_RIM_SEQ_NR);</span><br><span style="color: hsl(120, 100%, 40%);">+     else</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_PRES_LEN(tp, BSSGP_IE_RIM_PDU_INDICATIONS, sizeof(cont->pdu_ind)))</span><br><span style="color: hsl(120, 100%, 40%);">+                memcpy(&cont->pdu_ind, TLVP_VAL(tp, BSSGP_IE_RIM_PDU_INDICATIONS), sizeof(cont->pdu_ind));</span><br><span style="color: hsl(120, 100%, 40%);">+  else</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_PRES_LEN(tp, BSSGP_IE_RIM_PROTOCOL_VERSION, sizeof(cont->prot_ver)))</span><br><span style="color: hsl(120, 100%, 40%);">+              cont->prot_ver = TLVP_VAL(tp, BSSGP_IE_RIM_PROTOCOL_VERSION)[0];</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          cont->prot_ver = 1;</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%);">+static uint8_t *enc_rim_cont_common(uint8_t *buf, size_t len, const struct bssgp_ran_inf_x_cont *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%);">+   uint32_t seq_num = osmo_htonl(cont->seq_num);</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t app_id_temp;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (len <</span><br><span style="color: hsl(120, 100%, 40%);">+      TVLV_HDR_MAXLEN * 4 + sizeof(app_id_temp) + sizeof(seq_num) + sizeof(cont->pdu_ind) +</span><br><span style="color: hsl(120, 100%, 40%);">+      sizeof(cont->prot_ver))</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        app_id_temp = cont->app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+        buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_APP_IDENTITY, sizeof(app_id_temp), &app_id_temp);</span><br><span style="color: hsl(120, 100%, 40%);">+        buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_SEQ_NR, sizeof(seq_num), (uint8_t *) & seq_num);</span><br><span style="color: hsl(120, 100%, 40%);">+ buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_PDU_INDICATIONS, sizeof(cont->pdu_ind), (uint8_t *) & cont->pdu_ind);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (cont->prot_ver > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_PROTOCOL_VERSION, sizeof(cont->prot_ver), &cont->prot_ver);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return buf_ptr;</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 a RAN Information Request RIM Container (3GPP TS 48.018, table 11.3.62a.1.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] user provided memory for decoded data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user provided memory with the encoded value data of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_req_rim_cont(struct bssgp_ran_inf_req_rim_cont *cont, const uint8_t *buf, size_t len)</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       memset(cont, 0, sizeof(*cont));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = tlv_parse(&tp, &tvlv_att_def, buf, len, 0, 0);</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%);">+     rc = dec_rim_cont_common((struct bssgp_ran_inf_x_cont *)cont, &tp);</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, BSSGP_IE_RIM_REQ_APP_CONTAINER)) {</span><br><span style="color: hsl(120, 100%, 40%);">+          switch (cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+            case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+                       rc = bssgp_dec_ran_inf_req_app_cont_nacc(&cont->u.app_cont_nacc,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                TLVP_VAL(&tp, BSSGP_IE_RIM_REQ_APP_CONTAINER),</span><br><span style="color: hsl(120, 100%, 40%);">+                                                            TLVP_LEN(&tp, BSSGP_IE_RIM_REQ_APP_CONTAINER));</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+               case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* TODO: add parsers for Si3, MBMS, SON, UTRA-SI app containers */</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               default:</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 (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                        return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (TLVP_PRES_LEN(&tp, BSSGP_IE_SON_TRANSFER_APP_ID, 1)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                cont->son_trans_app_id = TLVP_VAL(&tp, BSSGP_IE_SON_TRANSFER_APP_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+          cont->son_trans_app_id_len = TLVP_LEN(&tp, BSSGP_IE_SON_TRANSFER_APP_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/* Dub a TLVP header into a given buffer. The value part of the IE must start</span><br><span style="color: hsl(120, 100%, 40%);">+ * at the 2nd octet. Should the length field make a 3 octet TLVP header</span><br><span style="color: hsl(120, 100%, 40%);">+ * necessary (unlikely, but possible) the value part is moved ahead by one</span><br><span style="color: hsl(120, 100%, 40%);">+ * octet. The function returns a pointer to the end of value part. */</span><br><span style="color: hsl(120, 100%, 40%);">+static uint8_t *dub_tlvp_header(uint8_t *buf, uint8_t iei, uint16_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     buf_ptr[0] = iei;</span><br><span style="color: hsl(120, 100%, 40%);">+     if (len <= TVLV_MAX_ONEBYTE) {</span><br><span style="color: hsl(120, 100%, 40%);">+             buf_ptr[1] = (uint8_t) len;</span><br><span style="color: hsl(120, 100%, 40%);">+           buf_ptr[1] |= 0x80;</span><br><span style="color: hsl(120, 100%, 40%);">+           buf_ptr += TVLV_HDR_LEN;</span><br><span style="color: hsl(120, 100%, 40%);">+      } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              memmove(buf_ptr + 1, buf_ptr, len);</span><br><span style="color: hsl(120, 100%, 40%);">+           buf_ptr[1] = len >> 8;</span><br><span style="color: hsl(120, 100%, 40%);">+          buf_ptr[1] = len & 0xff;</span><br><span style="color: hsl(120, 100%, 40%);">+          buf_ptr += TVLV_HDR_MAXLEN;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     buf_ptr += len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return buf_ptr;</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 RAN Information Request RIM Container (3GPP TS 48.018, table 11.3.62a.1.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] buf user provided memory for the generated value part of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cont user provided input data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns length of encoded octets, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_req_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_req_rim_cont *cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+       int app_cont_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int remaining_buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      buf_ptr = enc_rim_cont_common(buf_ptr, len, (struct bssgp_ran_inf_x_cont *)cont);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!buf_ptr)</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%);">+     remaining_buf_len = len - (int)(buf_ptr - buf);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (remaining_buf_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%);">+     switch (cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+               app_cont_len =</span><br><span style="color: hsl(120, 100%, 40%);">+                    bssgp_enc_ran_inf_req_app_cont_nacc(buf_ptr + TVLV_HDR_LEN, remaining_buf_len - TVLV_HDR_MAXLEN,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                  &cont->u.app_cont_nacc);</span><br><span style="color: hsl(120, 100%, 40%);">+               break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+       case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+            /* TODO: add encoders for Si3, MBMS, SON, UTRA-SI app containers */</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       default:</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 (app_cont_len < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       buf_ptr = dub_tlvp_header(buf_ptr, BSSGP_IE_RIM_REQ_APP_CONTAINER, app_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   remaining_buf_len = len - (int)(buf_ptr - buf);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (remaining_buf_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%);">+     if (cont->son_trans_app_id && cont->son_trans_app_id_len > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (remaining_buf_len < cont->son_trans_app_id_len + TVLV_HDR_MAXLEN)</span><br><span style="color: hsl(120, 100%, 40%);">+                   return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               buf_ptr =</span><br><span style="color: hsl(120, 100%, 40%);">+                 tvlv_put(buf_ptr, BSSGP_IE_SON_TRANSFER_APP_ID, cont->son_trans_app_id_len, cont->son_trans_app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     return (int)(buf_ptr - buf);</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 a RAN Information RIM Container (3GPP TS 48.018, table 11.3.62a.2.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] user provided memory for decoded data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user provided memory with the encoded value data of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_rim_cont(struct bssgp_ran_inf_rim_cont *cont, const uint8_t *buf, size_t len)</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       memset(cont, 0, sizeof(*cont));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = tlv_parse(&tp, &tvlv_att_def, buf, len, 0, 0);</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%);">+     rc = dec_rim_cont_common((struct bssgp_ran_inf_x_cont *)cont, &tp);</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, BSSGP_IE_RAN_INFO_APP_CONTAINER)) {</span><br><span style="color: hsl(120, 100%, 40%);">+         switch (cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+            case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+                       rc = bssgp_dec_ran_inf_app_cont_nacc(&cont->u.app_cont_nacc,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                        TLVP_VAL(&tp, BSSGP_IE_RAN_INFO_APP_CONTAINER),</span><br><span style="color: hsl(120, 100%, 40%);">+                                                           TLVP_LEN(&tp, BSSGP_IE_RAN_INFO_APP_CONTAINER));</span><br><span style="color: hsl(120, 100%, 40%);">+                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+               case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* TODO: add parsers for Si3, MBMS, SON, UTRA-SI app containers */</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               default:</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 (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                        return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+    } else if (TLVP_PRESENT(&tp, BSSGP_IE_APP_ERROR_CONTAINER)) {</span><br><span style="color: hsl(120, 100%, 40%);">+             switch (cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+            case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+                       rc = bssgp_dec_app_err_cont_nacc(&cont->u.app_err_cont_nacc,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                    TLVP_VAL(&tp, BSSGP_IE_APP_ERROR_CONTAINER), TLVP_LEN(&tp,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                                                          BSSGP_IE_APP_ERROR_CONTAINER));</span><br><span style="color: hsl(120, 100%, 40%);">+                        break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+               case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* TODO: add parsers for Si3, MBMS, SON, UTRA-SI app containers */</span><br><span style="color: hsl(120, 100%, 40%);">+                    return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               default:</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 (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                        return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+            cont->app_err = true;</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_PRES_LEN(&tp, BSSGP_IE_SON_TRANSFER_APP_ID, 1)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                cont->son_trans_app_id = TLVP_VAL(&tp, BSSGP_IE_SON_TRANSFER_APP_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+          cont->son_trans_app_id_len = TLVP_LEN(&tp, BSSGP_IE_SON_TRANSFER_APP_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode a RAN Information RIM Container (3GPP TS 48.018, table 11.3.62a.2.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] buf user provided memory for the generated value part of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cont user provided input data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns length of encoded octets, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_rim_cont *cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+       int app_cont_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int remaining_buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      buf_ptr = enc_rim_cont_common(buf_ptr, len, (struct bssgp_ran_inf_x_cont *)cont);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!buf_ptr)</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%);">+     remaining_buf_len = len - (int)(buf_ptr - buf);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (remaining_buf_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%);">+     if (cont->app_err) {</span><br><span style="color: hsl(120, 100%, 40%);">+               switch (cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+            case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+                       app_cont_len =</span><br><span style="color: hsl(120, 100%, 40%);">+                            bssgp_enc_app_err_cont_nacc(buf_ptr + TVLV_HDR_LEN, remaining_buf_len - TVLV_HDR_MAXLEN,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                  &cont->u.app_err_cont_nacc);</span><br><span style="color: hsl(120, 100%, 40%);">+                   break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+               case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* TODO: add encoders for Si3, MBMS, SON, UTRA-SI app containers */</span><br><span style="color: hsl(120, 100%, 40%);">+                   return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               default:</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 (app_cont_len < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                      return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               buf_ptr = dub_tlvp_header(buf_ptr, BSSGP_IE_APP_ERROR_CONTAINER, app_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+       } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              switch (cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+            case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+                       app_cont_len =</span><br><span style="color: hsl(120, 100%, 40%);">+                            bssgp_enc_ran_inf_app_cont_nacc(buf_ptr + TVLV_HDR_LEN, remaining_buf_len - TVLV_HDR_MAXLEN,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                          &cont->u.app_cont_nacc);</span><br><span style="color: hsl(120, 100%, 40%);">+                   break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+               case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+                    /* TODO: add encoders for Si3, MBMS, SON, UTRA-SI app containers */</span><br><span style="color: hsl(120, 100%, 40%);">+                   return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               default:</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 (app_cont_len < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                      return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               buf_ptr = dub_tlvp_header(buf_ptr, BSSGP_IE_RAN_INFO_APP_CONTAINER, app_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   remaining_buf_len = len - (int)(buf_ptr - buf);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (remaining_buf_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%);">+     if (cont->son_trans_app_id && cont->son_trans_app_id_len > 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              if (remaining_buf_len < cont->son_trans_app_id_len + TVLV_HDR_MAXLEN)</span><br><span style="color: hsl(120, 100%, 40%);">+                   return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+               buf_ptr =</span><br><span style="color: hsl(120, 100%, 40%);">+                 tvlv_put(buf_ptr, BSSGP_IE_SON_TRANSFER_APP_ID, cont->son_trans_app_id_len, cont->son_trans_app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+        }</span><br><span style="color: hsl(120, 100%, 40%);">+     return (int)(buf_ptr - buf);</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 a RAN Information ACK RIM Container (3GPP TS 48.018, table 11.3.62a.3.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] user provided memory for decoded data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user provided memory with the encoded value data of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_ack_rim_cont(struct bssgp_ran_inf_ack_rim_cont *cont, const uint8_t *buf, size_t len)</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       memset(cont, 0, sizeof(*cont));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = tlv_parse(&tp, &tvlv_att_def, buf, len, 0, 0);</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_PRES_LEN(&tp, BSSGP_IE_RIM_APP_IDENTITY, sizeof(uint8_t)))</span><br><span style="color: hsl(120, 100%, 40%);">+               cont->app_id = TLVP_VAL(&tp, BSSGP_IE_RIM_APP_IDENTITY)[0];</span><br><span style="color: hsl(120, 100%, 40%);">+    else</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_PRES_LEN(&tp, BSSGP_IE_RIM_SEQ_NR, sizeof(cont->seq_num)))</span><br><span style="color: hsl(120, 100%, 40%);">+            cont->seq_num = tlvp_val32be(&tp, BSSGP_IE_RIM_SEQ_NR);</span><br><span style="color: hsl(120, 100%, 40%);">+        else</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_PRES_LEN(&tp, BSSGP_IE_RIM_PROTOCOL_VERSION, sizeof(cont->prot_ver)))</span><br><span style="color: hsl(120, 100%, 40%);">+         cont->prot_ver = TLVP_VAL(&tp, BSSGP_IE_RIM_PROTOCOL_VERSION)[0];</span><br><span style="color: hsl(120, 100%, 40%);">+      else</span><br><span style="color: hsl(120, 100%, 40%);">+          cont->prot_ver = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (TLVP_PRES_LEN(&tp, BSSGP_IE_SON_TRANSFER_APP_ID, 1)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                cont->son_trans_app_id = TLVP_VAL(&tp, BSSGP_IE_SON_TRANSFER_APP_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+          cont->son_trans_app_id_len = TLVP_LEN(&tp, BSSGP_IE_SON_TRANSFER_APP_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode a RAN Information ACK RIM Container (3GPP TS 48.018, table 11.3.62a.3.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] buf user provided memory for the generated value part of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cont user provided input data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns length of encoded octets, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_ack_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_ack_rim_cont *cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint32_t seq_num = osmo_htonl(cont->seq_num);</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t app_id_temp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (len <</span><br><span style="color: hsl(120, 100%, 40%);">+      4 * TVLV_HDR_MAXLEN + sizeof(app_id_temp) + sizeof(seq_num) + sizeof(cont->prot_ver) +</span><br><span style="color: hsl(120, 100%, 40%);">+     cont->son_trans_app_id_len)</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%);">+     app_id_temp = cont->app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+        buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_APP_IDENTITY, sizeof(app_id_temp), &app_id_temp);</span><br><span style="color: hsl(120, 100%, 40%);">+        buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_SEQ_NR, sizeof(seq_num), (uint8_t *) & seq_num);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (cont->prot_ver > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_PROTOCOL_VERSION, sizeof(cont->prot_ver), &cont->prot_ver);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (cont->son_trans_app_id && cont->son_trans_app_id_len > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                buf_ptr =</span><br><span style="color: hsl(120, 100%, 40%);">+                 tvlv_put(buf_ptr, BSSGP_IE_SON_TRANSFER_APP_ID, cont->son_trans_app_id_len, cont->son_trans_app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return (int)(buf_ptr - buf);</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 a RAN Information Error RIM Container (3GPP TS 48.018, table 11.3.62a.4.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] user provided memory for decoded data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user provided memory with the encoded value data of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_dec_ran_inf_err_rim_cont(struct bssgp_ran_inf_err_rim_cont *cont, const uint8_t *buf, size_t len)</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       memset(cont, 0, sizeof(*cont));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = tlv_parse(&tp, &tvlv_att_def, buf, len, 0, 0);</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_PRES_LEN(&tp, BSSGP_IE_RIM_APP_IDENTITY, sizeof(uint8_t)))</span><br><span style="color: hsl(120, 100%, 40%);">+               cont->app_id = TLVP_VAL(&tp, BSSGP_IE_RIM_APP_IDENTITY)[0];</span><br><span style="color: hsl(120, 100%, 40%);">+    else</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_PRES_LEN(&tp, BSSGP_IE_CAUSE, sizeof(cont->cause)))</span><br><span style="color: hsl(120, 100%, 40%);">+           cont->cause = TLVP_VAL(&tp, BSSGP_IE_CAUSE)[0];</span><br><span style="color: hsl(120, 100%, 40%);">+        else</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_PRES_LEN(&tp, BSSGP_IE_RIM_PROTOCOL_VERSION, sizeof(cont->prot_ver)))</span><br><span style="color: hsl(120, 100%, 40%);">+         cont->prot_ver = TLVP_VAL(&tp, BSSGP_IE_RIM_PROTOCOL_VERSION)[0];</span><br><span style="color: hsl(120, 100%, 40%);">+      else</span><br><span style="color: hsl(120, 100%, 40%);">+          cont->prot_ver = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (TLVP_PRESENT(&tp, BSSGP_IE_PDU_IN_ERROR)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           cont->err_pdu = TLVP_VAL(&tp, BSSGP_IE_PDU_IN_ERROR);</span><br><span style="color: hsl(120, 100%, 40%);">+          cont->err_pdu_len = TLVP_LEN(&tp, BSSGP_IE_PDU_IN_ERROR);</span><br><span style="color: hsl(120, 100%, 40%);">+      } else {</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_PRES_LEN(&tp, BSSGP_IE_SON_TRANSFER_APP_ID, 1)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                cont->son_trans_app_id = TLVP_VAL(&tp, BSSGP_IE_SON_TRANSFER_APP_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+          cont->son_trans_app_id_len = TLVP_LEN(&tp, BSSGP_IE_SON_TRANSFER_APP_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+      }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! Encode a RAN Information Error RIM Container (3GPP TS 48.018, table 11.3.62a.4.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] buf user provided memory for the generated value part of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cont user provided input data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns length of encoded octets, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+int bssgp_enc_ran_inf_err_rim_cont(uint8_t *buf, size_t len, const struct bssgp_ran_inf_err_rim_cont *cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t app_id_temp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (len <</span><br><span style="color: hsl(120, 100%, 40%);">+      TVLV_HDR_MAXLEN * 5 + sizeof(app_id_temp) + sizeof(cont->cause) + sizeof(cont->prot_ver) +</span><br><span style="color: hsl(120, 100%, 40%);">+      cont->err_pdu_len + cont->son_trans_app_id_len)</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%);">+     app_id_temp = cont->app_id;</span><br><span style="color: hsl(120, 100%, 40%);">+        buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_APP_IDENTITY, sizeof(app_id_temp), &app_id_temp);</span><br><span style="color: hsl(120, 100%, 40%);">+        buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_CAUSE, sizeof(cont->cause), &cont->cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (cont->prot_ver > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_RIM_PROTOCOL_VERSION, sizeof(cont->prot_ver), &cont->prot_ver);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (cont->err_pdu && cont->err_pdu_len > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          buf_ptr = tvlv_put(buf_ptr, BSSGP_IE_PDU_IN_ERROR, cont->err_pdu_len, cont->err_pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+   else</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 (cont->son_trans_app_id && cont->son_trans_app_id_len > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                buf_ptr =</span><br><span style="color: hsl(120, 100%, 40%);">+                 tvlv_put(buf_ptr, BSSGP_IE_SON_TRANSFER_APP_ID, cont->son_trans_app_id_len, cont->son_trans_app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      return (int)(buf_ptr - buf);</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 a RAN Information Application Error RIM Container (3GPP TS 48.018, table 11.3.62a.5.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] user provided memory for decoded data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] buf user provided memory with the encoded value data of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns 0 on success, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+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 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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       memset(cont, 0, sizeof(*cont));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = tlv_parse(&tp, &tvlv_att_def, buf, len, 0, 0);</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%);">+     rc = dec_rim_cont_common((struct bssgp_ran_inf_x_cont *)cont, &tp);</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%);">+     switch (cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+               rc = bssgp_dec_app_err_cont_nacc(&cont->u.app_err_cont_nacc,</span><br><span style="color: hsl(120, 100%, 40%);">+                                            TLVP_VAL(&tp, BSSGP_IE_APP_ERROR_CONTAINER), TLVP_LEN(&tp,</span><br><span style="color: hsl(120, 100%, 40%);">+                                                                                                  BSSGP_IE_APP_ERROR_CONTAINER));</span><br><span style="color: hsl(120, 100%, 40%);">+                break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+       case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+            /* TODO: add parsers for Si3, MBMS, SON, UTRA-SI app containers */</span><br><span style="color: hsl(120, 100%, 40%);">+            return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       default:</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 (rc < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  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 RAN Information Application Error RIM Container (3GPP TS 48.018, table 11.3.62a.5.b).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[out] buf user provided memory for the generated value part of the IE.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \param[in] cont user provided input data struct.</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \returns length of encoded octets, -EINVAL on error. */</span><br><span style="color: hsl(120, 100%, 40%);">+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%);">+       uint8_t *buf_ptr = buf;</span><br><span style="color: hsl(120, 100%, 40%);">+       int app_cont_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+ int remaining_buf_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      buf_ptr = enc_rim_cont_common(buf_ptr, len, (struct bssgp_ran_inf_x_cont *)cont);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!buf_ptr)</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%);">+     remaining_buf_len = len - (int)(buf_ptr - buf);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (remaining_buf_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%);">+     switch (cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+    case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+               app_cont_len =</span><br><span style="color: hsl(120, 100%, 40%);">+                    bssgp_enc_app_err_cont_nacc(buf_ptr + TVLV_HDR_LEN, remaining_buf_len - TVLV_HDR_MAXLEN,</span><br><span style="color: hsl(120, 100%, 40%);">+                                          &cont->u.app_err_cont_nacc);</span><br><span style="color: hsl(120, 100%, 40%);">+           break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+       case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+            /* TODO: add encoders for Si3, MBMS, SON, UTRA-SI app containers */</span><br><span style="color: hsl(120, 100%, 40%);">+           return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       default:</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 (app_cont_len < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       buf_ptr = dub_tlvp_header(buf_ptr, BSSGP_IE_APP_ERROR_CONTAINER, app_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return (int)(buf_ptr - buf);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/src/gb/libosmogb.map b/src/gb/libosmogb.map</span><br><span>index 5c029b0..b012184 100644</span><br><span>--- a/src/gb/libosmogb.map</span><br><span>+++ b/src/gb/libosmogb.map</span><br><span>@@ -3,7 +3,23 @@</span><br><span> bssgp_cause_str;</span><br><span> bssgp_create_cell_id;</span><br><span> bssgp_create_rim_ri;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_dec_app_err_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_dec_ran_inf_ack_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_dec_ran_inf_err_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_dec_ran_inf_req_app_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_dec_ran_inf_req_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_dec_ran_inf_app_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_dec_ran_inf_app_err_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_dec_ran_inf_rim_cont;</span><br><span> bssgp_pdu_str;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_enc_app_err_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_enc_ran_inf_ack_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_enc_ran_inf_err_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_enc_ran_inf_req_app_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_enc_ran_inf_req_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_enc_ran_inf_app_cont_nacc;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_enc_ran_inf_app_err_rim_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_enc_ran_inf_rim_cont;</span><br><span> bssgp_fc_in;</span><br><span> bssgp_fc_init;</span><br><span> bssgp_fc_ms_init;</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index e0220bd..10306aa 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -75,7 +75,7 @@</span><br><span> endif</span><br><span> </span><br><span> if ENABLE_GB</span><br><span style="color: hsl(0, 100%, 40%);">-check_PROGRAMS += gb/bssgp_fc_test gb/gprs_bssgp_test gb/gprs_ns_test gb/gprs_ns2_test fr/fr_test</span><br><span style="color: hsl(120, 100%, 40%);">+check_PROGRAMS += gb/bssgp_fc_test gb/gprs_bssgp_test gb/gprs_bssgp_rim_test gb/gprs_ns_test gb/gprs_ns2_test fr/fr_test</span><br><span> endif</span><br><span> </span><br><span> utils_utils_test_SOURCES = utils/utils_test.c</span><br><span>@@ -176,6 +176,10 @@</span><br><span>                           $(top_builddir)/src/gsm/libosmogsm.la \</span><br><span>                      $(top_builddir)/src/gb/libosmogb.la</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+gb_gprs_bssgp_rim_test_SOURCES = gb/gprs_bssgp_rim_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+gb_gprs_bssgp_rim_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DLSYM) \</span><br><span style="color: hsl(120, 100%, 40%);">+                        $(top_builddir)/src/gb/libosmogb.la</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> gb_gprs_ns_test_SOURCES = gb/gprs_ns_test.c</span><br><span> gb_gprs_ns_test_LDADD = $(LDADD) $(top_builddir)/src/gb/libosmogb.la $(LIBRARY_DLSYM) \</span><br><span>                       $(top_builddir)/src/vty/libosmovty.la \</span><br><span>@@ -334,6 +338,7 @@</span><br><span>              gsm0808/gsm0808_test.ok gb/bssgp_fc_tests.err             \</span><br><span>              gb/bssgp_fc_tests.ok gb/bssgp_fc_tests.sh                     \</span><br><span>              gb/gprs_bssgp_test.ok gb/gprs_ns_test.ok gea/gea_test.ok      \</span><br><span style="color: hsl(120, 100%, 40%);">+          gb/gprs_bssgp_rim_test.ok                                  \</span><br><span>              gb/gprs_ns2_vty.vty gb/osmoappdesc.py gb/osmo-ns-dummy.cfg \</span><br><span>              gb/gprs_ns2_test.ok                                      \</span><br><span>              gprs/gprs_test.ok kasumi/kasumi_test.ok                       \</span><br><span>diff --git a/tests/gb/gprs_bssgp_rim_test.c b/tests/gb/gprs_bssgp_rim_test.c</span><br><span>new file mode 100644</span><br><span>index 0000000..8c6a00d</span><br><span>--- /dev/null</span><br><span>+++ b/tests/gb/gprs_bssgp_rim_test.c</span><br><span>@@ -0,0 +1,664 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* Test routines for the BSSGP implementation in libosmogb</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2020 by sysmocom - s.f.m.c. GmbH</span><br><span style="color: hsl(120, 100%, 40%);">+ * Author: Philipp Maier <pmaier@sysmocom.de></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Skeleton based on bssgp_fc_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+ * (C) 2012 by Harald Welte <laforge@gnumonks.org></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * SPDX-License-Identifier: GPL-2.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%);">+#undef _GNU_SOURCE</span><br><span style="color: hsl(120, 100%, 40%);">+#define _GNU_SOURCE</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/application.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/utils.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_bssgp.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_ns.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gprs/gprs_bssgp_rim.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdlib.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <string.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <unistd.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void dump_bssgp_ran_inf_req_app_cont_nacc(struct bssgp_ran_inf_req_app_cont_nacc *app_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" app_cont: bssgp_ran_inf_req_app_cont_nacc:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("  reprt_cell.rai.lac.plmn.mcc = %u\n", app_cont->reprt_cell.rai.lac.plmn.mcc);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("  reprt_cell.rai.lac.plmn.mnc = %u\n", app_cont->reprt_cell.rai.lac.plmn.mnc);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("  reprt_cell.rai.lac.plmn.mnc_3_digits = %u\n", app_cont->reprt_cell.rai.lac.plmn.mnc_3_digits);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("  reprt_cell.rai.lac.lac = %u\n", app_cont->reprt_cell.rai.lac.lac);</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("  reprt_cell.rai.rac = %u\n", app_cont->reprt_cell.rai.rac);</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("  reprt_cell.cell_identity = %04x\n", app_cont->reprt_cell.cell_identity);</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%);">+void dump_bssgp_ran_inf_req_rim_cont(struct bssgp_ran_inf_req_rim_cont *rim_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("bssgp_ran_inf_req_rim_cont:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" app_id = %02x\n", rim_cont->app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" seq_num = %08x\n", rim_cont->seq_num);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" pdu_ind.ack_requested = %u\n", rim_cont->pdu_ind.ack_requested);</span><br><span style="color: hsl(120, 100%, 40%);">+        printf(" pdu_ind.pdu_type_ext = %u\n", rim_cont->pdu_ind.pdu_type_ext);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" prot_ver = %u\n", rim_cont->prot_ver);</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (rim_cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+               dump_bssgp_ran_inf_req_app_cont_nacc(&rim_cont->u.app_cont_nacc);</span><br><span style="color: hsl(120, 100%, 40%);">+              break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+       case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+            printf(" app_cont: (not implemented yet)\n");</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%);">+              printf(" app_cont: (illegal application identifier)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rim_cont->son_trans_app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printf(" son_trans_app_id: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  osmo_hexdump_nospc(rim_cont->son_trans_app_id, rim_cont->son_trans_app_id_len));</span><br><span style="color: hsl(120, 100%, 40%);">+         printf(" son_trans_app_id_len: %lu\n", rim_cont->son_trans_app_id_len);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_dec_ran_inf_req_rim_cont_nacc()</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 bssgp_ran_inf_req_rim_cont rim_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t testvec[] =</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x01, 0x4f, 0x81, 0x02, 0x55, 0x81, 0x01, 0x4d, 0x88,</span><br><span style="color: hsl(120, 100%, 40%);">+    0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_ran_inf_req_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_ran_inf_req_rim_cont(&rim_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_ran_inf_req_rim_cont_nacc()</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 bssgp_ran_inf_req_rim_cont rim_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;</span><br><span style="color: hsl(120, 100%, 40%);">+  rim_cont.seq_num = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont.pdu_ind.ack_requested = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   rim_cont.pdu_ind.pdu_type_ext = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.prot_ver = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.son_trans_app_id = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.son_trans_app_id_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mcc = 262;</span><br><span style="color: hsl(120, 100%, 40%);">+   rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mnc = 42;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mnc_3_digits = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.lac = 13200;</span><br><span style="color: hsl(120, 100%, 40%);">+      rim_cont.u.app_cont_nacc.reprt_cell.rai.rac = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      rim_cont.u.app_cont_nacc.reprt_cell.cell_identity = 0x51e1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ dump_bssgp_ran_inf_req_rim_cont(&rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_enc_ran_inf_req_rim_cont(result, sizeof(result), &rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void dump_bssgp_ran_inf_app_cont_nacc(struct bssgp_ran_inf_app_cont_nacc *app_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     unsigned int i;</span><br><span style="color: hsl(120, 100%, 40%);">+       unsigned int silen;</span><br><span style="color: hsl(120, 100%, 40%);">+   printf(" app_cont: bssgp_ran_inf_app_cont_nacc:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("  reprt_cell.rai.lac.plmn.mcc = %u\n", app_cont->reprt_cell.rai.lac.plmn.mcc);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("  reprt_cell.rai.lac.plmn.mnc = %u\n", app_cont->reprt_cell.rai.lac.plmn.mnc);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("  reprt_cell.rai.lac.plmn.mnc_3_digits = %u\n", app_cont->reprt_cell.rai.lac.plmn.mnc_3_digits);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("  reprt_cell.rai.lac.lac = %u\n", app_cont->reprt_cell.rai.lac.lac);</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("  reprt_cell.rai.rac = %u\n", app_cont->reprt_cell.rai.rac);</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("  reprt_cell.cell_identity = %04x\n", app_cont->reprt_cell.cell_identity);</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("  type_psi = %u\n", app_cont->type_psi);</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("  num_si = %u\n", app_cont->num_si);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (app_cont->type_psi)</span><br><span style="color: hsl(120, 100%, 40%);">+            silen = 22;</span><br><span style="color: hsl(120, 100%, 40%);">+   else</span><br><span style="color: hsl(120, 100%, 40%);">+          silen = 21;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ for (i = 0; i < app_cont->num_si; i++)</span><br><span style="color: hsl(120, 100%, 40%);">+          printf(" si[%u] = %s\n", i, osmo_hexdump_nospc(app_cont->si[i], silen));</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void dump_bssgp_app_err_cont_nacc(struct bssgp_app_err_cont_nacc *app_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     printf(" app_err_cont: bssgp_app_err_cont_nacc:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("  macc_cause = %02x\n", app_cont->nacc_cause);</span><br><span style="color: hsl(120, 100%, 40%);">+   if (app_cont->err_app_cont) {</span><br><span style="color: hsl(120, 100%, 40%);">+              printf("  err_app_cont: %s\n", osmo_hexdump_nospc(app_cont->err_app_cont, app_cont->err_app_cont_len));</span><br><span style="color: hsl(120, 100%, 40%);">+               printf("  err_app_cont_len: %lu\n", app_cont->err_app_cont_len);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void dump_bssgp_ran_inf_rim_cont(struct bssgp_ran_inf_rim_cont *rim_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("bssgp_ran_inf_rim_cont:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        printf(" app_id = %02x\n", rim_cont->app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" seq_num = %08x\n", rim_cont->seq_num);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" pdu_ind.ack_requested = %u\n", rim_cont->pdu_ind.ack_requested);</span><br><span style="color: hsl(120, 100%, 40%);">+        printf(" pdu_ind.pdu_type_ext = %u\n", rim_cont->pdu_ind.pdu_type_ext);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" prot_ver = %u\n", rim_cont->prot_ver);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" app_err = %u\n", rim_cont->app_err);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (rim_cont->app_err) {</span><br><span style="color: hsl(120, 100%, 40%);">+           switch (rim_cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+                       dump_bssgp_app_err_cont_nacc(&rim_cont->u.app_err_cont_nacc);</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+               case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf(" app_err_cont: (not implemented yet)\n");</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%);">+                      printf(" app_err_cont: (illegal application identifier)\n");</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%);">+              switch (rim_cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+                       dump_bssgp_ran_inf_app_cont_nacc(&rim_cont->u.app_cont_nacc);</span><br><span style="color: hsl(120, 100%, 40%);">+                  break;</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+               case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+                case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+                    printf(" app_cont: (not implemented yet)\n");</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%);">+                      printf(" app_cont: (illegal application identifier)\n");</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 (rim_cont->son_trans_app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printf(" son_trans_app_id: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  osmo_hexdump_nospc(rim_cont->son_trans_app_id, rim_cont->son_trans_app_id_len));</span><br><span style="color: hsl(120, 100%, 40%);">+         printf(" son_trans_app_id_len: %lu\n", rim_cont->son_trans_app_id_len);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_dec_ran_inf_rim_cont_nacc()</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 bssgp_ran_inf_rim_cont rim_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t testvec[] =</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x02, 0x4f, 0x81, 0x02, 0x55, 0x81, 0x01, 0x4e, 0xc8,</span><br><span style="color: hsl(120, 100%, 40%);">+           0x62, 0xf2, 0x24, 0x33, 0x4f, 0x00, 0x51, 0xe0, 0x06, 0x19, 0x8f, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+             0x00, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+               0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x2b, 0x1b, 0x75, 0x30, 0x00, 0xf1, 0x10,</span><br><span style="color: hsl(120, 100%, 40%);">+             0x23, 0x6e,</span><br><span style="color: hsl(120, 100%, 40%);">+               0xc9, 0x03, 0x3c, 0x27, 0x47, 0x40, 0x79, 0x00, 0x00, 0x3c, 0x0b, 0x2b, 0x2b, 0x00, 0x90, 0x00, 0x18,</span><br><span style="color: hsl(120, 100%, 40%);">+             0x5a, 0x6f,</span><br><span style="color: hsl(120, 100%, 40%);">+               0xc9, 0xe0, 0x84, 0x10, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b</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("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_ran_inf_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_ran_inf_rim_cont(&rim_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_dec_ran_inf_rim_cont_err_nacc()</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 bssgp_ran_inf_rim_cont rim_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t testvec[] =</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x01, 0x4f, 0x81, 0x02, 0x55, 0x81, 0x01, 0x56, 0x86,</span><br><span style="color: hsl(120, 100%, 40%);">+    0x01, 0xaa, 0xbb, 0xcc, 0xdd, 0xee };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_ran_inf_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_ran_inf_rim_cont(&rim_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_ran_inf_rim_cont_nacc()</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 bssgp_ran_inf_rim_cont rim_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t si1[] =</span><br><span style="color: hsl(120, 100%, 40%);">+           { 0x19, 0x8f, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+           0x79, 0x00, 0x00, 0x2b</span><br><span style="color: hsl(120, 100%, 40%);">+        };</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t si3[] =</span><br><span style="color: hsl(120, 100%, 40%);">+           { 0x1b, 0x75, 0x30, 0x00, 0xf1, 0x10, 0x23, 0x6e, 0xc9, 0x03, 0x3c, 0x27, 0x47, 0x40, 0x79, 0x00, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+           0x3c, 0x0b, 0x2b, 0x2b</span><br><span style="color: hsl(120, 100%, 40%);">+        };</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t si13[] =</span><br><span style="color: hsl(120, 100%, 40%);">+          { 0x00, 0x90, 0x00, 0x18, 0x5a, 0x6f, 0xc9, 0xe0, 0x84, 0x10, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,</span><br><span style="color: hsl(120, 100%, 40%);">+           0x2b, 0x2b, 0x2b, 0x2b</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%);">+  uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;</span><br><span style="color: hsl(120, 100%, 40%);">+  rim_cont.seq_num = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont.pdu_ind.ack_requested = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   rim_cont.pdu_ind.pdu_type_ext = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.prot_ver = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.son_trans_app_id = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.son_trans_app_id_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.app_err = false;</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mcc = 262;</span><br><span style="color: hsl(120, 100%, 40%);">+   rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mnc = 42;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.plmn.mnc_3_digits = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.u.app_cont_nacc.reprt_cell.rai.lac.lac = 13135;</span><br><span style="color: hsl(120, 100%, 40%);">+      rim_cont.u.app_cont_nacc.reprt_cell.rai.rac = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      rim_cont.u.app_cont_nacc.reprt_cell.cell_identity = 0x51e0;</span><br><span style="color: hsl(120, 100%, 40%);">+   rim_cont.u.app_cont_nacc.type_psi = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.u.app_cont_nacc.num_si = 3;</span><br><span style="color: hsl(120, 100%, 40%);">+  rim_cont.u.app_cont_nacc.si[0] = si1;</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont.u.app_cont_nacc.si[1] = si3;</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont.u.app_cont_nacc.si[2] = si13;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      dump_bssgp_ran_inf_rim_cont(&rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_enc_ran_inf_rim_cont(result, sizeof(result), &rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_ran_inf_rim_cont_err_nacc()</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 bssgp_ran_inf_rim_cont rim_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t err_app_cont[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;</span><br><span style="color: hsl(120, 100%, 40%);">+  rim_cont.seq_num = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont.pdu_ind.ack_requested = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   rim_cont.pdu_ind.pdu_type_ext = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.prot_ver = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.son_trans_app_id = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.son_trans_app_id_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.app_err = true;</span><br><span style="color: hsl(120, 100%, 40%);">+      rim_cont.u.app_err_cont_nacc.nacc_cause = BSSGP_NACC_CAUSE_SYNTAX_ERR;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.u.app_err_cont_nacc.err_app_cont = err_app_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.u.app_err_cont_nacc.err_app_cont_len = sizeof(err_app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ dump_bssgp_ran_inf_rim_cont(&rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_enc_ran_inf_rim_cont(result, sizeof(result), &rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void dump_bssgp_ran_inf_ack_rim_cont(struct bssgp_ran_inf_ack_rim_cont *rim_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("bssgp_ran_inf_ack_rim_cont:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" app_id = %02x\n", rim_cont->app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" seq_num = %08x\n", rim_cont->seq_num);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" prot_ver = %u\n", rim_cont->prot_ver);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rim_cont->son_trans_app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printf(" son_trans_app_id: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  osmo_hexdump_nospc(rim_cont->son_trans_app_id, rim_cont->son_trans_app_id_len));</span><br><span style="color: hsl(120, 100%, 40%);">+         printf(" son_trans_app_id_len: %lu\n", rim_cont->son_trans_app_id_len);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_dec_ran_inf_ack_rim_cont()</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 bssgp_ran_inf_ack_rim_cont rim_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t testvec[] = { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x01, 0x55, 0x81, 0x01 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_ran_inf_ack_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_ran_inf_ack_rim_cont(&rim_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_ran_inf_ack_rim_cont()</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 bssgp_ran_inf_ack_rim_cont rim_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;</span><br><span style="color: hsl(120, 100%, 40%);">+  rim_cont.seq_num = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont.prot_ver = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.son_trans_app_id = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.son_trans_app_id_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    dump_bssgp_ran_inf_ack_rim_cont(&rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_enc_ran_inf_ack_rim_cont(result, sizeof(result), &rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</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%);">+void dump_bssgp_ran_inf_err_rim_cont(struct bssgp_ran_inf_err_rim_cont *rim_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("bssgp_ran_inf_err_rim_cont:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" app_id = %02x\n", rim_cont->app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" cause = %02x\n", rim_cont->cause);</span><br><span style="color: hsl(120, 100%, 40%);">+      printf(" prot_ver = %u\n", rim_cont->prot_ver);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (rim_cont->err_pdu) {</span><br><span style="color: hsl(120, 100%, 40%);">+           printf(" err_pdu: %s\n", osmo_hexdump_nospc(rim_cont->err_pdu, rim_cont->err_pdu_len));</span><br><span style="color: hsl(120, 100%, 40%);">+               printf(" err_pdu_len: %lu\n", rim_cont->err_pdu_len);</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rim_cont->son_trans_app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+          printf(" son_trans_app_id: %s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                  osmo_hexdump_nospc(rim_cont->son_trans_app_id, rim_cont->son_trans_app_id_len));</span><br><span style="color: hsl(120, 100%, 40%);">+         printf(" son_trans_app_id_len: %lu\n", rim_cont->son_trans_app_id_len);</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_dec_ran_inf_err_rim_cont()</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 bssgp_ran_inf_err_rim_cont rim_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t testvec[] =</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0x4b, 0x81, 0x17, 0x07, 0x81, 0x2b, 0x55, 0x81, 0x01, 0x15, 0x85, 0xaa, 0xbb, 0xcc, 0xdd, 0xee };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_ran_inf_err_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_ran_inf_err_rim_cont(&rim_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_ran_inf_err_rim_cont()</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 bssgp_ran_inf_err_rim_cont rim_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t err_pdu[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee };</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.app_id = 23;</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont.cause = 0x2b;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.prot_ver = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.err_pdu = err_pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+   rim_cont.err_pdu_len = sizeof(err_pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+       rim_cont.son_trans_app_id = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.son_trans_app_id_len = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    dump_bssgp_ran_inf_err_rim_cont(&rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_enc_ran_inf_err_rim_cont(result, sizeof(result), &rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+   printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</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%);">+void dump_bssgp_ran_inf_app_err_rim_cont(struct bssgp_ran_inf_app_err_rim_cont *rim_cont)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("bssgp_ran_inf_app_err_rim_cont:\n");</span><br><span style="color: hsl(120, 100%, 40%);">+        printf(" app_id = %02x\n", rim_cont->app_id);</span><br><span style="color: hsl(120, 100%, 40%);">+    printf(" seq_num = %08x\n", rim_cont->seq_num);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" pdu_ind.ack_requested = %u\n", rim_cont->pdu_ind.ack_requested);</span><br><span style="color: hsl(120, 100%, 40%);">+        printf(" pdu_ind.pdu_type_ext = %u\n", rim_cont->pdu_ind.pdu_type_ext);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf(" prot_ver = %u\n", rim_cont->prot_ver);</span><br><span style="color: hsl(120, 100%, 40%);">+  switch (rim_cont->app_id) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_NACC:</span><br><span style="color: hsl(120, 100%, 40%);">+               dump_bssgp_app_err_cont_nacc(&rim_cont->u.app_err_cont_nacc);</span><br><span style="color: hsl(120, 100%, 40%);">+          break;</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_SI3:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_MBMS:</span><br><span style="color: hsl(120, 100%, 40%);">+       case BSSGP_RAN_INF_APP_ID_SON:</span><br><span style="color: hsl(120, 100%, 40%);">+        case BSSGP_RAN_INF_APP_ID_UTRA_SI:</span><br><span style="color: hsl(120, 100%, 40%);">+            printf(" app_err_cont: (not implemented yet)\n");</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%);">+              printf(" app_err_cont: (illegal application identifier)\n");</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%);">+static void test_bssgp_dec_ran_inf_app_err_rim_cont_nacc()</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 bssgp_ran_inf_app_err_rim_cont rim_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+   uint8_t testvec[] =</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0x4b, 0x81, 0x01, 0x4c, 0x84, 0x00, 0x00, 0x00, 0x01, 0x4f, 0x81, 0x02, 0x55, 0x81, 0x01, 0x56, 0x85,</span><br><span style="color: hsl(120, 100%, 40%);">+           0xaa, 0xbb, 0xcc, 0xdd, 0xee</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("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_ran_inf_app_err_rim_cont(&rim_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_ran_inf_app_err_rim_cont(&rim_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_ran_inf_app_err_rim_cont_nacc()</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 bssgp_ran_inf_app_err_rim_cont rim_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t err_app_cont[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee };</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+       rim_cont.app_id = BSSGP_RAN_INF_APP_ID_NACC;</span><br><span style="color: hsl(120, 100%, 40%);">+  rim_cont.seq_num = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+ rim_cont.pdu_ind.ack_requested = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+   rim_cont.pdu_ind.pdu_type_ext = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+    rim_cont.prot_ver = 1;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.u.app_err_cont_nacc.nacc_cause = BSSGP_NACC_CAUSE_SYNTAX_ERR;</span><br><span style="color: hsl(120, 100%, 40%);">+        rim_cont.u.app_err_cont_nacc.err_app_cont = err_app_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+     rim_cont.u.app_err_cont_nacc.err_app_cont_len = sizeof(err_app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+ dump_bssgp_ran_inf_app_err_rim_cont(&rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = bssgp_enc_ran_inf_app_err_rim_cont(result, sizeof(result), &rim_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_dec_ran_inf_req_app_cont_nacc()</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 bssgp_ran_inf_req_app_cont_nacc app_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t testvec[] = { 0x62, 0xf2, 0x24, 0x33, 0x90, 0x00, 0x51, 0xe1 };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_ran_inf_req_app_cont_nacc(&app_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_ran_inf_req_app_cont_nacc(&app_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_ran_inf_req_app_cont_nacc()</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 bssgp_ran_inf_req_app_cont_nacc app_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     app_cont.reprt_cell.rai.lac.plmn.mcc = 262;</span><br><span style="color: hsl(120, 100%, 40%);">+   app_cont.reprt_cell.rai.lac.plmn.mnc = 42;</span><br><span style="color: hsl(120, 100%, 40%);">+    app_cont.reprt_cell.rai.lac.plmn.mnc_3_digits = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    app_cont.reprt_cell.rai.lac.lac = 13200;</span><br><span style="color: hsl(120, 100%, 40%);">+      app_cont.reprt_cell.rai.rac = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      app_cont.reprt_cell.cell_identity = 0x51e1;</span><br><span style="color: hsl(120, 100%, 40%);">+   dump_bssgp_ran_inf_req_app_cont_nacc(&app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bssgp_enc_ran_inf_req_app_cont_nacc(result, sizeof(result), &app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_dec_ran_inf_app_cont_nacc()</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 bssgp_ran_inf_app_cont_nacc app_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+      uint8_t testvec[] =</span><br><span style="color: hsl(120, 100%, 40%);">+       { 0x62, 0xf2, 0x24, 0x33, 0x4f, 0x00, 0x51, 0xe0, 0x06, 0x19, 0x8f, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+    0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x00, 0x00, 0x2b, 0x1b, 0x75, 0x30, 0x00, 0xf1, 0x10,</span><br><span style="color: hsl(120, 100%, 40%);">+    0x23, 0x6e, 0xc9, 0x03, 0x3c, 0x27, 0x47, 0x40, 0x79, 0x00, 0x00, 0x3c, 0x0b, 0x2b, 0x2b, 0x00, 0x90, 0x00, 0x18,</span><br><span style="color: hsl(120, 100%, 40%);">+    0x5a, 0x6f, 0xc9, 0xe0, 0x84, 0x10, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_ran_inf_app_cont_nacc(&app_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_ran_inf_app_cont_nacc(&app_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_ran_inf_app_cont_nacc()</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 bssgp_ran_inf_app_cont_nacc app_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t si1[] =</span><br><span style="color: hsl(120, 100%, 40%);">+           { 0x19, 0x8f, 0xb1, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+   0x79, 0x00, 0x00, 0x2b };</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t si3[] =</span><br><span style="color: hsl(120, 100%, 40%);">+           { 0x1b, 0x75, 0x30, 0x00, 0xf1, 0x10, 0x23, 0x6e, 0xc9, 0x03, 0x3c, 0x27, 0x47, 0x40, 0x79, 0x00, 0x00,</span><br><span style="color: hsl(120, 100%, 40%);">+   0x3c, 0x0b, 0x2b, 0x2b };</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t si13[] =</span><br><span style="color: hsl(120, 100%, 40%);">+          { 0x00, 0x90, 0x00, 0x18, 0x5a, 0x6f, 0xc9, 0xe0, 0x84, 0x10, 0xab, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b, 0x2b,</span><br><span style="color: hsl(120, 100%, 40%);">+       0x2b, 0x2b, 0x2b, 0x2b };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     app_cont.reprt_cell.rai.lac.plmn.mcc = 262;</span><br><span style="color: hsl(120, 100%, 40%);">+   app_cont.reprt_cell.rai.lac.plmn.mnc = 42;</span><br><span style="color: hsl(120, 100%, 40%);">+    app_cont.reprt_cell.rai.lac.plmn.mnc_3_digits = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+    app_cont.reprt_cell.rai.lac.lac = 13135;</span><br><span style="color: hsl(120, 100%, 40%);">+      app_cont.reprt_cell.rai.rac = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+      app_cont.reprt_cell.cell_identity = 0x51e1;</span><br><span style="color: hsl(120, 100%, 40%);">+   app_cont.type_psi = false;</span><br><span style="color: hsl(120, 100%, 40%);">+    app_cont.num_si = 3;</span><br><span style="color: hsl(120, 100%, 40%);">+  app_cont.si[0] = si1;</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont.si[1] = si3;</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont.si[2] = si13;</span><br><span style="color: hsl(120, 100%, 40%);">+        dump_bssgp_ran_inf_app_cont_nacc(&app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    rc = bssgp_enc_ran_inf_app_cont_nacc(result, sizeof(result), &app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_dec_app_err_cont_nacc()</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 bssgp_app_err_cont_nacc app_cont_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+  uint8_t testvec[] = { 0x01, 0xaa, 0xbb, 0xcc, 0xdd, 0xee };</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     rc = bssgp_dec_app_err_cont_nacc(&app_cont_dec, testvec, sizeof(testvec));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc == 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          dump_bssgp_app_err_cont_nacc(&app_cont_dec);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("----- %s END\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void test_bssgp_enc_app_err_cont_nacc()</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 bssgp_app_err_cont_nacc app_cont = { };</span><br><span style="color: hsl(120, 100%, 40%);">+        uint8_t err_app_cont[] = { 0xaa, 0xbb, 0xcc, 0xdd, 0xee };</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t result[256];</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("----- %s START\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     app_cont.nacc_cause = BSSGP_NACC_CAUSE_SYNTAX_ERR;</span><br><span style="color: hsl(120, 100%, 40%);">+    app_cont.err_app_cont = err_app_cont;</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont.err_app_cont_len = sizeof(err_app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+     dump_bssgp_app_err_cont_nacc(&app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        rc = bssgp_enc_app_err_cont_nacc(result, sizeof(result), &app_cont);</span><br><span style="color: hsl(120, 100%, 40%);">+      printf("rc=%d, ", rc);</span><br><span style="color: hsl(120, 100%, 40%);">+      if (rc > 0)</span><br><span style="color: hsl(120, 100%, 40%);">+                printf("result=%s", osmo_hexdump_nospc(result, rc));</span><br><span style="color: hsl(120, 100%, 40%);">+        printf("\n");</span><br><span style="color: hsl(120, 100%, 40%);">+       printf("----- %s END\n", __func__);</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_prim_cb(struct osmo_prim_hdr *oph, void *ctx)</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%);">+int main(int argc, char **argv)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    printf("===== BSSGP RIM test START\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   /* RIM containers */</span><br><span style="color: hsl(120, 100%, 40%);">+  test_bssgp_dec_ran_inf_req_rim_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+   test_bssgp_enc_ran_inf_req_rim_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+   test_bssgp_dec_ran_inf_rim_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+       test_bssgp_dec_ran_inf_rim_cont_err_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+   test_bssgp_enc_ran_inf_rim_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+       test_bssgp_enc_ran_inf_rim_cont_err_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+   test_bssgp_dec_ran_inf_ack_rim_cont();</span><br><span style="color: hsl(120, 100%, 40%);">+        test_bssgp_enc_ran_inf_ack_rim_cont();</span><br><span style="color: hsl(120, 100%, 40%);">+        test_bssgp_dec_ran_inf_err_rim_cont();</span><br><span style="color: hsl(120, 100%, 40%);">+        test_bssgp_enc_ran_inf_err_rim_cont();</span><br><span style="color: hsl(120, 100%, 40%);">+        test_bssgp_dec_ran_inf_app_err_rim_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+       test_bssgp_enc_ran_inf_app_err_rim_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     /* Application containers */</span><br><span style="color: hsl(120, 100%, 40%);">+  test_bssgp_dec_ran_inf_req_app_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+   test_bssgp_enc_ran_inf_req_app_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+   test_bssgp_dec_ran_inf_app_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+       test_bssgp_enc_ran_inf_app_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+       test_bssgp_dec_app_err_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+   test_bssgp_enc_app_err_cont_nacc();</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ printf("===== BSSGP RIM test END\n\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   exit(EXIT_SUCCESS);</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/tests/gb/gprs_bssgp_rim_test.ok b/tests/gb/gprs_bssgp_rim_test.ok</span><br><span>new file mode 100644</span><br><span>index 0000000..d075ca3</span><br><span>--- /dev/null</span><br><span>+++ b/tests/gb/gprs_bssgp_rim_test.ok</span><br><span>@@ -0,0 +1,220 @@</span><br><span style="color: hsl(120, 100%, 40%);">+===== BSSGP RIM test START</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_req_rim_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0, bssgp_ran_inf_req_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.ack_requested = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.pdu_type_ext = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont: bssgp_ran_inf_req_app_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mcc = 262</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc = 42</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc_3_digits = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.lac = 13200</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.rac = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.cell_identity = 51e1</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_req_rim_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_req_rim_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_ran_inf_req_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.ack_requested = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.pdu_type_ext = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont: bssgp_ran_inf_req_app_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mcc = 262</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc = 42</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc_3_digits = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.lac = 13200</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.rac = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.cell_identity = 51e1</span><br><span style="color: hsl(120, 100%, 40%);">+rc=25, result=4b81014c84000000014f81025581014d8862f22433900051e1</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_req_rim_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_rim_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0, bssgp_ran_inf_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000002</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.ack_requested = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.pdu_type_ext = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont: bssgp_ran_inf_app_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mcc = 262</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc = 42</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc_3_digits = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.lac = 13135</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.rac = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.cell_identity = 51e0</span><br><span style="color: hsl(120, 100%, 40%);">+  type_psi = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  num_si = 3</span><br><span style="color: hsl(120, 100%, 40%);">+ si[0] = 198fb100000000000000000000000000007900002b</span><br><span style="color: hsl(120, 100%, 40%);">+ si[1] = 1b753000f110236ec9033c2747407900003c0b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+ si[2] = 009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_rim_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_rim_cont_err_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0, bssgp_ran_inf_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.ack_requested = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.pdu_type_ext = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err_cont: bssgp_app_err_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  macc_cause = 01</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont: aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont_len: 5</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_rim_cont_err_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_rim_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_ran_inf_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.ack_requested = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.pdu_type_ext = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont: bssgp_ran_inf_app_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mcc = 262</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc = 42</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc_3_digits = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.lac = 13135</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.rac = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.cell_identity = 51e0</span><br><span style="color: hsl(120, 100%, 40%);">+  type_psi = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  num_si = 3</span><br><span style="color: hsl(120, 100%, 40%);">+ si[0] = 198fb100000000000000000000000000007900002b</span><br><span style="color: hsl(120, 100%, 40%);">+ si[1] = 1b753000f110236ec9033c2747407900003c0b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+ si[2] = 009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+rc=89, result=4b81014c84000000014f81025581014ec862f224334f0051e006198fb100000000000000000000000000007900002b1b753000f110236ec9033c2747407900003c0b2b2b009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_rim_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_rim_cont_err_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_ran_inf_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.ack_requested = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.pdu_type_ext = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err_cont: bssgp_app_err_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  macc_cause = 01</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont: aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont_len: 5</span><br><span style="color: hsl(120, 100%, 40%);">+rc=23, result=4b81014c84000000014f8102558101568601aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_rim_cont_err_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_ack_rim_cont START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0, bssgp_ran_inf_ack_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_ack_rim_cont END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_ack_rim_cont START</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_ran_inf_ack_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+rc=12, result=4b81014c8400000001558101</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_ack_rim_cont END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_err_rim_cont START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0, bssgp_ran_inf_err_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 17</span><br><span style="color: hsl(120, 100%, 40%);">+ cause = 2b</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ err_pdu: aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+ err_pdu_len: 5</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_err_rim_cont END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_err_rim_cont START</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_ran_inf_err_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 17</span><br><span style="color: hsl(120, 100%, 40%);">+ cause = 2b</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ err_pdu: aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+ err_pdu_len: 5</span><br><span style="color: hsl(120, 100%, 40%);">+rc=16, result=4b811707812b5581011585aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_err_rim_cont END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_app_err_rim_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0, bssgp_ran_inf_app_err_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.ack_requested = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.pdu_type_ext = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err_cont: bssgp_app_err_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  macc_cause = aa</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont: bbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont_len: 4</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_app_err_rim_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_app_err_rim_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+bssgp_ran_inf_app_err_rim_cont:</span><br><span style="color: hsl(120, 100%, 40%);">+ app_id = 01</span><br><span style="color: hsl(120, 100%, 40%);">+ seq_num = 00000001</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.ack_requested = 0</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu_ind.pdu_type_ext = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ prot_ver = 1</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err_cont: bssgp_app_err_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  macc_cause = 01</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont: aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont_len: 5</span><br><span style="color: hsl(120, 100%, 40%);">+rc=23, result=4b81014c84000000014f8102558101568601aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_app_err_rim_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_req_app_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0,  app_cont: bssgp_ran_inf_req_app_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mcc = 262</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc = 42</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc_3_digits = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.lac = 13200</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.rac = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.cell_identity = 51e1</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_req_app_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_req_app_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont: bssgp_ran_inf_req_app_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mcc = 262</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc = 42</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc_3_digits = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.lac = 13200</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.rac = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.cell_identity = 51e1</span><br><span style="color: hsl(120, 100%, 40%);">+rc=8, result=62f22433900051e1</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_req_app_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_app_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0,  app_cont: bssgp_ran_inf_app_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mcc = 262</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc = 42</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc_3_digits = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.lac = 13135</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.rac = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.cell_identity = 51e0</span><br><span style="color: hsl(120, 100%, 40%);">+  type_psi = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  num_si = 3</span><br><span style="color: hsl(120, 100%, 40%);">+ si[0] = 198fb100000000000000000000000000007900002b</span><br><span style="color: hsl(120, 100%, 40%);">+ si[1] = 1b753000f110236ec9033c2747407900003c0b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+ si[2] = 009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_ran_inf_app_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_app_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+ app_cont: bssgp_ran_inf_app_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mcc = 262</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc = 42</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.plmn.mnc_3_digits = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.lac.lac = 13135</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.rai.rac = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  reprt_cell.cell_identity = 51e1</span><br><span style="color: hsl(120, 100%, 40%);">+  type_psi = 0</span><br><span style="color: hsl(120, 100%, 40%);">+  num_si = 3</span><br><span style="color: hsl(120, 100%, 40%);">+ si[0] = 198fb100000000000000000000000000007900002b</span><br><span style="color: hsl(120, 100%, 40%);">+ si[1] = 1b753000f110236ec9033c2747407900003c0b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+ si[2] = 009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+rc=72, result=62f224334f0051e106198fb100000000000000000000000000007900002b1b753000f110236ec9033c2747407900003c0b2b2b009000185a6fc9e08410ab2b2b2b2b2b2b2b2b2b2b</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_ran_inf_app_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_app_err_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+rc=0,  app_err_cont: bssgp_app_err_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  macc_cause = 01</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont: aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont_len: 5</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_dec_app_err_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_app_err_cont_nacc START</span><br><span style="color: hsl(120, 100%, 40%);">+ app_err_cont: bssgp_app_err_cont_nacc:</span><br><span style="color: hsl(120, 100%, 40%);">+  macc_cause = 01</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont: aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+  err_app_cont_len: 5</span><br><span style="color: hsl(120, 100%, 40%);">+rc=6, result=01aabbccddee</span><br><span style="color: hsl(120, 100%, 40%);">+----- test_bssgp_enc_app_err_cont_nacc END</span><br><span style="color: hsl(120, 100%, 40%);">+===== BSSGP RIM test END</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span>diff --git a/tests/testsuite.at b/tests/testsuite.at</span><br><span>index 75ce039..d715a3e 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -215,6 +215,12 @@</span><br><span> AT_CHECK([$abs_top_builddir/tests/gb/gprs_bssgp_test], [0], [expout], [ignore])</span><br><span> AT_CLEANUP</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+AT_SETUP([gprs-bssgp-rim])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_KEYWORDS([gprs-bssgp-rim])</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/gb/gprs_bssgp_rim_test.ok > expout</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CHECK([$abs_top_builddir/tests/gb/gprs_bssgp_rim_test], [0], [expout], [ignore])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CLEANUP</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> AT_SETUP([gprs-ns])</span><br><span> AT_KEYWORDS([gprs-ns])</span><br><span> cat $abs_srcdir/gb/gprs_ns_test.ok > expout</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/21862">change 21862</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/+/21862"/><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: Ibbc7fd67658e3040c12abb5706fe9d1f31894352 </div>
<div style="display:none"> Gerrit-Change-Number: 21862 </div>
<div style="display:none"> Gerrit-PatchSet: 13 </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>