aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-trx/rach.c
blob: 670a4d1dace1d7dd1bb9cf29fb0e91cc751e85c0 (plain)
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;
}