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