aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-trx/sched_utils.h
blob: 398083d9ef704138f79b65ee25aed2d58ceddf8a (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
119
120
121
122
123
124
125
126
127
128
129
130
/* Auxiliary scheduler utilities.
 *
 * (C) 2017 by Harald Welte <laforge@gnumonks.org>
 *
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 */

#pragma once

#include <stdint.h>
#include <errno.h>
#include <stdbool.h>
#include <osmo-bts/scheduler.h>

extern void *tall_bts_ctx;

/* Compute the bit error rate in 1/10000 units */
static inline uint16_t compute_ber10k(int n_bits_total, int n_errors)
{
	if (n_bits_total == 0)
		return 10000;
	else
		return 10000 * n_errors / n_bits_total;
}

/* 3GPP TS 45.009, table 3.2.1.3-{1,3}: AMR on Uplink TCH/F */
static const uint8_t sched_tchf_ul_amr_cmi_map[26] = {
	[7]  = 1, /* TCH/F: first=0  / last=7 */
	[16] = 1, /* TCH/F: first=8  / last=16 */
	[24] = 1, /* TCH/F: first=17 / last=24 */
};

/* 3GPP TS 45.009, table 3.2.1.3-{2,4}: AMR on Uplink TCH/H */
static const uint8_t sched_tchh_ul_amr_cmi_map[26] = {
	[6]  = 1, /* TCH/H(0): first=0  / last=6 */
	[15] = 1, /* TCH/H(0): first=8  / last=15 */
	[23] = 1, /* TCH/H(0): first=17 / last=23 */

	[7]  = 1, /* TCH/H(1): first=1  / last=7 */
	[16] = 1, /* TCH/H(1): first=9  / last=16 */
	[24] = 1, /* TCH/H(1): first=18 / last=24 */
};

/*! determine whether an uplink AMR block is CMI according to 3GPP TS 45.009.
 *  \param[in] fn_begin frame number of the beginning of the block.
 *  \returns true in case of CMI; false otherwise. */
static inline bool ul_amr_fn_is_cmi(uint32_t fn_begin)
{
	switch (fn_begin % 26) {
		/*! See also: 3GPP TS 45.009, section 3.2.1.3 Transmitter/Receiver Synchronisation */
		/* valid for AHS subslot 0 and AFS: */
	case 0:
	case 8:
	case 17:
		/* valid for AHS subslot 1: */
	case 1:
	case 9:
	case 18:
		return true;
		break;
		/* Complementary values for sanity check */
		/* valid for AHS subslot 0 and AFS: */
	case 4:
	case 13:
	case 21:
		/* valid for AHS subslot 1: */
	case 5:
	case 14:
	case 22:
		return false;
		break;
	default:
		LOGP(DL1P, LOGL_DEBUG,
		     "uplink frame number fn_begin=%u does not mark the beginning of a voice block!\n", fn_begin);
		OSMO_ASSERT(false);
		return false;
		break;
	}
}

/*! determine the whether a downlink AMR block is CMI according to 3GPP TS 45.009.
 *  \param[in] fn_begin frame number of the beginning of the block.
 *  \returns true in case of CMI; false otherwise. */
static inline bool dl_amr_fn_is_cmi(uint32_t fn_begin)
{
	switch (fn_begin % 26) {
		/*! See also: 3GPP TS 45.009, section 3.2.1.3 Transmitter/Receiver Synchronisation */
		/* valid for AHS subslot 0 and AFS: */
	case 4:
	case 13:
	case 21:
		/* valid for AHS subslot 1: */
	case 5:
	case 14:
	case 22:
		return true;
		break;
		/* Complementary values for sanity check */
		/* valid for AHS subslot 0 and AFS: */
	case 0:
	case 8:
	case 17:
		/* valid for AHS subslot 1: */
	case 1:
	case 9:
	case 18:
		return false;
		break;
	default:
		LOGP(DL1P, LOGL_DEBUG,
		     "downlink frame number fn_begin=%u does not mark the beginning of a voice block!\n", fn_begin);
		OSMO_ASSERT(false);
		return false;
		break;
	}
}