[PATCH] libosmocore[master]: Add octet-aligned/unaligned shift functions

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/gerrit-log@lists.osmocom.org/.

Max gerrit-no-reply at lists.osmocom.org
Mon Jun 20 16:15:23 UTC 2016


Hello Harald Welte, Jenkins Builder,

I'd like you to reexamine a change.  Please visit

    https://gerrit.osmocom.org/326

to look at the new patch set (#2).

Add octet-aligned/unaligned shift functions

The actual code is from OsmoBTS' tch.c by Harald Welte. Add unit tests
and doxygen annotation. Those functions are used in several BTS
implementations but seems generic enough to be generally useful.

Change-Id: I2b1901c4161e8035f059585901dca593b661556d
---
M include/osmocom/core/bits.h
M src/bits.c
M tests/bits/bitrev_test.c
M tests/bits/bitrev_test.ok
4 files changed, 179 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.osmocom.org:29418/libosmocore refs/changes/26/326/2

diff --git a/include/osmocom/core/bits.h b/include/osmocom/core/bits.h
index 3218330..5535920 100644
--- a/include/osmocom/core/bits.h
+++ b/include/osmocom/core/bits.h
@@ -41,6 +41,11 @@
 
 int osmo_pbit2ubit(ubit_t *out, const pbit_t *in, unsigned int num_bits);
 
+void osmo_nibble_shift_right(uint8_t *out, const uint8_t *in,
+			     unsigned int num_nibbles);
+void osmo_nibble_shift_left_unal(uint8_t *out, const uint8_t *in,
+				 unsigned int num_nibbles);
+
 void osmo_ubit2sbit(sbit_t *out, const ubit_t *in, unsigned int num_bits);
 void osmo_sbit2ubit(ubit_t *out, const sbit_t *in, unsigned int num_bits);
 
diff --git a/src/bits.c b/src/bits.c
index 569a10f..613e258 100644
--- a/src/bits.c
+++ b/src/bits.c
@@ -61,6 +61,50 @@
 	return outptr - out;
 }
 
+/*! \brief Shift unaligned input to octet-aligned output
+ *  \param[out] out output buffer, unaligned
+ *  \param[in] in input buffer, octet-aligned
+ *  \param[in] num_nibbles number of nibbles
+ */
+void osmo_nibble_shift_right(uint8_t *out, const uint8_t *in,
+			     unsigned int num_nibbles)
+{
+	unsigned int i, num_whole_bytes = num_nibbles / 2;
+
+	/* first byte: upper nibble empty, lower nibble from src */
+	out[0] = (in[0] >> 4);
+
+	/* bytes 1.. */
+	for (i = 1; i < num_whole_bytes; i++)
+		out[i] = ((in[i - 1] & 0xF) << 4) | (in[i] >> 4);
+
+	/* shift the last nibble, in case there's an odd count */
+	i = num_whole_bytes;
+	if (num_nibbles & 1)
+		out[i] = ((in[i - 1] & 0xF) << 4) | (in[i] >> 4);
+	else
+		out[i] = (in[i - 1] & 0xF) << 4;
+}
+
+/*! \brief Shift unaligned input to octet-aligned output
+ *  \param[out] out output buffer, octet-aligned
+ *  \param[in] in input buffer, unaligned
+ *  \param[in] num_nibbles number of nibbles
+ */
+void osmo_nibble_shift_left_unal(uint8_t *out, const uint8_t *in,
+				unsigned int num_nibbles)
+{
+	unsigned int i, num_whole_bytes = num_nibbles / 2;
+
+	for (i = 0; i < num_whole_bytes; i++)
+		out[i] = ((in[i] & 0xF) << 4) | (in[i + 1] >> 4);
+
+	/* shift the last nibble, in case there's an odd count */
+	i = num_whole_bytes;
+	if (num_nibbles & 1)
+		out[i] = (in[i] & 0xF) << 4;
+}
+
 /*! \brief convert unpacked bits to soft bits
  *  \param[out] out output buffer of soft bits
  *  \param[in] in input buffer of unpacked bits
diff --git a/tests/bits/bitrev_test.c b/tests/bits/bitrev_test.c
index 987f4d5..36c9925 100644
--- a/tests/bits/bitrev_test.c
+++ b/tests/bits/bitrev_test.c
@@ -205,6 +205,20 @@
 	printcheck16(e, test, test, (BE == e) ? s : NULL, print);
 }
 
+static void sh_chk(const uint8_t *in, size_t len, unsigned int nib, bool r)
+{
+	uint8_t x[len];
+	if (r)
+		osmo_nibble_shift_right(x, in, nib);
+	else
+		osmo_nibble_shift_left_unal(x, in, nib);
+
+	printf("[%u] %s IN: %s, nibble %u:", len, r ? "R" : "L",
+	       osmo_hexdump_nospc(in, len), nib);
+	/* do NOT combine those printfs: osmo_hexdump* use static buffer which
+	   WILL screw things up in that case */
+	printf("\n     OUT: %s\n", osmo_hexdump_nospc(x, nib/2));
+}
 
 int main(int argc, char **argv)
 {
@@ -274,5 +288,16 @@
 	check16(0, BE);
 	check16(0, LE);
 
+	printf("running nibble tests...\n");
+
+	const uint8_t in1[] = { 0xF0, 0x0D, 0xCA, 0xFE, 0xDE, 0xAD, 0xBE, 0xEF },
+		      in2[] = { 0xB0, 0x0B, 0xBA, 0xBE, 0xFA, 0xCE };
+
+	for (offs = 0; offs < 13; offs++) {
+		sh_chk(in1, ARRAY_SIZE(in1), offs, true);
+		sh_chk(in1, ARRAY_SIZE(in1), offs, false);
+		sh_chk(in2, ARRAY_SIZE(in2), offs, true);
+		sh_chk(in2, ARRAY_SIZE(in2), offs, false);
+	}
 	return 0;
 }
diff --git a/tests/bits/bitrev_test.ok b/tests/bits/bitrev_test.ok
index 90cb295..9fbb4d9 100644
--- a/tests/bits/bitrev_test.ok
+++ b/tests/bits/bitrev_test.ok
@@ -53,3 +53,108 @@
 24 LE OK
 16 BE OK, storage OK
 16 LE OK
+running nibble tests...
+[8] R IN: f00dcafedeadbeef, nibble 0:
+     OUT: 
+[8] L IN: f00dcafedeadbeef, nibble 0:
+     OUT: 
+[6] R IN: b00bbabeface, nibble 0:
+     OUT: 
+[6] L IN: b00bbabeface, nibble 0:
+     OUT: 
+[8] R IN: f00dcafedeadbeef, nibble 1:
+     OUT: 
+[8] L IN: f00dcafedeadbeef, nibble 1:
+     OUT: 
+[6] R IN: b00bbabeface, nibble 1:
+     OUT: 
+[6] L IN: b00bbabeface, nibble 1:
+     OUT: 
+[8] R IN: f00dcafedeadbeef, nibble 2:
+     OUT: 0f
+[8] L IN: f00dcafedeadbeef, nibble 2:
+     OUT: 00
+[6] R IN: b00bbabeface, nibble 2:
+     OUT: 0b
+[6] L IN: b00bbabeface, nibble 2:
+     OUT: 00
+[8] R IN: f00dcafedeadbeef, nibble 3:
+     OUT: 0f
+[8] L IN: f00dcafedeadbeef, nibble 3:
+     OUT: 00
+[6] R IN: b00bbabeface, nibble 3:
+     OUT: 0b
+[6] L IN: b00bbabeface, nibble 3:
+     OUT: 00
+[8] R IN: f00dcafedeadbeef, nibble 4:
+     OUT: 0f00
+[8] L IN: f00dcafedeadbeef, nibble 4:
+     OUT: 00dc
+[6] R IN: b00bbabeface, nibble 4:
+     OUT: 0b00
+[6] L IN: b00bbabeface, nibble 4:
+     OUT: 00bb
+[8] R IN: f00dcafedeadbeef, nibble 5:
+     OUT: 0f00
+[8] L IN: f00dcafedeadbeef, nibble 5:
+     OUT: 00dc
+[6] R IN: b00bbabeface, nibble 5:
+     OUT: 0b00
+[6] L IN: b00bbabeface, nibble 5:
+     OUT: 00bb
+[8] R IN: f00dcafedeadbeef, nibble 6:
+     OUT: 0f00dc
+[8] L IN: f00dcafedeadbeef, nibble 6:
+     OUT: 00dcaf
+[6] R IN: b00bbabeface, nibble 6:
+     OUT: 0b00bb
+[6] L IN: b00bbabeface, nibble 6:
+     OUT: 00bbab
+[8] R IN: f00dcafedeadbeef, nibble 7:
+     OUT: 0f00dc
+[8] L IN: f00dcafedeadbeef, nibble 7:
+     OUT: 00dcaf
+[6] R IN: b00bbabeface, nibble 7:
+     OUT: 0b00bb
+[6] L IN: b00bbabeface, nibble 7:
+     OUT: 00bbab
+[8] R IN: f00dcafedeadbeef, nibble 8:
+     OUT: 0f00dcaf
+[8] L IN: f00dcafedeadbeef, nibble 8:
+     OUT: 00dcafed
+[6] R IN: b00bbabeface, nibble 8:
+     OUT: 0b00bbab
+[6] L IN: b00bbabeface, nibble 8:
+     OUT: 00bbabef
+[8] R IN: f00dcafedeadbeef, nibble 9:
+     OUT: 0f00dcaf
+[8] L IN: f00dcafedeadbeef, nibble 9:
+     OUT: 00dcafed
+[6] R IN: b00bbabeface, nibble 9:
+     OUT: 0b00bbab
+[6] L IN: b00bbabeface, nibble 9:
+     OUT: 00bbabef
+[8] R IN: f00dcafedeadbeef, nibble 10:
+     OUT: 0f00dcafed
+[8] L IN: f00dcafedeadbeef, nibble 10:
+     OUT: 00dcafedea
+[6] R IN: b00bbabeface, nibble 10:
+     OUT: 0b00bbabef
+[6] L IN: b00bbabeface, nibble 10:
+     OUT: 00bbabefac
+[8] R IN: f00dcafedeadbeef, nibble 11:
+     OUT: 0f00dcafed
+[8] L IN: f00dcafedeadbeef, nibble 11:
+     OUT: 00dcafedea
+[6] R IN: b00bbabeface, nibble 11:
+     OUT: 0b00bbabef
+[6] L IN: b00bbabeface, nibble 11:
+     OUT: 00bbabefac
+[8] R IN: f00dcafedeadbeef, nibble 12:
+     OUT: 0f00dcafedea
+[8] L IN: f00dcafedeadbeef, nibble 12:
+     OUT: 00dcafedeadb
+[6] R IN: b00bbabeface, nibble 12:
+     OUT: 0b00bbabefac
+[6] L IN: b00bbabeface, nibble 12:
+     OUT: 00bbabeface0

-- 
To view, visit https://gerrit.osmocom.org/326
To unsubscribe, visit https://gerrit.osmocom.org/settings

Gerrit-MessageType: newpatchset
Gerrit-Change-Id: I2b1901c4161e8035f059585901dca593b661556d
Gerrit-PatchSet: 2
Gerrit-Project: libosmocore
Gerrit-Branch: master
Gerrit-Owner: Max <msuraev at sysmocom.de>
Gerrit-Reviewer: Harald Welte <laforge at gnumonks.org>
Gerrit-Reviewer: Holger Freyther <holger at freyther.de>
Gerrit-Reviewer: Jenkins Builder



More information about the gerrit-log mailing list