Harald Welte | 1389e86 | 2017-06-18 18:16:02 +0300 | [diff] [blame] | 1 | /* Osmocom implementation of pseudo-random bit sequence generation */ |
Harald Welte | e08da97 | 2017-11-13 01:00:26 +0900 | [diff] [blame] | 2 | /* (C) 2017 by Harald Welte <laforge@gnumonks.org> |
| 3 | * All Rights Reserved |
| 4 | * |
| 5 | * SPDX-License-Identifier: GPL-2.0+ |
| 6 | * */ |
Harald Welte | 1389e86 | 2017-06-18 18:16:02 +0300 | [diff] [blame] | 7 | |
| 8 | #include <stdint.h> |
| 9 | #include <string.h> |
| 10 | #include <osmocom/core/bits.h> |
| 11 | #include <osmocom/core/prbs.h> |
| 12 | |
| 13 | /*! \brief PRBS-7 according ITU-T O.150 */ |
| 14 | const struct osmo_prbs osmo_prbs7 = { |
| 15 | /* x^7 + x^6 + 1 */ |
| 16 | .name = "PRBS-7", |
| 17 | .len = 7, |
| 18 | .coeff = (1<<6) | (1<<5), |
| 19 | }; |
| 20 | |
| 21 | /*! \brief PRBS-9 according ITU-T O.150 */ |
| 22 | const struct osmo_prbs osmo_prbs9 = { |
| 23 | /* x^9 + x^5 + 1 */ |
| 24 | .name = "PRBS-9", |
| 25 | .len = 9, |
| 26 | .coeff = (1<<8) | (1<<4), |
| 27 | }; |
| 28 | |
| 29 | /*! \brief PRBS-11 according ITU-T O.150 */ |
| 30 | const struct osmo_prbs osmo_prbs11 = { |
| 31 | /* x^11 + x^9 + 1 */ |
| 32 | .name = "PRBS-11", |
| 33 | .len = 11, |
| 34 | .coeff = (1<<10) | (1<<8), |
| 35 | }; |
| 36 | |
| 37 | /*! \brief PRBS-15 according ITU-T O.150 */ |
| 38 | const struct osmo_prbs osmo_prbs15 = { |
| 39 | /* x^15 + x^14+ 1 */ |
| 40 | .name = "PRBS-15", |
| 41 | .len = 15, |
| 42 | .coeff = (1<<14) | (1<<13), |
| 43 | }; |
| 44 | |
| 45 | /*! \brief Initialize the given caller-allocated PRBS state */ |
| 46 | void osmo_prbs_state_init(struct osmo_prbs_state *st, const struct osmo_prbs *prbs) |
| 47 | { |
| 48 | memset(st, 0, sizeof(*st)); |
| 49 | st->prbs = prbs; |
| 50 | st->state = 1; |
| 51 | } |
| 52 | |
| 53 | static void osmo_prbs_process_bit(struct osmo_prbs_state *state, ubit_t bit) |
| 54 | { |
| 55 | state->state >>= 1; |
| 56 | if (bit) |
| 57 | state->state ^= state->prbs->coeff; |
| 58 | } |
| 59 | |
| 60 | /*! \brief Get the next bit out of given PRBS instance */ |
| 61 | ubit_t osmo_prbs_get_ubit(struct osmo_prbs_state *state) |
| 62 | { |
| 63 | ubit_t result = state->state & 0x1; |
| 64 | osmo_prbs_process_bit(state, result); |
| 65 | |
| 66 | return result; |
| 67 | } |
| 68 | |
| 69 | /*! \brief Fill buffer of unpacked bits with next bits out of given PRBS instance */ |
| 70 | int osmo_prbs_get_ubits(ubit_t *out, unsigned int out_len, struct osmo_prbs_state *state) |
| 71 | { |
| 72 | unsigned int i; |
| 73 | |
| 74 | for (i = 0; i < out_len; i++) |
| 75 | out[i] = osmo_prbs_get_ubit(state); |
| 76 | |
| 77 | return i; |
| 78 | } |