mirror of https://gerrit.osmocom.org/libosmocore
Add pseudo-random bit sequence generator to libosmcoore
These PRBS sequences are specified in ITU-T O.150. They are typically used as test data to be transmitted for BER (bit error rate) testing. Change-Id: I227b6a6e86a251460ecb816afa9a7439d5fb94d1changes/62/3162/4
parent
548e371200
commit
1389e86d11
|
@ -31,6 +31,7 @@ nobase_include_HEADERS = \
|
|||
osmocom/core/macaddr.h \
|
||||
osmocom/core/msgb.h \
|
||||
osmocom/core/panic.h \
|
||||
osmocom/core/prbs.h \
|
||||
osmocom/core/prim.h \
|
||||
osmocom/core/process.h \
|
||||
osmocom/core/rate_ctr.h \
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <osmocom/core/bits.h>
|
||||
|
||||
/*! \brief definition of a PRBS sequence */
|
||||
struct osmo_prbs {
|
||||
const char *name; /*!< human-readable name */
|
||||
unsigned int len; /*!< length in bits */
|
||||
uint64_t coeff; /*!< coefficients */
|
||||
};
|
||||
|
||||
/*! \brief state of a given PRBS sequence generator */
|
||||
struct osmo_prbs_state {
|
||||
const struct osmo_prbs *prbs;
|
||||
uint64_t state;
|
||||
};
|
||||
|
||||
extern const struct osmo_prbs osmo_prbs7;
|
||||
extern const struct osmo_prbs osmo_prbs9;
|
||||
extern const struct osmo_prbs osmo_prbs11;
|
||||
extern const struct osmo_prbs osmo_prbs15;
|
||||
|
||||
void osmo_prbs_state_init(struct osmo_prbs_state *st, const struct osmo_prbs *prbs);
|
||||
ubit_t osmo_prbs_get_ubit(struct osmo_prbs_state *state);
|
||||
int osmo_prbs_get_ubits(ubit_t *out, unsigned int out_len, struct osmo_prbs_state *state);
|
|
@ -21,7 +21,7 @@ libosmocore_la_SOURCES = timer.c timer_gettimeofday.c select.c signal.c msgb.c b
|
|||
conv.c application.c rbtree.c strrb.c \
|
||||
loggingrb.c crc8gen.c crc16gen.c crc32gen.c crc64gen.c \
|
||||
macaddr.c stat_item.c stats.c stats_statsd.c prim.c \
|
||||
conv_acc.c conv_acc_generic.c sercomm.c
|
||||
conv_acc.c conv_acc_generic.c sercomm.c prbs.c
|
||||
|
||||
if HAVE_SSE3
|
||||
libosmocore_la_SOURCES += conv_acc_sse.c
|
||||
|
|
|
@ -0,0 +1,74 @@
|
|||
/* Osmocom implementation of pseudo-random bit sequence generation */
|
||||
/* (C) 2017 by Harald Welte <laforge@gnumonks.org> */
|
||||
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <osmocom/core/bits.h>
|
||||
#include <osmocom/core/prbs.h>
|
||||
|
||||
/*! \brief PRBS-7 according ITU-T O.150 */
|
||||
const struct osmo_prbs osmo_prbs7 = {
|
||||
/* x^7 + x^6 + 1 */
|
||||
.name = "PRBS-7",
|
||||
.len = 7,
|
||||
.coeff = (1<<6) | (1<<5),
|
||||
};
|
||||
|
||||
/*! \brief PRBS-9 according ITU-T O.150 */
|
||||
const struct osmo_prbs osmo_prbs9 = {
|
||||
/* x^9 + x^5 + 1 */
|
||||
.name = "PRBS-9",
|
||||
.len = 9,
|
||||
.coeff = (1<<8) | (1<<4),
|
||||
};
|
||||
|
||||
/*! \brief PRBS-11 according ITU-T O.150 */
|
||||
const struct osmo_prbs osmo_prbs11 = {
|
||||
/* x^11 + x^9 + 1 */
|
||||
.name = "PRBS-11",
|
||||
.len = 11,
|
||||
.coeff = (1<<10) | (1<<8),
|
||||
};
|
||||
|
||||
/*! \brief PRBS-15 according ITU-T O.150 */
|
||||
const struct osmo_prbs osmo_prbs15 = {
|
||||
/* x^15 + x^14+ 1 */
|
||||
.name = "PRBS-15",
|
||||
.len = 15,
|
||||
.coeff = (1<<14) | (1<<13),
|
||||
};
|
||||
|
||||
/*! \brief Initialize the given caller-allocated PRBS state */
|
||||
void osmo_prbs_state_init(struct osmo_prbs_state *st, const struct osmo_prbs *prbs)
|
||||
{
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->prbs = prbs;
|
||||
st->state = 1;
|
||||
}
|
||||
|
||||
static void osmo_prbs_process_bit(struct osmo_prbs_state *state, ubit_t bit)
|
||||
{
|
||||
state->state >>= 1;
|
||||
if (bit)
|
||||
state->state ^= state->prbs->coeff;
|
||||
}
|
||||
|
||||
/*! \brief Get the next bit out of given PRBS instance */
|
||||
ubit_t osmo_prbs_get_ubit(struct osmo_prbs_state *state)
|
||||
{
|
||||
ubit_t result = state->state & 0x1;
|
||||
osmo_prbs_process_bit(state, result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/*! \brief Fill buffer of unpacked bits with next bits out of given PRBS instance */
|
||||
int osmo_prbs_get_ubits(ubit_t *out, unsigned int out_len, struct osmo_prbs_state *state)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < out_len; i++)
|
||||
out[i] = osmo_prbs_get_ubit(state);
|
||||
|
||||
return i;
|
||||
}
|
|
@ -15,7 +15,7 @@ check_PROGRAMS = timer/timer_test sms/sms_test ussd/ussd_test \
|
|||
write_queue/wqueue_test socket/socket_test \
|
||||
coding/coding_test conv/conv_gsm0503_test \
|
||||
abis/abis_test endian/endian_test sercomm/sercomm_test \
|
||||
stats/stats_test
|
||||
stats/stats_test prbs/prbs_test
|
||||
|
||||
if ENABLE_MSGFILE
|
||||
check_PROGRAMS += msgfile/msgfile_test
|
||||
|
@ -183,6 +183,9 @@ endian_endian_test_LDADD = $(top_builddir)/src/libosmocore.la
|
|||
sercomm_sercomm_test_SOURCES = sercomm/sercomm_test.c
|
||||
sercomm_sercomm_test_LDADD = $(top_builddir)/src/libosmocore.la
|
||||
|
||||
prbs_prbs_test_SOURCES = prbs/prbs_test.c
|
||||
prbs_prbs_test_LDADD = $(top_builddir)/src/libosmocore.la
|
||||
|
||||
# The `:;' works around a Bash 3.2 bug when the output is not writeable.
|
||||
$(srcdir)/package.m4: $(top_srcdir)/configure.ac
|
||||
:;{ \
|
||||
|
@ -226,7 +229,7 @@ EXTRA_DIST = testsuite.at $(srcdir)/package.m4 $(TESTSUITE) \
|
|||
osmo-auc-gen/osmo-auc-gen_test.ok \
|
||||
osmo-auc-gen/osmo-auc-gen_test.err \
|
||||
conv/conv_gsm0503_test.ok endian/endian_test.ok \
|
||||
sercomm/sercomm_test.ok
|
||||
sercomm/sercomm_test.ok prbs/prbs_test.ok
|
||||
|
||||
DISTCLEANFILES = atconfig atlocal conv/gsm0503_test_vectors.c
|
||||
BUILT_SOURCES = conv/gsm0503_test_vectors.c
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <osmocom/core/prbs.h>
|
||||
|
||||
static void dump_bits(const ubit_t *bits, unsigned int num_bits)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < num_bits; i++) {
|
||||
if (bits[i])
|
||||
fputc('1', stdout);
|
||||
else
|
||||
fputc('0', stdout);
|
||||
}
|
||||
fputc('\n',stdout);
|
||||
}
|
||||
|
||||
static void test_prbs(const struct osmo_prbs *prbs)
|
||||
{
|
||||
struct osmo_prbs_state st;
|
||||
unsigned int i;
|
||||
|
||||
printf("Testing PRBS sequence generation '%s'\n", prbs->name);
|
||||
osmo_prbs_state_init(&st, prbs);
|
||||
|
||||
/* 2 lines */
|
||||
for (i = 0; i < 2; i++) {
|
||||
unsigned int seq_len = (1 << prbs->len)-1;
|
||||
ubit_t bits[seq_len];
|
||||
memset(bits, 0, sizeof(bits));
|
||||
osmo_prbs_get_ubits(bits, sizeof(bits), &st);
|
||||
dump_bits(bits, sizeof(bits));
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
test_prbs(&osmo_prbs7);
|
||||
test_prbs(&osmo_prbs9);
|
||||
test_prbs(&osmo_prbs11);
|
||||
test_prbs(&osmo_prbs15);
|
||||
|
||||
exit(0);
|
||||
}
|
File diff suppressed because one or more lines are too long
|
@ -280,3 +280,9 @@ AT_KEYWORDS([sercomm])
|
|||
cat $abs_srcdir/sercomm/sercomm_test.ok > expout
|
||||
AT_CHECK([$abs_top_builddir/tests/sercomm/sercomm_test], [0], [expout], [ignore])
|
||||
AT_CLEANUP
|
||||
|
||||
AT_SETUP([prbs])
|
||||
AT_KEYWORDS([prbs])
|
||||
cat $abs_srcdir/prbs/prbs_test.ok > expout
|
||||
AT_CHECK([$abs_top_builddir/tests/prbs/prbs_test], [0], [expout], [ignore])
|
||||
AT_CLEANUP
|
||||
|
|
Loading…
Reference in New Issue