1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
/*
* conv_rach.c
*
* Convolutional code tables for RACH channels
*
* Copyright (C) 2011 Sylvain Munaut <tnt@246tNt.com>
*/
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <osmocom/core/bits.h>
#include <osmocom/core/conv.h>
#include <osmocom/core/crcgen.h>
#include "rach.h"
/*
* GSM RACH parity
*
* g(x) = x^6 + x^5 + x^3 + x^2 + x^1 + 1
*/
static const struct osmo_crc8gen_code rach_crc6 = {
.bits = 6,
.poly = 0x2f,
.init = 0x00,
.remainder = 0x3f,
};
/*
* GSM RACH convolutional coding
*
* G_0 = 1 + x^3 + x^4
* G_1 = 1 + x + x^3 + x^4
*/
static const uint8_t conv_rach_next_output[][2] = {
{ 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
{ 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
{ 3, 0 }, { 2, 1 }, { 3, 0 }, { 2, 1 },
{ 0, 3 }, { 1, 2 }, { 0, 3 }, { 1, 2 },
};
static const uint8_t conv_rach_next_state[][2] = {
{ 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
{ 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
{ 0, 1 }, { 2, 3 }, { 4, 5 }, { 6, 7 },
{ 8, 9 }, { 10, 11 }, { 12, 13 }, { 14, 15 },
};
const struct osmo_conv_code conv_rach = {
.N = 2,
.K = 5,
.len = 14,
.next_output = conv_rach_next_output,
.next_state = conv_rach_next_state,
};
/*
* GSM RACH apply BSIC to parity
*
* p(j) = p(j) xor b(j) j = 0, ..., 5
* b(0) = MSB of PLMN colour code
* b(5) = LSB of BS colour code
*/
static int
rach_apply_bsic(ubit_t *d, uint8_t bsic)
{
int i;
/* Apply it */
for (i=0; i<6; i++)
d[8+i] ^= ((bsic >> (5-i)) & 1);
return 0;
}
int
rach_decode(uint8_t *ra, sbit_t *burst, uint8_t bsic)
{
ubit_t conv[14];
int rv;
osmo_conv_decode(&conv_rach, burst, conv);
rach_apply_bsic(conv, bsic);
rv = osmo_crc8gen_check_bits(&rach_crc6, conv, 8, conv+8);
if (rv)
return -1;
osmo_ubit2pbit_ext(ra, 0, conv, 0, 8, 1);
return 0;
}
int
rach_encode(ubit_t *burst, uint8_t *ra, uint8_t bsic)
{
ubit_t conv[14];
osmo_pbit2ubit_ext(conv, 0, ra, 0, 8, 1);
osmo_crc8gen_set_bits(&rach_crc6, conv, 8, conv+8);
rach_apply_bsic(conv, bsic);
osmo_conv_encode(&conv_rach, conv, burst);
return 0;
}
|