<p>neels has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/20333">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">add BSSLAP coding for Location Services<br><br>BSSLAP: there are APDUs transferred in BSSMAP-LE Connection Oriented<br>Information messages on Lb between BSC and SMLC.<br>Add BSSLAP coding for these APDU messages:<br>- TA Layer3<br>- TA Request<br>- TA Response, possibly containing Location Estimate coded in GAD<br>- Reject<br>- Reset (for intra-BSS handover during TA Request)<br>- Abort (for inter-BSS handover)<br><br>Add encoding and decoding tests.<br><br>Change-Id: I6409c4bcac402dc7626a3afce9081c59cd715fe8<br>---<br>M include/Makefile.am<br>A include/osmocom/gsm/bsslap.h<br>M src/gsm/Makefile.am<br>A src/gsm/bsslap.c<br>M src/gsm/libosmogsm.map<br>M tests/Makefile.am<br>A tests/bsslap/bsslap_test.c<br>A tests/bsslap/bsslap_test.ok<br>M tests/testsuite.at<br>9 files changed, 691 insertions(+), 1 deletion(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/33/20333/1</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 a505952..7aa6442 100644</span><br><span>--- a/include/Makefile.am</span><br><span>+++ b/include/Makefile.am</span><br><span>@@ -92,6 +92,7 @@</span><br><span>                        osmocom/coding/gsm0503_interleaving.h \</span><br><span>                        osmocom/coding/gsm0503_coding.h \</span><br><span>                        osmocom/coding/gsm0503_amr_dtx.h \</span><br><span style="color: hsl(120, 100%, 40%);">+                       osmocom/gsm/bsslap.h \</span><br><span>                        osmocom/gsm/gad.h \</span><br><span>                        osmocom/gsm/gsm0808.h \</span><br><span>                        osmocom/gsm/gsm29205.h \</span><br><span>diff --git a/include/osmocom/gsm/bsslap.h b/include/osmocom/gsm/bsslap.h</span><br><span>new file mode 100644</span><br><span>index 0000000..135a943</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/gsm/bsslap.h</span><br><span>@@ -0,0 +1,105 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \defgroup bsslap Message encoding and decoding for 3GPP TS 48.071 BSS LCS Assistance Protocol (BSSLAP).</span><br><span style="color: hsl(120, 100%, 40%);">+ *  @{</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \file bsslap.h</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%);">+ * (C) 2020 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de></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%);">+ * Author: Neels Hofmeyr <neels@hofmeyr.de></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 along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</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 <errno.h></span><br><span style="color: hsl(120, 100%, 40%);">+</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/gsm/protocol/gsm_08_08.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/gsm0808.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/tlv.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum osmo_bsslap_msgt {</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_MSGT_TA_REQUEST = 0x1,</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_BSSLAP_MSGT_TA_RESPONSE = 0x2,</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_BSSLAP_MSGT_REJECT = 0xa,</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_BSSLAP_MSGT_RESET = 0xb,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_MSGT_ABORT = 0xc,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_MSGT_TA_LAYER3 = 0xd,</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_MSGT_MS_POS_CMD = 0xf,</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_BSSLAP_MSGT_MS_POS_RESP = 0x10,</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_BSSLAP_MSGT_UTDOA_REQ = 0x11,</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_BSSLAP_MSGT_UTDOA_RESP = 0x12,</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%);">+extern const struct value_string osmo_bsslap_msgt_names[];</span><br><span style="color: hsl(120, 100%, 40%);">+static inline const char *osmo_bsslap_msgt_name(enum osmo_bsslap_msgt val)</span><br><span style="color: hsl(120, 100%, 40%);">+{ return get_value_string(osmo_bsslap_msgt_names, val); }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum osmo_bsslap_cause {</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_BSSLAP_CAUSE_CONGESTION = 0x0,</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_BSSLAP_CAUSE_CHAN_MODE_NOT_SUPP = 0x1,</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_BSSLAP_CAUSE_POS_PROC_NOT_SUPP = 0x2,</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_BSSLAP_CAUSE_OTHER_RADIO_EVT_FAIL = 0x3,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_CAUSE_INTRA_BSS_HO = 0x4,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_CAUSE_SUPERV_TIMER_EXPIRED = 0x5,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_CAUSE_INTER_BSS_HO = 0x6,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_CAUSE_LOSS_SIG_CONN_MS = 0x7,</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_CAUSE_INCORR_SERV_CELL_ID = 0x8,</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_BSSLAP_CAUSE_BSSAP_LE_SEGMENT_ERR = 0x9,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_CAUSE_CONCUR_POS_PROC_NOT_EN = 0xa,</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%);">+struct osmo_bsslap_ta_response {</span><br><span style="color: hsl(120, 100%, 40%);">+       uint16_t cell_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t ta;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bool more_items; /*!< always set this to false */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_bsslap_ta_layer3 {</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t ta;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ bool more_items; /*!< always set this to false */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_bsslap_reset {</span><br><span style="color: hsl(120, 100%, 40%);">+        uint16_t cell_id;</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t ta;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct gsm48_chan_desc chan_desc;</span><br><span style="color: hsl(120, 100%, 40%);">+     enum osmo_bsslap_cause cause;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       bool more_items; /*!< always set this to false */</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_bsslap_pdu {</span><br><span style="color: hsl(120, 100%, 40%);">+  enum osmo_bsslap_msgt msg_type;</span><br><span style="color: hsl(120, 100%, 40%);">+       union {</span><br><span style="color: hsl(120, 100%, 40%);">+               /* ta_request: a TA Request message consists only of the message type. */</span><br><span style="color: hsl(120, 100%, 40%);">+             struct osmo_bsslap_ta_response ta_response;</span><br><span style="color: hsl(120, 100%, 40%);">+           enum osmo_bsslap_cause reject;</span><br><span style="color: hsl(120, 100%, 40%);">+                struct osmo_bsslap_reset reset;</span><br><span style="color: hsl(120, 100%, 40%);">+               enum osmo_bsslap_cause abort;</span><br><span style="color: hsl(120, 100%, 40%);">+         struct osmo_bsslap_ta_layer3 ta_layer3;</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%);">+int osmo_bsslap_enc(struct msgb *msg, const struct osmo_bsslap_pdu *pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+const char *osmo_bsslap_dec(struct osmo_bsslap_pdu *pdu, const uint8_t *data, size_t len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span>diff --git a/src/gsm/Makefile.am b/src/gsm/Makefile.am</span><br><span>index 4fa940b..465bae1 100644</span><br><span>--- a/src/gsm/Makefile.am</span><br><span>+++ b/src/gsm/Makefile.am</span><br><span>@@ -33,7 +33,7 @@</span><br><span>                    gsup.c gsup_sms.c gprs_gea.c gsm0503_conv.c oap.c gsm0808_utils.c \</span><br><span>                  gsm23003.c gsm23236.c mncc.c bts_features.c oap_client.c \</span><br><span>                   gsm29118.c gsm48_rest_octets.c cbsp.c gsm48049.c i460_mux.c \</span><br><span style="color: hsl(0, 100%, 40%);">-                   gad.c</span><br><span style="color: hsl(120, 100%, 40%);">+                 gad.c bsslap.c</span><br><span> libgsmint_la_LDFLAGS = -no-undefined</span><br><span> libgsmint_la_LIBADD = $(top_builddir)/src/libosmocore.la</span><br><span> </span><br><span>diff --git a/src/gsm/bsslap.c b/src/gsm/bsslap.c</span><br><span>new file mode 100644</span><br><span>index 0000000..a874789</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/bsslap.c</span><br><span>@@ -0,0 +1,461 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/* 3GPP TS 48.071 BSSLAP protocol definitions */</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 <info@sysmocom.de></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%);">+ * Author: Neels Hofmeyr <neels@hofmeyr.de></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 along</span><br><span style="color: hsl(120, 100%, 40%);">+ * with this program; if not, write to the Free Software Foundation, Inc.,</span><br><span style="color: hsl(120, 100%, 40%);">+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.</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 <osmocom/core/msgb.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/bsslap.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/core/logging.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \addtogroup bsslap</span><br><span style="color: hsl(120, 100%, 40%);">+ *  @{</span><br><span style="color: hsl(120, 100%, 40%);">+ *  \file bsslap.c</span><br><span style="color: hsl(120, 100%, 40%);">+ *  Message encoding and decoding for 3GPP TS 48.071 BSSLAP protocol.</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%);">+enum osmo_bsslap_iei {</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_BSSLAP_IEI_TA = 0x1,</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_IEI_CELL_ID = 0x9,</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_BSSLAP_IEI_CHAN_DESC = 0x10,</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_IEI_MEAS_REP = 0x14,</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_BSSLAP_IEI_CAUSE = 0x18,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_IEI_RRLP_FLAG = 0x19,</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_IEI_RRLP = 0x1b,</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_BSSLAP_IEI_CELL_ID_LIST = 0x1c,</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_BSSLAP_IEI_ENH_MEAS_REP = 0x1d,</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_BSSLAP_IEI_LAC = 0x1e,</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_BSSLAP_IEI_FREQ_LIST = 0x21,</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_IEI_MS_POWER = 0x22,</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_BSSLAP_IEI_DELTA_TIMER = 0x23,</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_BSSLAP_IEI_SERVING_CELL_ID = 0x24,</span><br><span style="color: hsl(120, 100%, 40%);">+       OSMO_BSSLAP_IEI_ENCR_KEY = 0x25,</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_BSSLAP_IEI_CIPH_MODE_SET = 0x26,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_IEI_CHAN_MODE = 0x27,</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_IEI_MR_CONFIG = 0x28,</span><br><span style="color: hsl(120, 100%, 40%);">+     OSMO_BSSLAP_IEI_POLLING_REPETITION = 0x29,</span><br><span style="color: hsl(120, 100%, 40%);">+    OSMO_BSSLAP_IEI_PACKET_CHAN_DESC = 0x2a,</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_BSSLAP_IEI_TLLI = 0x2b,</span><br><span style="color: hsl(120, 100%, 40%);">+  OSMO_BSSLAP_IEI_TFI = 0x2c,</span><br><span style="color: hsl(120, 100%, 40%);">+   OSMO_BSSLAP_IEI_TBF_START_TIME = 0x2d,</span><br><span style="color: hsl(120, 100%, 40%);">+        OSMO_BSSLAP_IEI_PWRUP_START_TIME = 0x2e,</span><br><span style="color: hsl(120, 100%, 40%);">+      OSMO_BSSLAP_IEI_LONG_ENCR_KEY = 0x2f,</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_BSSLAP_IEI_CONCUR_POS_PROC_F = 0x30,</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 const struct tlv_definition osmo_bsslap_tlvdef = {</span><br><span style="color: hsl(120, 100%, 40%);">+    .def = {</span><br><span style="color: hsl(120, 100%, 40%);">+      [OSMO_BSSLAP_IEI_TA] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+       [OSMO_BSSLAP_IEI_CELL_ID] = { TLV_TYPE_FIXED, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+    [OSMO_BSSLAP_IEI_CHAN_DESC] = { TLV_TYPE_FIXED, 3 },</span><br><span style="color: hsl(120, 100%, 40%);">+  [OSMO_BSSLAP_IEI_MEAS_REP] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+        [OSMO_BSSLAP_IEI_CAUSE] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+    [OSMO_BSSLAP_IEI_RRLP_FLAG] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+        [OSMO_BSSLAP_IEI_RRLP] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+    [OSMO_BSSLAP_IEI_CELL_ID_LIST] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+    [OSMO_BSSLAP_IEI_ENH_MEAS_REP] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+    [OSMO_BSSLAP_IEI_LAC] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+     [OSMO_BSSLAP_IEI_FREQ_LIST] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+       [OSMO_BSSLAP_IEI_MS_POWER] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [OSMO_BSSLAP_IEI_DELTA_TIMER] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+      [OSMO_BSSLAP_IEI_SERVING_CELL_ID] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [OSMO_BSSLAP_IEI_ENCR_KEY] = { TLV_TYPE_FIXED, 8 },</span><br><span style="color: hsl(120, 100%, 40%);">+   [OSMO_BSSLAP_IEI_CIPH_MODE_SET] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+    [OSMO_BSSLAP_IEI_CHAN_MODE] = { TLV_TYPE_TV, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+     [OSMO_BSSLAP_IEI_MR_CONFIG] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+       [OSMO_BSSLAP_IEI_POLLING_REPETITION] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+       [OSMO_BSSLAP_IEI_PACKET_CHAN_DESC] = { TLV_TYPE_FIXED, 4 },</span><br><span style="color: hsl(120, 100%, 40%);">+   [OSMO_BSSLAP_IEI_TLLI] = { TLV_TYPE_FIXED, 4 },</span><br><span style="color: hsl(120, 100%, 40%);">+       [OSMO_BSSLAP_IEI_TFI] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+     [OSMO_BSSLAP_IEI_TBF_START_TIME] = { TLV_TYPE_FIXED, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+     [OSMO_BSSLAP_IEI_PWRUP_START_TIME] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+        [OSMO_BSSLAP_IEI_LONG_ENCR_KEY] = { TLV_TYPE_FIXED, 16 },</span><br><span style="color: hsl(120, 100%, 40%);">+     [OSMO_BSSLAP_IEI_CONCUR_POS_PROC_F] = { TLV_TYPE_TV },</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 enum osmo_bsslap_msgt osmo_bsslap_msgt(const uint8_t *data, uint8_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!data || len < 1)</span><br><span style="color: hsl(120, 100%, 40%);">+              return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       return data[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 int osmo_bsslap_parse_tlv(struct tlv_parsed *tp, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     enum osmo_bsslap_msgt msg_type;</span><br><span style="color: hsl(120, 100%, 40%);">+       const uint8_t *ies_start;</span><br><span style="color: hsl(120, 100%, 40%);">+     int ies_len;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        msg_type = osmo_bsslap_msgt(data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (msg_type < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          return -EBADMSG;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ies_start = &data[1];</span><br><span style="color: hsl(120, 100%, 40%);">+     ies_len = len - 1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (tlv_parse2(tp, 1, &osmo_bsslap_tlvdef, ies_start, ies_len, 0, 0) <= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+             return -EBADMSG;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return msg_type;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int osmo_bsslap_ie_dec_cell_id(uint16_t *cell_id, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   if (len != 2)</span><br><span style="color: hsl(120, 100%, 40%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       *cell_id = osmo_load16be(data);</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 int osmo_bsslap_ie_dec_ta(uint8_t *ta, const uint8_t *data, size_t len)</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%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       *ta = data[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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int osmo_bsslap_ie_dec_cause(enum osmo_bsslap_cause *cause, const uint8_t *data, size_t len)</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%);">+         return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       *cause = data[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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int osmo_bsslap_ie_dec_chan_desc(struct gsm48_chan_desc *chan_desc, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        if (len != sizeof(*chan_desc))</span><br><span style="color: hsl(120, 100%, 40%);">+                return -EINVAL;</span><br><span style="color: hsl(120, 100%, 40%);">+       *chan_desc = *(struct gsm48_chan_desc*)data;</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 int osmo_bsslap_enc_ta_request(struct msgb *msg)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_put_u8(msg, OSMO_BSSLAP_MSGT_TA_REQUEST);</span><br><span style="color: hsl(120, 100%, 40%);">+        return 1;</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 osmo_bsslap_enc_ta_response(struct msgb *msg, const struct osmo_bsslap_ta_response *params)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     uint8_t *old_tail = msg->tail;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_put_u8(msg, OSMO_BSSLAP_MSGT_TA_RESPONSE);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     msgb_put_u8(msg, OSMO_BSSLAP_IEI_CELL_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_put_u16(msg, params->cell_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_put_u8(msg, OSMO_BSSLAP_IEI_TA);</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put_u8(msg, params->ta);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return (msg->tail - old_tail);</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 const char *osmo_bsslap_dec_ta_response(struct osmo_bsslap_ta_response *pdu, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct tlv_parsed _tp;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct tlv_parsed *tp = &_tp;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct tlv_p_entry *e;</span><br><span style="color: hsl(120, 100%, 40%);">+        int t;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PARSE_ERR(errmsg) \</span><br><span style="color: hsl(120, 100%, 40%);">+         return "Decoding BSSLAP TA Response: " errmsg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    *pdu = (struct osmo_bsslap_ta_response){};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  t = osmo_bsslap_parse_tlv(tp, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (t < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         PARSE_ERR("failed to parse TLV structure");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (t != OSMO_BSSLAP_MSGT_TA_RESPONSE)</span><br><span style="color: hsl(120, 100%, 40%);">+                PARSE_ERR("unexpected message type");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_CELL_ID)))</span><br><span style="color: hsl(120, 100%, 40%);">+             PARSE_ERR("missing mandatory Cell Identity IE");</span><br><span style="color: hsl(120, 100%, 40%);">+    if (osmo_bsslap_ie_dec_cell_id(&pdu->cell_id, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+           PARSE_ERR("cannot parse Cell Identity IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_TA)))</span><br><span style="color: hsl(120, 100%, 40%);">+          PARSE_ERR("missing mandatory TA IE");</span><br><span style="color: hsl(120, 100%, 40%);">+       if (osmo_bsslap_ie_dec_ta(&pdu->ta, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+             PARSE_ERR("cannot parse TA IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+#undef PARSE_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%);">+static int osmo_bsslap_enc_ta_layer3(struct msgb *msg, const struct osmo_bsslap_ta_layer3 *params)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *old_tail = msg->tail;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_put_u8(msg, OSMO_BSSLAP_MSGT_TA_LAYER3);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       msgb_put_u8(msg, OSMO_BSSLAP_IEI_TA);</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put_u8(msg, params->ta);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    return (msg->tail - old_tail);</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 const char *osmo_bsslap_dec_ta_layer3(struct osmo_bsslap_ta_layer3 *pdu, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct tlv_parsed _tp;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct tlv_parsed *tp = &_tp;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct tlv_p_entry *e;</span><br><span style="color: hsl(120, 100%, 40%);">+        int t;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PARSE_ERR(errmsg) \</span><br><span style="color: hsl(120, 100%, 40%);">+         return "Decoding BSSLAP TA Layer3: " errmsg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      *pdu = (struct osmo_bsslap_ta_layer3){};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    t = osmo_bsslap_parse_tlv(tp, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (t < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         PARSE_ERR("failed to parse TLV structure");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (t != OSMO_BSSLAP_MSGT_TA_LAYER3)</span><br><span style="color: hsl(120, 100%, 40%);">+          PARSE_ERR("unexpected message type");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_TA)))</span><br><span style="color: hsl(120, 100%, 40%);">+          PARSE_ERR("missing mandatory TA IE");</span><br><span style="color: hsl(120, 100%, 40%);">+       if (osmo_bsslap_ie_dec_ta(&pdu->ta, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+             PARSE_ERR("cannot parse TA IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+#undef PARSE_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%);">+static int osmo_bsslap_enc_reject(struct msgb *msg, enum osmo_bsslap_cause cause)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     msgb_put_u8(msg, OSMO_BSSLAP_MSGT_REJECT);</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_put_u8(msg, OSMO_BSSLAP_IEI_CAUSE);</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_put_u8(msg, cause);</span><br><span style="color: hsl(120, 100%, 40%);">+      return 3;</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 const char *osmo_bsslap_dec_reject(enum osmo_bsslap_cause *cause, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  struct tlv_parsed _tp;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct tlv_parsed *tp = &_tp;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct tlv_p_entry *e;</span><br><span style="color: hsl(120, 100%, 40%);">+        int t;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PARSE_ERR(errmsg) \</span><br><span style="color: hsl(120, 100%, 40%);">+         return "Decoding BSSLAP Reject: " errmsg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ *cause = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        t = osmo_bsslap_parse_tlv(tp, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (t < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         PARSE_ERR("failed to parse TLV structure");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (t != OSMO_BSSLAP_MSGT_REJECT)</span><br><span style="color: hsl(120, 100%, 40%);">+             PARSE_ERR("unexpected message type");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_CAUSE)))</span><br><span style="color: hsl(120, 100%, 40%);">+               PARSE_ERR("missing mandatory Cause IE");</span><br><span style="color: hsl(120, 100%, 40%);">+    if (osmo_bsslap_ie_dec_cause(cause, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+            PARSE_ERR("cannot parse Cause IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+#undef PARSE_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%);">+static int osmo_bsslap_enc_abort(struct msgb *msg, enum osmo_bsslap_cause cause)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_put_u8(msg, OSMO_BSSLAP_MSGT_ABORT);</span><br><span style="color: hsl(120, 100%, 40%);">+     msgb_put_u8(msg, OSMO_BSSLAP_IEI_CAUSE);</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_put_u8(msg, cause);</span><br><span style="color: hsl(120, 100%, 40%);">+      return 3;</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 const char *osmo_bsslap_dec_abort(enum osmo_bsslap_cause *cause, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct tlv_parsed _tp;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct tlv_parsed *tp = &_tp;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct tlv_p_entry *e;</span><br><span style="color: hsl(120, 100%, 40%);">+        int t;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PARSE_ERR(errmsg) \</span><br><span style="color: hsl(120, 100%, 40%);">+         return "Decoding BSSLAP TA Abort: " errmsg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       *cause = -1;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        t = osmo_bsslap_parse_tlv(tp, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (t < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         PARSE_ERR("failed to parse TLV structure");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (t != OSMO_BSSLAP_MSGT_ABORT)</span><br><span style="color: hsl(120, 100%, 40%);">+              PARSE_ERR("unexpected message type");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_CAUSE)))</span><br><span style="color: hsl(120, 100%, 40%);">+               PARSE_ERR("missing mandatory Cause IE");</span><br><span style="color: hsl(120, 100%, 40%);">+    if (osmo_bsslap_ie_dec_cause(cause, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+            PARSE_ERR("cannot parse Cause IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+#undef PARSE_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%);">+static int osmo_bsslap_enc_reset(struct msgb *msg, const struct osmo_bsslap_reset *params)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    struct gsm48_chan_desc *chan_desc;</span><br><span style="color: hsl(120, 100%, 40%);">+    uint8_t *old_tail = msg->tail;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_put_u8(msg, OSMO_BSSLAP_MSGT_RESET);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   msgb_put_u8(msg, OSMO_BSSLAP_IEI_CELL_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_put_u16(msg, params->cell_id);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_put_u8(msg, OSMO_BSSLAP_IEI_TA);</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put_u8(msg, params->ta);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    msgb_put_u8(msg, OSMO_BSSLAP_IEI_CHAN_DESC);</span><br><span style="color: hsl(120, 100%, 40%);">+  chan_desc = (void*)msgb_put(msg, sizeof(params->chan_desc));</span><br><span style="color: hsl(120, 100%, 40%);">+       *chan_desc = params->chan_desc;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  msgb_put_u8(msg, OSMO_BSSLAP_IEI_CAUSE);</span><br><span style="color: hsl(120, 100%, 40%);">+      msgb_put_u8(msg, params->cause);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return (msg->tail - old_tail);</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 const char *osmo_bsslap_dec_reset(struct osmo_bsslap_reset *pdu, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+   struct tlv_parsed _tp;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct tlv_parsed *tp = &_tp;</span><br><span style="color: hsl(120, 100%, 40%);">+     struct tlv_p_entry *e;</span><br><span style="color: hsl(120, 100%, 40%);">+        int t;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define PARSE_ERR(errmsg) \</span><br><span style="color: hsl(120, 100%, 40%);">+         return "Decoding BSSLAP Reset: " errmsg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  *pdu = (struct osmo_bsslap_reset){};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        t = osmo_bsslap_parse_tlv(tp, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (t < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+         PARSE_ERR("failed to parse TLV structure");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (t != OSMO_BSSLAP_MSGT_RESET)</span><br><span style="color: hsl(120, 100%, 40%);">+              PARSE_ERR("unexpected message type");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_CELL_ID)))</span><br><span style="color: hsl(120, 100%, 40%);">+             PARSE_ERR("missing mandatory Cell Identity IE");</span><br><span style="color: hsl(120, 100%, 40%);">+    if (osmo_bsslap_ie_dec_cell_id(&pdu->cell_id, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+           PARSE_ERR("cannot parse Cell Identity IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_TA)))</span><br><span style="color: hsl(120, 100%, 40%);">+          PARSE_ERR("missing mandatory TA IE");</span><br><span style="color: hsl(120, 100%, 40%);">+       if (osmo_bsslap_ie_dec_ta(&pdu->ta, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+             PARSE_ERR("cannot parse TA IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_CHAN_DESC)))</span><br><span style="color: hsl(120, 100%, 40%);">+           PARSE_ERR("missing mandatory Channel Description IE");</span><br><span style="color: hsl(120, 100%, 40%);">+      if (osmo_bsslap_ie_dec_chan_desc(&pdu->chan_desc, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+               PARSE_ERR("cannot parse Channel Description IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!(e = TLVP_GET(tp, OSMO_BSSLAP_IEI_CAUSE)))</span><br><span style="color: hsl(120, 100%, 40%);">+               PARSE_ERR("missing mandatory Cause IE");</span><br><span style="color: hsl(120, 100%, 40%);">+    if (osmo_bsslap_ie_dec_cause(&pdu->cause, e->val, e->len))</span><br><span style="color: hsl(120, 100%, 40%);">+               PARSE_ERR("cannot parse Cause IE");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+#undef PARSE_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%);">+/*! Encode BSSLAP PDU and add to msgb (3GPP TS 48.071).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] msg  msgb to append to.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] pdu  PDU data to encode.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return number of bytes written, negative on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_bsslap_enc(struct msgb *msg, const struct osmo_bsslap_pdu *pdu)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (pdu->msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+   case OSMO_BSSLAP_MSGT_TA_REQUEST:</span><br><span style="color: hsl(120, 100%, 40%);">+             return osmo_bsslap_enc_ta_request(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       case OSMO_BSSLAP_MSGT_TA_RESPONSE:</span><br><span style="color: hsl(120, 100%, 40%);">+            return osmo_bsslap_enc_ta_response(msg, &pdu->ta_response);</span><br><span style="color: hsl(120, 100%, 40%);">+    case OSMO_BSSLAP_MSGT_REJECT:</span><br><span style="color: hsl(120, 100%, 40%);">+         return osmo_bsslap_enc_reject(msg, pdu->reject);</span><br><span style="color: hsl(120, 100%, 40%);">+   case OSMO_BSSLAP_MSGT_RESET:</span><br><span style="color: hsl(120, 100%, 40%);">+          return osmo_bsslap_enc_reset(msg, &pdu->reset);</span><br><span style="color: hsl(120, 100%, 40%);">+        case OSMO_BSSLAP_MSGT_ABORT:</span><br><span style="color: hsl(120, 100%, 40%);">+          return osmo_bsslap_enc_abort(msg, pdu->abort);</span><br><span style="color: hsl(120, 100%, 40%);">+     case OSMO_BSSLAP_MSGT_TA_LAYER3:</span><br><span style="color: hsl(120, 100%, 40%);">+              return osmo_bsslap_enc_ta_layer3(msg, &pdu->ta_layer3);</span><br><span style="color: hsl(120, 100%, 40%);">+        default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return -ENOTSUP;</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%);">+/*! Decode BSSLAP PDU (3GPP TS 48.071).</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[out] pdu  Write decoded values here.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] data  Pointer to BSSLAP PDU raw data.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] len  Data length to decode.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \return NULL upon success, a human readable error message on failure.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+const char *osmo_bsslap_dec(struct osmo_bsslap_pdu *pdu, const uint8_t *data, size_t len)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  *pdu = (struct osmo_bsslap_pdu){};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  pdu->msg_type = osmo_bsslap_msgt(data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+       if (pdu->msg_type < 0)</span><br><span style="color: hsl(120, 100%, 40%);">+          return "BSSLAP PDU too short";</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    switch (pdu->msg_type) {</span><br><span style="color: hsl(120, 100%, 40%);">+   case OSMO_BSSLAP_MSGT_TA_REQUEST:</span><br><span style="color: hsl(120, 100%, 40%);">+             /* The TA Request message contains only the message type. */</span><br><span style="color: hsl(120, 100%, 40%);">+          return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_BSSLAP_MSGT_TA_RESPONSE:</span><br><span style="color: hsl(120, 100%, 40%);">+            return osmo_bsslap_dec_ta_response(&pdu->ta_response, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+      case OSMO_BSSLAP_MSGT_REJECT:</span><br><span style="color: hsl(120, 100%, 40%);">+         return osmo_bsslap_dec_reject(&pdu->reject, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+        case OSMO_BSSLAP_MSGT_RESET:</span><br><span style="color: hsl(120, 100%, 40%);">+          return osmo_bsslap_dec_reset(&pdu->reset, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_BSSLAP_MSGT_ABORT:</span><br><span style="color: hsl(120, 100%, 40%);">+          return osmo_bsslap_dec_abort(&pdu->abort, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+  case OSMO_BSSLAP_MSGT_TA_LAYER3:</span><br><span style="color: hsl(120, 100%, 40%);">+              return osmo_bsslap_dec_ta_layer3(&pdu->ta_layer3, data, len);</span><br><span style="color: hsl(120, 100%, 40%);">+  default:</span><br><span style="color: hsl(120, 100%, 40%);">+              return "Unsupported BSSLAP message type";</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string osmo_bsslap_msgt_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+     { OSMO_BSSLAP_MSGT_TA_REQUEST, "TA_REQUEST" },</span><br><span style="color: hsl(120, 100%, 40%);">+      { OSMO_BSSLAP_MSGT_TA_RESPONSE, "TA_RESPONSE" },</span><br><span style="color: hsl(120, 100%, 40%);">+    { OSMO_BSSLAP_MSGT_REJECT, "REJECT" },</span><br><span style="color: hsl(120, 100%, 40%);">+      { OSMO_BSSLAP_MSGT_RESET, "RESET" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { OSMO_BSSLAP_MSGT_ABORT, "ABORT" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { OSMO_BSSLAP_MSGT_TA_LAYER3, "TA_LAYER3" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { OSMO_BSSLAP_MSGT_MS_POS_CMD, "MS_POS_CMD" },</span><br><span style="color: hsl(120, 100%, 40%);">+      { OSMO_BSSLAP_MSGT_MS_POS_RESP, "MS_POS_RESP" },</span><br><span style="color: hsl(120, 100%, 40%);">+    { OSMO_BSSLAP_MSGT_UTDOA_REQ, "UTDOA_REQ" },</span><br><span style="color: hsl(120, 100%, 40%);">+        { OSMO_BSSLAP_MSGT_UTDOA_RESP, "UTDOA_RESP" },</span><br><span style="color: hsl(120, 100%, 40%);">+      {}</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! @} */</span><br><span>diff --git a/src/gsm/libosmogsm.map b/src/gsm/libosmogsm.map</span><br><span>index a31f73a..257c3fa 100644</span><br><span>--- a/src/gsm/libosmogsm.map</span><br><span>+++ b/src/gsm/libosmogsm.map</span><br><span>@@ -705,6 +705,10 @@</span><br><span> osmo_nri_ranges_to_str_buf;</span><br><span> osmo_nri_ranges_to_str_c;</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+osmo_bsslap_enc;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_bsslap_dec;</span><br><span style="color: hsl(120, 100%, 40%);">+osmo_bsslap_msgt_names;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> osmo_gad_enc;</span><br><span> osmo_gad_dec;</span><br><span> osmo_gad_to_str_buf;</span><br><span>diff --git a/tests/Makefile.am b/tests/Makefile.am</span><br><span>index 9a2f217..4dfad1b 100644</span><br><span>--- a/tests/Makefile.am</span><br><span>+++ b/tests/Makefile.am</span><br><span>@@ -39,6 +39,7 @@</span><br><span>                  i460_mux/i460_mux_test                                        \</span><br><span>             bitgen/bitgen_test                                     \</span><br><span>             gad/gad_test                                           \</span><br><span style="color: hsl(120, 100%, 40%);">+              bsslap/bsslap_test                                     \</span><br><span>             $(NULL)</span><br><span> </span><br><span> if ENABLE_MSGFILE</span><br><span>@@ -285,6 +286,9 @@</span><br><span> gad_gad_test_SOURCES = gad/gad_test.c</span><br><span> gad_gad_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/gad.o</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+bsslap_bsslap_test_SOURCES = bsslap/bsslap_test.c</span><br><span style="color: hsl(120, 100%, 40%);">+bsslap_bsslap_test_LDADD = $(LDADD) $(top_builddir)/src/gsm/libosmogsm.la</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> # The `:;' works around a Bash 3.2 bug when the output is not writeable.</span><br><span> $(srcdir)/package.m4: $(top_srcdir)/configure.ac</span><br><span>      :;{ \</span><br><span>@@ -366,6 +370,7 @@</span><br><span>       i460_mux/i460_mux_test.ok \</span><br><span>          bitgen/bitgen_test.ok \</span><br><span>              gad/gad_test.ok \</span><br><span style="color: hsl(120, 100%, 40%);">+             bsslap/bsslap_test.ok \</span><br><span>              $(NULL)</span><br><span> </span><br><span> if ENABLE_LIBSCTP</span><br><span>diff --git a/tests/bsslap/bsslap_test.c b/tests/bsslap/bsslap_test.c</span><br><span>new file mode 100644</span><br><span>index 0000000..2b6c35e</span><br><span>--- /dev/null</span><br><span>+++ b/tests/bsslap/bsslap_test.c</span><br><span>@@ -0,0 +1,101 @@</span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdio.h></span><br><span style="color: hsl(120, 100%, 40%);">+</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/gsm/bsslap.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_bsslap_pdu bsslap_test_pdus[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+        {</span><br><span style="color: hsl(120, 100%, 40%);">+             .msg_type = OSMO_BSSLAP_MSGT_TA_REQUEST,</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%);">+             .msg_type = OSMO_BSSLAP_MSGT_TA_RESPONSE,</span><br><span style="color: hsl(120, 100%, 40%);">+             .ta_response = {</span><br><span style="color: hsl(120, 100%, 40%);">+                      .cell_id = 23,</span><br><span style="color: hsl(120, 100%, 40%);">+                        .ta = 42,</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%);">+             .msg_type = OSMO_BSSLAP_MSGT_REJECT,</span><br><span style="color: hsl(120, 100%, 40%);">+          .reject = OSMO_BSSLAP_CAUSE_OTHER_RADIO_EVT_FAIL,</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%);">+             .msg_type = OSMO_BSSLAP_MSGT_RESET,</span><br><span style="color: hsl(120, 100%, 40%);">+           .reset = {</span><br><span style="color: hsl(120, 100%, 40%);">+                    .cell_id = 23,</span><br><span style="color: hsl(120, 100%, 40%);">+                        .ta = 42,</span><br><span style="color: hsl(120, 100%, 40%);">+                     .chan_desc =  {</span><br><span style="color: hsl(120, 100%, 40%);">+                               .chan_nr = 23,</span><br><span style="color: hsl(120, 100%, 40%);">+                                .h0 = {</span><br><span style="color: hsl(120, 100%, 40%);">+                                       .tsc = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+                                     .h = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+                                       .arfcn_high = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+                                      .arfcn_low = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+                               },</span><br><span style="color: hsl(120, 100%, 40%);">+                    },</span><br><span style="color: hsl(120, 100%, 40%);">+                    .cause = OSMO_BSSLAP_CAUSE_INTRA_BSS_HO,</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%);">+             .msg_type = OSMO_BSSLAP_MSGT_ABORT,</span><br><span style="color: hsl(120, 100%, 40%);">+           .abort = OSMO_BSSLAP_CAUSE_LOSS_SIG_CONN_MS,</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%);">+             .msg_type = OSMO_BSSLAP_MSGT_TA_LAYER3,</span><br><span style="color: hsl(120, 100%, 40%);">+               .ta_layer3 = {</span><br><span style="color: hsl(120, 100%, 40%);">+                        .ta = 23,</span><br><span style="color: hsl(120, 100%, 40%);">+             },</span><br><span style="color: hsl(120, 100%, 40%);">+    },</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+void test_bsslap_enc_dec()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct osmo_bsslap_pdu *pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+  printf("--- %s\n", __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     for (pdu = bsslap_test_pdus; (pdu - bsslap_test_pdus) < ARRAY_SIZE(bsslap_test_pdus); pdu++) {</span><br><span style="color: hsl(120, 100%, 40%);">+             struct msgb *msg = msgb_alloc(1024, __func__);</span><br><span style="color: hsl(120, 100%, 40%);">+                struct osmo_bsslap_pdu dec_pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+               int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+               const char *errmsg;</span><br><span style="color: hsl(120, 100%, 40%);">+           rc = osmo_bsslap_enc(msg, pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (rc <= 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("[%ld] %s: ERROR: failed to encode pdu\n", (pdu - bsslap_test_pdus),</span><br><span style="color: hsl(120, 100%, 40%);">+                        osmo_bsslap_msgt_name(pdu->msg_type));</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto loop_end;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+             if (rc != msg->len) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      printf("[%ld] %s: ERROR: osmo_bsslap_enc() returned length %d but msgb has %d bytes\n",</span><br><span style="color: hsl(120, 100%, 40%);">+                            (pdu - bsslap_test_pdus), osmo_bsslap_msgt_name(pdu->msg_type),</span><br><span style="color: hsl(120, 100%, 40%);">+                            rc, msg->len);</span><br><span style="color: hsl(120, 100%, 40%);">+                      goto loop_end;</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%);">+           memset(&dec_pdu, 0xff, sizeof(dec_pdu));</span><br><span style="color: hsl(120, 100%, 40%);">+          errmsg = osmo_bsslap_dec(&dec_pdu, msg->data, msg->len);</span><br><span style="color: hsl(120, 100%, 40%);">+            if (errmsg) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 printf("[%ld] %s: ERROR: failed to decode pdu: %s\n", (pdu - bsslap_test_pdus),</span><br><span style="color: hsl(120, 100%, 40%);">+                            osmo_bsslap_msgt_name(pdu->msg_type), errmsg);</span><br><span style="color: hsl(120, 100%, 40%);">+                      printf("     encoded data: %s\n", osmo_hexdump(msg->data, msg->len));</span><br><span style="color: hsl(120, 100%, 40%);">+                 goto loop_end;</span><br><span style="color: hsl(120, 100%, 40%);">+                }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+           if (memcmp(pdu, &dec_pdu, sizeof(dec_pdu))) {</span><br><span style="color: hsl(120, 100%, 40%);">+                     printf("[%ld] %s: ERROR: decoded PDU != encoded PDU\n", (pdu - bsslap_test_pdus),</span><br><span style="color: hsl(120, 100%, 40%);">+                          osmo_bsslap_msgt_name(pdu->msg_type));</span><br><span style="color: hsl(120, 100%, 40%);">+                      printf("     original struct: %s\n", osmo_hexdump((void*)pdu, sizeof(*pdu)));</span><br><span style="color: hsl(120, 100%, 40%);">+                       printf("      decoded struct: %s\n", osmo_hexdump((void*)&dec_pdu, sizeof(dec_pdu)));</span><br><span style="color: hsl(120, 100%, 40%);">+                   goto loop_end;</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("[%ld] %s: ok\n", (pdu - bsslap_test_pdus), osmo_bsslap_msgt_name(pdu->msg_type));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+loop_end:</span><br><span style="color: hsl(120, 100%, 40%);">+           msgb_free(msg);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+int main()</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ test_bsslap_enc_dec();</span><br><span style="color: hsl(120, 100%, 40%);">+        return 0;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span>diff --git a/tests/bsslap/bsslap_test.ok b/tests/bsslap/bsslap_test.ok</span><br><span>new file mode 100644</span><br><span>index 0000000..8e4643c</span><br><span>--- /dev/null</span><br><span>+++ b/tests/bsslap/bsslap_test.ok</span><br><span>@@ -0,0 +1,7 @@</span><br><span style="color: hsl(120, 100%, 40%);">+--- test_bsslap_enc_dec</span><br><span style="color: hsl(120, 100%, 40%);">+[0] TA_REQUEST: ok</span><br><span style="color: hsl(120, 100%, 40%);">+[1] TA_RESPONSE: ok</span><br><span style="color: hsl(120, 100%, 40%);">+[2] REJECT: ok</span><br><span style="color: hsl(120, 100%, 40%);">+[3] RESET: ok</span><br><span style="color: hsl(120, 100%, 40%);">+[4] ABORT: ok</span><br><span style="color: hsl(120, 100%, 40%);">+[5] TA_LAYER3: ok</span><br><span>diff --git a/tests/testsuite.at b/tests/testsuite.at</span><br><span>index 10cf74b..1fa9a07 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -408,3 +408,9 @@</span><br><span> cat $abs_srcdir/gad/gad_test.ok > expout</span><br><span> AT_CHECK([$abs_top_builddir/tests/gad/gad_test], [0], [expout], [ignore])</span><br><span> AT_CLEANUP</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+AT_SETUP([bsslap])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_KEYWORDS([bsslap])</span><br><span style="color: hsl(120, 100%, 40%);">+cat $abs_srcdir/bsslap/bsslap_test.ok > expout</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CHECK([$abs_top_builddir/tests/bsslap/bsslap_test], [0], [expout], [ignore])</span><br><span style="color: hsl(120, 100%, 40%);">+AT_CLEANUP</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/c/libosmocore/+/20333">change 20333</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/+/20333"/><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: I6409c4bcac402dc7626a3afce9081c59cd715fe8 </div>
<div style="display:none"> Gerrit-Change-Number: 20333 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>