<p>laforge <strong>submitted</strong> this change.</p><p><a href="https://gerrit.osmocom.org/c/libosmocore/+/20333">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
laforge: Looks good to me, approved
</div><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>A include/osmocom/gsm/protocol/gsm_48_071.h<br>A include/osmocom/gsm/protocol/gsm_49_031.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>11 files changed, 698 insertions(+), 1 deletion(-)<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 fc1eec3..19d4043 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>@@ -134,6 +135,8 @@</span><br><span> osmocom/gsm/protocol/gsm_29_118.h \</span><br><span> osmocom/gsm/protocol/gsm_44_318.h \</span><br><span> osmocom/gsm/protocol/gsm_48_049.h \</span><br><span style="color: hsl(120, 100%, 40%);">+ osmocom/gsm/protocol/gsm_48_071.h \</span><br><span style="color: hsl(120, 100%, 40%);">+ osmocom/gsm/protocol/gsm_49_031.h \</span><br><span> osmocom/gsm/protocol/ipaccess.h \</span><br><span> osmocom/gsm/protocol/smpp34_osmocom.h \</span><br><span> osmocom/gsm/rsl.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..b2174b3</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/gsm/bsslap.h</span><br><span>@@ -0,0 +1,57 @@</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.h</span><br><span style="color: hsl(120, 100%, 40%);">+ * 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%);">+/*</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 <osmocom/gsm/protocol/gsm_48_071.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <osmocom/gsm/protocol/gsm_49_031.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct msgb;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct osmo_bsslap_err {</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bsslap_msgt msg_type;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bsslap_iei iei;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum lcs_cause cause;</span><br><span style="color: hsl(120, 100%, 40%);">+ char *logmsg;</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 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%);">+extern const struct value_string osmo_bsslap_iei_names[];</span><br><span style="color: hsl(120, 100%, 40%);">+static inline const char *osmo_bsslap_iei_name(enum bsslap_iei val)</span><br><span style="color: hsl(120, 100%, 40%);">+{ return get_value_string(osmo_bsslap_iei_names, val); }</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 bsslap_pdu *pdu);</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_bsslap_dec(struct bsslap_pdu *pdu,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_bsslap_err **err, void *err_ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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/include/osmocom/gsm/protocol/gsm_48_071.h b/include/osmocom/gsm/protocol/gsm_48_071.h</span><br><span>new file mode 100644</span><br><span>index 0000000..fb9653a</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/gsm/protocol/gsm_48_071.h</span><br><span>@@ -0,0 +1,122 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \defgroup bsslap 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 gsm_48_071.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 <osmocom/gsm/protocol/gsm_04_08.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+enum bsslap_msgt {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_TA_REQUEST = 0x1,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_TA_RESPONSE = 0x2,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_REJECT = 0xa,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_RESET = 0xb,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_ABORT = 0xc,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_TA_LAYER3 = 0xd,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_MS_POS_CMD = 0xf,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_MS_POS_RESP = 0x10,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_MSGT_UTDOA_REQ = 0x11,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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%);">+enum bsslap_cause {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_CONGESTION = 0x0,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_CHAN_MODE_NOT_SUPP = 0x1,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_POS_PROC_NOT_SUPP = 0x2,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_OTHER_RADIO_EVT_FAIL = 0x3,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_INTRA_BSS_HO = 0x4,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_SUPERV_TIMER_EXPIRED = 0x5,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_INTER_BSS_HO = 0x6,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_LOSS_SIG_CONN_MS = 0x7,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_INCORR_SERV_CELL_ID = 0x8,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_CAUSE_BSSAP_LE_SEGMENT_ERR = 0x9,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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%);">+enum bsslap_iei {</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_TA = 0x1,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_CELL_ID = 0x9,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_CHAN_DESC = 0x10,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_MEAS_REP = 0x14,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_CAUSE = 0x18,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_RRLP_FLAG = 0x19,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_RRLP = 0x1b,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_CELL_ID_LIST = 0x1c,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_ENH_MEAS_REP = 0x1d,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_LAC = 0x1e,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_FREQ_LIST = 0x21,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_MS_POWER = 0x22,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_DELTA_TIMER = 0x23,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_SERVING_CELL_ID = 0x24,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_ENCR_KEY = 0x25,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_CIPH_MODE_SET = 0x26,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_CHAN_MODE = 0x27,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_MR_CONFIG = 0x28,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_POLLING_REPETITION = 0x29,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_PACKET_CHAN_DESC = 0x2a,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_TLLI = 0x2b,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_TFI = 0x2c,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_TBF_START_TIME = 0x2d,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_PWRUP_START_TIME = 0x2e,</span><br><span style="color: hsl(120, 100%, 40%);">+ BSSLAP_IEI_LONG_ENCR_KEY = 0x2f,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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%);">+struct 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 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 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 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 bsslap_pdu {</span><br><span style="color: hsl(120, 100%, 40%);">+ enum 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 bsslap_ta_response ta_response;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bsslap_cause reject;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct bsslap_reset reset;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bsslap_cause abort;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct 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%);">+/*! @} */</span><br><span>diff --git a/include/osmocom/gsm/protocol/gsm_49_031.h b/include/osmocom/gsm/protocol/gsm_49_031.h</span><br><span>new file mode 100644</span><br><span>index 0000000..b44a07e</span><br><span>--- /dev/null</span><br><span>+++ b/include/osmocom/gsm/protocol/gsm_49_031.h</span><br><span>@@ -0,0 +1,61 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \defgroup bssmap_le 3GPP TS 49.031 BSSMAP-LE.</span><br><span style="color: hsl(120, 100%, 40%);">+ * @{</span><br><span style="color: hsl(120, 100%, 40%);">+ * \file gsm_49_031.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 <stdint.h></span><br><span style="color: hsl(120, 100%, 40%);">+#include <stdbool.h></span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! 3GPP TS 49.031 10.13 LCS Cause, also in 3GPP TS 48.008 3.2.2.66, which simply refers to the former. */</span><br><span style="color: hsl(120, 100%, 40%);">+enum lcs_cause {</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_UNSPECIFIED = 0,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_SYSTEM_FAILURE = 1,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_PROTOCOL_ERROR = 2,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_DATA_MISSING_IN_REQ = 3,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_UNEXP_DATA_IN_REQ = 4,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_POS_METH_FAILURE = 5,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_TGT_MS_UNREACHABLE = 6,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_REQUEST_ABORTED = 7,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_FACILITY_NOTSUPP = 8,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_INTER_BSC_HO = 9,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_INTRA_BSC_HO = 10,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_CONGESTION = 11,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_INTER_NSE_CHG = 12,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_RA_UPDAT = 13,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_PTMSI_REALLOC = 14,</span><br><span style="color: hsl(120, 100%, 40%);">+ LCS_CAUSE_GPRS_SUSPENSION = 15,</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 49.031 10.13 LCS Cause, also in 3GPP TS 48.008 3.2.2.66, which simply refers to the former. */</span><br><span style="color: hsl(120, 100%, 40%);">+struct lcs_cause_ie {</span><br><span style="color: hsl(120, 100%, 40%);">+ bool present;</span><br><span style="color: hsl(120, 100%, 40%);">+ enum lcs_cause cause_val;</span><br><span style="color: hsl(120, 100%, 40%);">+ bool diag_val_present;</span><br><span style="color: hsl(120, 100%, 40%);">+ uint8_t diag_val;</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/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..7886da6</span><br><span>--- /dev/null</span><br><span>+++ b/src/gsm/bsslap.c</span><br><span>@@ -0,0 +1,329 @@</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 <errno.h></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%);">+#include <osmocom/gsm/tlv.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%);">+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%);">+ [BSSLAP_IEI_TA] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_CELL_ID] = { TLV_TYPE_FIXED, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_CHAN_DESC] = { TLV_TYPE_FIXED, 3 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_MEAS_REP] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_CAUSE] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_RRLP_FLAG] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_RRLP] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_CELL_ID_LIST] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_ENH_MEAS_REP] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_LAC] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_FREQ_LIST] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_MS_POWER] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_DELTA_TIMER] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_SERVING_CELL_ID] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_ENCR_KEY] = { TLV_TYPE_FIXED, 8 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_CIPH_MODE_SET] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_CHAN_MODE] = { TLV_TYPE_TV, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_MR_CONFIG] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_POLLING_REPETITION] = { TLV_TYPE_TV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_PACKET_CHAN_DESC] = { TLV_TYPE_FIXED, 4 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_TLLI] = { TLV_TYPE_FIXED, 4 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_TFI] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_TBF_START_TIME] = { TLV_TYPE_FIXED, 2 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_PWRUP_START_TIME] = { TLV_TYPE_TLV },</span><br><span style="color: hsl(120, 100%, 40%);">+ [BSSLAP_IEI_LONG_ENCR_KEY] = { TLV_TYPE_FIXED, 16 },</span><br><span style="color: hsl(120, 100%, 40%);">+ [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%);">+#define DEC_ERR(RC, MSG_TYPE, IEI, CAUSE, fmt, args...) do { \</span><br><span style="color: hsl(120, 100%, 40%);">+ if (err && !*err) { \</span><br><span style="color: hsl(120, 100%, 40%);">+ *err = talloc_zero(err_ctx, struct osmo_bsslap_err); \</span><br><span style="color: hsl(120, 100%, 40%);">+ **err = (struct osmo_bsslap_err){ \</span><br><span style="color: hsl(120, 100%, 40%);">+ .rc = (RC), \</span><br><span style="color: hsl(120, 100%, 40%);">+ .msg_type = (MSG_TYPE), \</span><br><span style="color: hsl(120, 100%, 40%);">+ .iei = (IEI), \</span><br><span style="color: hsl(120, 100%, 40%);">+ .cause = (CAUSE), \</span><br><span style="color: hsl(120, 100%, 40%);">+ .logmsg = talloc_asprintf(*err, "Error decoding BSSLAP%s%s%s%s%s: " fmt, \</span><br><span style="color: hsl(120, 100%, 40%);">+ (MSG_TYPE) >= 0 ? " " : "", \</span><br><span style="color: hsl(120, 100%, 40%);">+ (MSG_TYPE) >= 0 ? osmo_bsslap_msgt_name(MSG_TYPE) : "", \</span><br><span style="color: hsl(120, 100%, 40%);">+ (IEI) >= 0 ? ": " : "", \</span><br><span style="color: hsl(120, 100%, 40%);">+ (IEI) >= 0 ? osmo_bsslap_iei_name(IEI) : "", \</span><br><span style="color: hsl(120, 100%, 40%);">+ (IEI) >= 0 ? " IE" : "", \</span><br><span style="color: hsl(120, 100%, 40%);">+##args), \</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 RC; \</span><br><span style="color: hsl(120, 100%, 40%);">+ } while(0)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static void osmo_bsslap_ie_enc_cell_id(struct msgb *msg, uint16_t cell_id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put_u8(msg, BSSLAP_IEI_CELL_ID);</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put_u16(msg, cell_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%);">+static int osmo_bsslap_ie_dec_cell_id(uint16_t *cell_id,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bsslap_msgt msgt, enum bsslap_iei iei,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_bsslap_err **err, void *err_ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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%);">+ DEC_ERR(-EINVAL, msgt, iei, LCS_CAUSE_UNSPECIFIED, "Expected 2 bytes, got %zu", len);</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 void osmo_bsslap_ie_enc_ta(struct msgb *msg, uint8_t ta)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put_u8(msg, BSSLAP_IEI_TA);</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put_u8(msg, ta);</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,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bsslap_msgt msgt, enum bsslap_iei iei,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_bsslap_err **err, void *err_ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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%);">+ DEC_ERR(-EINVAL, msgt, iei, LCS_CAUSE_UNSPECIFIED, "Expected 1 byte, got %zu", len);</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 void osmo_bsslap_ie_enc_cause(struct msgb *msg, enum 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, 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%);">+}</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 bsslap_cause *cause,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bsslap_msgt msgt, enum bsslap_iei iei,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_bsslap_err **err, void *err_ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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%);">+ DEC_ERR(-EINVAL, msgt, iei, LCS_CAUSE_UNSPECIFIED, "Expected 1 byte, got %zu", len);</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 void osmo_bsslap_ie_enc_chan_desc(struct msgb *msg, const struct gsm48_chan_desc *chan_desc)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm48_chan_desc *put_chan_desc;</span><br><span style="color: hsl(120, 100%, 40%);">+ msgb_put_u8(msg, BSSLAP_IEI_CHAN_DESC);</span><br><span style="color: hsl(120, 100%, 40%);">+ put_chan_desc = (void*)msgb_put(msg, sizeof(*chan_desc));</span><br><span style="color: hsl(120, 100%, 40%);">+ *put_chan_desc = *chan_desc;</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,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum bsslap_msgt msgt, enum bsslap_iei iei,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_bsslap_err **err, void *err_ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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%);">+ DEC_ERR(-EINVAL, msgt, iei, LCS_CAUSE_UNSPECIFIED, "Expected %zu bytes, got %zu",</span><br><span style="color: hsl(120, 100%, 40%);">+ sizeof(*chan_desc), len);</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%);">+/*! Encode BSSLAP PDU and append 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 bsslap_pdu *pdu)</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, pdu->msg_type);</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 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%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSLAP_MSGT_TA_RESPONSE:</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_cell_id(msg, pdu->ta_response.cell_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_ta(msg, pdu->ta_response.ta);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSLAP_MSGT_REJECT:</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_cause(msg, pdu->reject);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSLAP_MSGT_RESET:</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_cell_id(msg, pdu->reset.cell_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_ta(msg, pdu->reset.ta);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_chan_desc(msg, &pdu->reset.chan_desc);</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_cause(msg, pdu->reset.cause);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSLAP_MSGT_ABORT:</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_cause(msg, pdu->abort);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSLAP_MSGT_TA_LAYER3:</span><br><span style="color: hsl(120, 100%, 40%);">+ osmo_bsslap_ie_enc_ta(msg, pdu->ta_layer3.ta);</span><br><span style="color: hsl(120, 100%, 40%);">+ break;</span><br><span style="color: hsl(120, 100%, 40%);">+</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%);">+ 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%);">+/*! 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[out] err Returned pointer to error info, dynamically allocated; NULL to not return any.</span><br><span style="color: hsl(120, 100%, 40%);">+ * \param[in] err_ctx Talloc context to allocate err from, if required.</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 0 on success, negative on error.</span><br><span style="color: hsl(120, 100%, 40%);">+ */</span><br><span style="color: hsl(120, 100%, 40%);">+int osmo_bsslap_dec(struct bsslap_pdu *pdu,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_bsslap_err **err, void *err_ctx,</span><br><span style="color: hsl(120, 100%, 40%);">+ 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%);">+ 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%);">+ struct tlv_parsed tp;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ *pdu = (struct bsslap_pdu){};</span><br><span style="color: hsl(120, 100%, 40%);">+ if (err)</span><br><span style="color: hsl(120, 100%, 40%);">+ *err = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#define DEC_IE_MANDATORY(IEI, DEC_FUN, DEC_FUN_ARG) do { \</span><br><span style="color: hsl(120, 100%, 40%);">+ const struct tlv_p_entry *e; \</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc; \</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!(e = TLVP_GET(&tp, IEI))) \</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_ERR(-EINVAL, pdu->msg_type, IEI, LCS_CAUSE_DATA_MISSING_IN_REQ, "missing mandatory IE"); \</span><br><span style="color: hsl(120, 100%, 40%);">+ rc = DEC_FUN(DEC_FUN_ARG, pdu->msg_type, IEI, err, err_ctx, e->val, e->len); \</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc) \</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_ERR(rc, pdu->msg_type, IEI, LCS_CAUSE_UNSPECIFIED, "cannot parse IE"); \</span><br><span style="color: hsl(120, 100%, 40%);">+ } while (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%);">+ DEC_ERR(-EINVAL, -1, -1, LCS_CAUSE_UNSPECIFIED, "PDU too short: %zu b", len);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ pdu->msg_type = data[0];</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (pdu->msg_type == 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 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%);">+ 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%);">+ DEC_ERR(-EINVAL, pdu->msg_type, -1, LCS_CAUSE_UNSPECIFIED, "failed to parse TLV structure");</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ case BSSLAP_MSGT_TA_RESPONSE:</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_CELL_ID, osmo_bsslap_ie_dec_cell_id, &pdu->ta_response.cell_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_TA, osmo_bsslap_ie_dec_ta, &pdu->ta_response.ta);</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%);">+ case BSSLAP_MSGT_REJECT:</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_CAUSE, osmo_bsslap_ie_dec_cause, &pdu->reject);</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%);">+ case BSSLAP_MSGT_RESET:</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_CELL_ID, osmo_bsslap_ie_dec_cell_id, &pdu->reset.cell_id);</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_TA, osmo_bsslap_ie_dec_ta, &pdu->reset.ta);</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_CHAN_DESC, osmo_bsslap_ie_dec_chan_desc, &pdu->reset.chan_desc);</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_CAUSE, osmo_bsslap_ie_dec_cause, &pdu->reset.cause);</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%);">+ case BSSLAP_MSGT_ABORT:</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_CAUSE, osmo_bsslap_ie_dec_cause, &pdu->abort);</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%);">+ case BSSLAP_MSGT_TA_LAYER3:</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_IE_MANDATORY(BSSLAP_IEI_TA, osmo_bsslap_ie_dec_ta, &pdu->ta_layer3.ta);</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%);">+ default:</span><br><span style="color: hsl(120, 100%, 40%);">+ DEC_ERR(-EINVAL, pdu->msg_type, -1, LCS_CAUSE_UNSPECIFIED, "Unsupported 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%);">+</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%);">+ { BSSLAP_MSGT_TA_REQUEST, "TA Request" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_TA_RESPONSE, "TA Response" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_REJECT, "Reject" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_RESET, "Reset" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_ABORT, "Abort" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_TA_LAYER3, "TA Layer3" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_MS_POS_CMD, "MS Position Command" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_MS_POS_RESP, "MS Position Response" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_UTDOA_REQ, "U-TDOA Request" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_MSGT_UTDOA_RESP, "U-TDOA Response" },</span><br><span style="color: hsl(120, 100%, 40%);">+ {}</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+const struct value_string osmo_bsslap_iei_names[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_TA, "Timing Advance" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_CELL_ID, "Cell Identity" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_CHAN_DESC, "Channel Description" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_MEAS_REP, "Measurement Report" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_CAUSE, "Cause" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_RRLP_FLAG, "RRLP Flag" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_RRLP, "RRLP" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_CELL_ID_LIST, "Cell Identity List" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_ENH_MEAS_REP, "Enhanced Measurement Report" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_LAC, "Location Area Code" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_FREQ_LIST, "Frequency List" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_MS_POWER, "MS Power" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_DELTA_TIMER, "Delta Timer" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_SERVING_CELL_ID, "Serving Cell Identifier" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_ENCR_KEY, "Encryption Key" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_CIPH_MODE_SET, "Cipher Mode Setting" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_CHAN_MODE, "Channel Mode" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_MR_CONFIG, "MultiRate Configuration" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_POLLING_REPETITION, "Polling Repetition" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_PACKET_CHAN_DESC, "Packet Channel Description" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_TLLI, "TLLI" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_TFI, "TFI" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_TBF_START_TIME, "TBF Starting Time" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_PWRUP_START_TIME, "Powerup Starting Time" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_LONG_ENCR_KEY, "Long Encryption Key" },</span><br><span style="color: hsl(120, 100%, 40%);">+ { BSSLAP_IEI_CONCUR_POS_PROC_F, "Concurrent Positioning Flag" },</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 c4e6b9f..fc99485 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..43ea0d4</span><br><span>--- /dev/null</span><br><span>+++ b/tests/bsslap/bsslap_test.c</span><br><span>@@ -0,0 +1,103 @@</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/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%);">+struct 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 = 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 = 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 = BSSLAP_MSGT_REJECT,</span><br><span style="color: hsl(120, 100%, 40%);">+ .reject = 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 = 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 = 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 = BSSLAP_MSGT_ABORT,</span><br><span style="color: hsl(120, 100%, 40%);">+ .abort = 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 = 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 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 bsslap_pdu dec_pdu;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct osmo_bsslap_err *err;</span><br><span style="color: hsl(120, 100%, 40%);">+ int rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ void *loop_ctx = msg;</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%);">+ rc = osmo_bsslap_dec(&dec_pdu, &err, loop_ctx, msg->data, msg->len);</span><br><span style="color: hsl(120, 100%, 40%);">+ if (rc) {</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), err->logmsg);</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..f3199e1</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 e29c131..0923c25 100644</span><br><span>--- a/tests/testsuite.at</span><br><span>+++ b/tests/testsuite.at</span><br><span>@@ -409,3 +409,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: 5 </div>
<div style="display:none"> Gerrit-Owner: neels <nhofmeyr@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: neels <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: pespin <pespin@sysmocom.de> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>