Project

General

Profile

Support #4213 » loops_areas_fix.c

S_erge_y, 11/01/2019 08:54 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 > my_target)
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 < target_hi)
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
	chan_state->meas.toa_num = 0;
109
	chan_state->meas.toa256_sum = 0;
110

    
111
}
112

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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