Project

General

Profile

Support #4213 » loops_areas.c

S_erge_y, 11/01/2019 08:08 AM

 
1
/* Loop control for OsmoBTS-TRX */
2

    
3
/* (C) 2013 by Andreas Eversberg <jolly@eversberg.eu>
4
 *
5
 * All Rights Reserved
6
 *
7
 * This program is free software; you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as published by
9
 * the Free Software Foundation; either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU Affero General Public License
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19
 *
20
 */
21

    
22
#include <stdint.h>
23
#include <unistd.h>
24
#include <stdlib.h>
25
#include <errno.h>
26

    
27
#include <osmo-bts/gsm_data.h>
28
#include <osmo-bts/logging.h>
29
#include <osmo-bts/l1sap.h>
30
#include <osmocom/core/bits.h>
31

    
32
#include "trx_if.h"
33
#include "l1_if.h"
34
#include "loops.h"
35

    
36
/*
37
 * MS Power loop
38
 */
39

    
40

    
41

    
42
/*! Input a new RSSI value into the MS power control loop for the given logical channel.
43
 *  \param lchan logical channel
44
 *  \param chan_state L1 channel state of the logical channel.
45
 *  \param rssi Received Signal Strength Indication (in dBm) */
46
static void ms_power_val(struct gsm_lchan *lchan, struct l1sched_chan_state *chan_state, int8_t rssi)
47
{
48
int8_t ms_send;
49
int8_t my_target;
50
int8_t target_hi;
51
my_target = trx_phy_instance(lchan->ts->trx)->phy_link->u.osmotrx.trx_target_rssi;
52
target_hi = my_target - 15;
53
//LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Target check: %d\n", target_hi);
54
ms_send = lchan->ms_power_ctrl.current;
55

    
56
if (rssi > target_hi)
57
{
58
ms_send = ms_send + 1;
59
LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "RSSI value: %d, Set ms_power_ctrl.current +1 (DOWN power) value: %d\n", rssi, ms_send);
60
}
61
if (rssi < my_target)
62
{
63
ms_send = ms_send - 1;
64
LOGPLCHAN(lchan, DLOOP, LOGL_INFO, "RSSI value: %d, Set ms_power_ctrl.current -1 (UP power) value: %d\n", rssi, ms_send);
65
}
66
//Protect 30..5:
67
if (ms_send > 30)
68
   ms_send = 30;
69
if (ms_send < 5)
70
   ms_send = 5;
71
//Write
72
lchan->ms_power_ctrl.current = ms_send;
73
}
74

    
75
/* 90% of one bit duration in 1/256 symbols: 256*0.9 */
76
#define TOA256_9OPERCENT	230
77

    
78
/*
79
 * Timing Advance loop
80
 */
81

    
82
void ta_val(struct gsm_lchan *lchan, struct l1sched_chan_state *chan_state, int16_t toa256)
83
{
84
	/* check if the current L1 header acks to the current ordered TA */
85
	if (lchan->meas.l1_info[1] != lchan->rqd_ta)
86
		return;
87

    
88
	/* sum measurement */
89
	chan_state->meas.toa256_sum += toa256;
90
	if (++(chan_state->meas.toa_num) < 16)
91
		return;
92

    
93
	/* complete set */
94
	toa256 = chan_state->meas.toa256_sum / chan_state->meas.toa_num;
95

    
96
	/* check for change of TOA */
97
	if (toa256 < -TOA256_9OPERCENT && lchan->rqd_ta > 0) {
98
		LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "TOA is too early (%d), now lowering TA from %d to %d\n",
99
			toa256, lchan->rqd_ta, lchan->rqd_ta - 1);
100
		lchan->rqd_ta--;
101
	} else if (toa256 > TOA256_9OPERCENT && lchan->rqd_ta < 63) {
102
		LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "TOA is too late (%d), now raising TA from %d to %d\n",
103
			toa256, lchan->rqd_ta, lchan->rqd_ta + 1);
104
		lchan->rqd_ta++;
105
	} else
106
		LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "TOA is correct (%d), keeping current TA of %d\n",
107
			toa256, lchan->rqd_ta);
108

    
109
	chan_state->meas.toa_num = 0;
110
	chan_state->meas.toa256_sum = 0;
111

    
112
}
113

    
114
/*! Process a SACCH event as input to the MS power control and TA loop.  Function
115
 *  is called once every uplink SACCH block is received.
116
 * \param l1t L1 TRX instance on which we operate
117
 * \param chan_nr RSL channel number on which we operate
118
 * \param chan_state L1 scheduler channel state of the channel on which we operate
119
 * \param[in] rssi Receive Signal Strength Indication
120
 * \param[in] toa256 Time of Arrival in 1/256 symbol periods */
121
void trx_loop_sacch_input(struct l1sched_trx *l1t, uint8_t chan_nr,
122
	struct l1sched_chan_state *chan_state, int8_t rssi, int16_t toa256)
123
{
124
	struct gsm_lchan *lchan = &l1t->trx->ts[L1SAP_CHAN2TS(chan_nr)]
125
					.lchan[l1sap_chan2ss(chan_nr)];
126
	struct phy_instance *pinst = trx_phy_instance(l1t->trx);
127

    
128
	/* if MS power control loop is enabled, handle it */
129
	if (pinst->phy_link->u.osmotrx.trx_ms_power_loop)
130
		ms_power_val(lchan, chan_state, rssi);
131

    
132
	/* if TA loop is enabled, handle it */
133
	if (pinst->phy_link->u.osmotrx.trx_ta_loop)
134
		ta_val(lchan, chan_state, toa256);
135
}
136

    
137
/*! Called once every downlink SACCH block needs to be sent. */
138
void trx_loop_sacch_clock(struct l1sched_trx *l1t, uint8_t chan_nr,
139
	struct l1sched_chan_state *chan_state)
140
{
141
	struct gsm_lchan *lchan = &l1t->trx->ts[L1SAP_CHAN2TS(chan_nr)]
142
					.lchan[l1sap_chan2ss(chan_nr)];
143
//	struct phy_instance *pinst = trx_phy_instance(l1t->trx);
144

    
145
	if (lchan->ms_power_ctrl.fixed)
146
	        return;
147

    
148
//	if (pinst->phy_link->u.osmotrx.trx_ms_power_loop)
149
//		ms_power_clock(lchan, chan_state);
150

    
151
	/* count the number of SACCH clocks */
152
	chan_state->meas.clock++;
153
}
154

    
155
void trx_loop_amr_input(struct l1sched_trx *l1t, uint8_t chan_nr,
156
	struct l1sched_chan_state *chan_state, float ber)
157
{
158
	struct gsm_bts_trx *trx = l1t->trx;
159
	struct gsm_lchan *lchan = &trx->ts[L1SAP_CHAN2TS(chan_nr)]
160
					.lchan[l1sap_chan2ss(chan_nr)];
161

    
162
	/* check if loop is enabled */
163
	if (!chan_state->amr_loop)
164
		return;
165

    
166
	/* wait for MS to use the requested codec */
167
	if (chan_state->ul_ft != chan_state->dl_cmr)
168
		return;
169

    
170
	/* count bit errors */
171
	if (L1SAP_IS_CHAN_TCHH(chan_nr)) {
172
		chan_state->ber_num += 2;
173
		chan_state->ber_sum += (ber + ber);
174
	} else {
175
		chan_state->ber_num++;
176
		chan_state->ber_sum += ber;
177
	}
178

    
179
	/* count frames */
180
	if (chan_state->ber_num < 48)
181
		return;
182

    
183
	/* calculate average (reuse ber variable) */
184
	ber = chan_state->ber_sum / chan_state->ber_num;
185

    
186
	/* reset bit errors */
187
	chan_state->ber_num = 0;
188
	chan_state->ber_sum = 0;
189

    
190
	LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Current bit error rate (BER) %.6f "
191
		"codec id %d\n", ber, chan_state->ul_ft);
192

    
193
	/* degrade */
194
	if (chan_state->dl_cmr > 0) {
195
		/* degrade, if ber is above threshold FIXME: C/I */
196
		if (ber >
197
		   lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr-1].threshold) {
198
			LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Degrading due to BER %.6f "
199
				"from codec id %d to %d\n", ber, chan_state->dl_cmr,
200
				chan_state->dl_cmr - 1);
201
			chan_state->dl_cmr--;
202
		}
203
	} else if (chan_state->dl_cmr < chan_state->codecs - 1) {
204
		/* degrade, if ber is above threshold  FIXME: C/I*/
205
		if (ber <
206
		    lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr].threshold
207
		  - lchan->tch.amr_mr.bts_mode[chan_state->dl_cmr].hysteresis) {
208
			LOGPLCHAN(lchan, DLOOP, LOGL_DEBUG, "Upgrading due to BER %.6f "
209
				"from codec id %d to %d\n", ber, chan_state->dl_cmr,
210
				chan_state->dl_cmr + 1);
211
			chan_state->dl_cmr++;
212
		}
213
	}
214
}
215

    
216
void trx_loop_amr_set(struct l1sched_chan_state *chan_state, int loop)
217
{
218
	if (chan_state->amr_loop && !loop) {
219
		chan_state->amr_loop = 0;
220
		return;
221
	}
222

    
223
	if (!chan_state->amr_loop && loop) {
224
		chan_state->amr_loop = 1;
225

    
226
		/* reset bit errors */
227
		chan_state->ber_num = 0;
228
		chan_state->ber_sum = 0;
229

    
230
		return;
231
	}
232
}
(4-4/6)
Add picture from clipboard (Maximum size: 48.8 MB)