aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-09-25 23:30:38 +0700
committerVadim Yanitskiy <vyanitskiy@sysmocom.de>2023-09-25 23:58:40 +0700
commit5285d475485f6414ca6afbdeb36c5f4c844517de (patch)
treea06e12788a613947c682eeae48632df833e9c1f6
parent433218a6ef5853f4d40a488d1a1e8b824eab2e7c (diff)
gsm: add gsm0502_fn_compare() for comparing TDMA FNs
We need this function in: * osmocom-bb.git for trxcon and l1gprs, * osmo-pcu.git replacing fn_cmp(). Change-Id: I9590f2e836fc48650decf1564b6ab46306c4fe2d Related: OS#5500
-rw-r--r--include/osmocom/gsm/gsm0502.h19
-rw-r--r--tests/gsm0502/gsm0502_test.c20
2 files changed, 39 insertions, 0 deletions
diff --git a/include/osmocom/gsm/gsm0502.h b/include/osmocom/gsm/gsm0502.h
index ffd6e20e..6624e705 100644
--- a/include/osmocom/gsm/gsm0502.h
+++ b/include/osmocom/gsm/gsm0502.h
@@ -64,6 +64,25 @@
#define GSM_NBITS_AB_GMSK_TAIL GSM_NBITS_NB_GMSK_TAIL
#define GSM_NBITS_AB_GMSK_BURST GSM_NBITS_NB_GMSK_BURST
+/*! Compare the given TDMA FNs, taking the wrapping into account.
+ * \param[in] fn1 First TDMA Fn value to compare.
+ * \param[in] fn2 Second TDMA Fn value to compare.
+ * \returns similarly to memcmp(), -1 if fn1 goes before fn2;
+ * 0 if fn1 equals fn2;
+ * 1 if fn1 goes after fn2. */
+static inline int gsm0502_fn_compare(uint32_t fn1, uint32_t fn2)
+{
+ const uint32_t thresh = GSM_TDMA_HYPERFRAME / 2;
+
+ if (fn1 == fn2)
+ return 0;
+ if ((fn1 < fn2 && (fn2 - fn1) < thresh) ||
+ (fn1 > fn2 && (fn1 - fn2) > thresh))
+ return -1;
+
+ return 1;
+}
+
/* Table 5 Clause 7 TS 05.02 */
static inline unsigned int
gsm0502_get_n_pag_blocks(const struct gsm48_control_channel_descr *chan_desc)
diff --git a/tests/gsm0502/gsm0502_test.c b/tests/gsm0502/gsm0502_test.c
index e9deaa9f..d78a94d5 100644
--- a/tests/gsm0502/gsm0502_test.c
+++ b/tests/gsm0502/gsm0502_test.c
@@ -148,8 +148,28 @@ static void test_gsm0502_fn_remap(void)
printf("\n");
}
+static void test_gsm0502_fn_compare(void)
+{
+ OSMO_ASSERT(gsm0502_fn_compare(1337, 1337) == 0);
+ OSMO_ASSERT(gsm0502_fn_compare(42, 1337) == -1);
+ OSMO_ASSERT(gsm0502_fn_compare(1337, 42) == 1);
+ OSMO_ASSERT(gsm0502_fn_compare(42, 0) == 1);
+
+ /* 2715642 is very close to the Fn period (GSM_TDMA_HYPERFRAME) */
+ OSMO_ASSERT(gsm0502_fn_compare(2715642, 42) == -1);
+ OSMO_ASSERT(gsm0502_fn_compare(42, 2715642) == 1);
+ OSMO_ASSERT(gsm0502_fn_compare(0, 2715642) == 1);
+
+ /* 1357824 is half of the Fn period (GSM_TDMA_HYPERFRAME) */
+ OSMO_ASSERT(gsm0502_fn_compare(1357820, 1357824) == -1);
+ OSMO_ASSERT(gsm0502_fn_compare(1357820, 1357825) == -1);
+ OSMO_ASSERT(gsm0502_fn_compare(1357824, 1357820) == 1);
+ OSMO_ASSERT(gsm0502_fn_compare(1357825, 1357820) == 1);
+}
+
int main(int argc, char **argv)
{
test_gsm0502_fn_remap();
+ test_gsm0502_fn_compare();
return EXIT_SUCCESS;
}