gsm: Introduce API osmo_gsm48_rest_octets_si13_decode

Related: SYS#5358
Change-Id: I74fb0a3afc1ac4aadbfc609b882d929401f790eb
diff --git a/tests/gsm48/rest_octets_test.c b/tests/gsm48/rest_octets_test.c
new file mode 100644
index 0000000..beff6e4
--- /dev/null
+++ b/tests/gsm48/rest_octets_test.c
@@ -0,0 +1,120 @@
+/*
+ * (C) 2021 by sysmocom - s.m.f.c. GmbH <info@sysmocom.de>
+ * Author: Pau Espin Pedrol <pespin@sysmocom.de>
+ * All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm48_rest_octets.h>
+
+struct si13_test {
+	const char *name;
+	const struct osmo_gsm48_si13_info si;
+	int enc_rc;
+	int dec_rc;
+	void (*post_dec_cb)(const struct si13_test *test, const struct osmo_gsm48_si13_info* dec);
+};
+
+void post_dec_cb_test_alpha(const struct si13_test *test, const struct osmo_gsm48_si13_info* dec)
+{
+	OSMO_ASSERT(test->si.pwr_ctrl_pars.alpha == dec->pwr_ctrl_pars.alpha);
+}
+
+static const struct si13_test test_si13_arr[] = {
+	{
+		.name = "test alpha",
+		.si = {
+			.cell_opts = {
+				.nmo 		= GPRS_NMO_II,
+				.t3168		= 2000,
+				.t3192		= 1500,
+				.drx_timer_max	= 3,
+				.bs_cv_max	= 15,
+				.ctrl_ack_type_use_block = true,
+				.ext_info_present = 0,
+				.ext_info = {
+					.egprs_supported = 1,
+					.use_egprs_p_ch_req = 1,
+					.bep_period = 5,
+					.pfc_supported = 0,
+					.dtm_supported = 0,
+					.bss_paging_coordination = 0,
+					.ccn_active = true,
+				},
+			},
+			.pwr_ctrl_pars = {
+				.alpha		= 5,
+				.t_avg_w	= 16,
+				.t_avg_t	= 16,
+				.pc_meas_chan	= 0,
+				.n_avg_i	= 8,
+			},
+			.bcch_change_mark	= 1,
+			.si_change_field	= 0,
+			.rac		= 0x03,
+			.spgc_ccch_sup 	= 0,
+			.net_ctrl_ord	= 0,
+			.prio_acc_thr	= 6,
+		},
+		.enc_rc = 20,
+		.dec_rc = 71,
+		.post_dec_cb = post_dec_cb_test_alpha,
+	},
+};
+
+static void test_si13()
+{
+	int i, rc;
+	uint8_t data[GSM_MACBLOCK_LEN];
+	struct osmo_gsm48_si13_info si13;
+
+	for (i = 0; i < ARRAY_SIZE(test_si13_arr); i++) {
+		memset(data, 0, sizeof(data));
+		rc = osmo_gsm48_rest_octets_si13_encode(data, &test_si13_arr[i].si);
+		if (rc >= 0) {
+			printf("si13_encode (%d): %s\n", rc, osmo_hexdump(data, rc));
+		} else {
+			printf("si13_encode failed (%d)\n", rc);
+		}
+		OSMO_ASSERT(rc == test_si13_arr[i].enc_rc);
+		if (rc <= 0)
+			continue;
+		memset(&si13, 0 , sizeof(si13));
+		rc = osmo_gsm48_rest_octets_si13_decode(&si13, data);
+		if (rc >= 0) {
+			printf("si13_decode (%d)\n", rc);
+		} else {
+			printf("si13_decode failed (%d)\n", rc);
+		}
+		OSMO_ASSERT(rc == test_si13_arr[i].dec_rc);
+		if (test_si13_arr[i].post_dec_cb) {
+			test_si13_arr[i].post_dec_cb(&test_si13_arr[i], &si13);
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	test_si13();
+
+	return EXIT_SUCCESS;
+}