aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/examples/osmo-pcu.cfg1
-rw-r--r--doc/manuals/chapters/configuration.adoc12
-rw-r--r--src/bts.cpp15
-rw-r--r--src/bts.h3
-rw-r--r--src/gprs_pcu.c2
-rw-r--r--src/gprs_pcu.h2
-rw-r--r--src/pcu_l1_if.cpp5
-rw-r--r--src/pcu_vty.c17
-rw-r--r--src/tbf.cpp4
-rw-r--r--tests/emu/pcu_emu.cpp1
10 files changed, 43 insertions, 19 deletions
diff --git a/doc/examples/osmo-pcu.cfg b/doc/examples/osmo-pcu.cfg
index b88e6e7b..4a3842dd 100644
--- a/doc/examples/osmo-pcu.cfg
+++ b/doc/examples/osmo-pcu.cfg
@@ -2,5 +2,4 @@ pcu
flow-control-interval 10
cs 2
alloc-algorithm dynamic
- alpha 0
gamma 0
diff --git a/doc/manuals/chapters/configuration.adoc b/doc/manuals/chapters/configuration.adoc
index 01e4d652..d031ce6a 100644
--- a/doc/manuals/chapters/configuration.adoc
+++ b/doc/manuals/chapters/configuration.adoc
@@ -15,14 +15,12 @@ pcu
flow-control-interval 10 <1>
cs 2 <2>
alloc-algorithm dynamic <3>
- alpha 0 <4>
gamma 0
----
<1> send a BSSGP flow-control PDU every 10 seconds
<2> start a TBF with the initial coding scheme 2
<3> dynamically chose between single-slot or multi-slot TBF allocations
depending on system load
-<4> disable MS power control loop
However, there are plenty of tuning parameters for people interested to
optimize PCU throughput or latency according to their requirements.
@@ -212,13 +210,15 @@ parameters.
You can set those parameters at the `pcu` VTY config node as follows:
-`alpha <0-10>`::
- Alpha parameter for MS power control in units of 0.1.
- Make sure to set the alpha value at System Information 13 (in
- the BSC), too!
`gamma <0-62>`::
Set the gamma parameter for MS power control in units of dB.
+Parameter `ALPHA` is set on the BSC VTY configuration file on a per-BTS basis,
+and forwarded by OsmoPCU to the MS through the SI13 received from the former
+over PCUIF. OsmoPCU VTY command `alpha <0-10>` overrides the value received over
+PCUIF to keep backward compatibility with existing config files, but it is
+currently deprecated and its use is discouraged; one should configure it per-BTS
+in OsmoBSC VTY instead.
=== Configuring Network Assisted Cell Change (NACC)
diff --git a/src/bts.cpp b/src/bts.cpp
index fb7de649..11aef3f6 100644
--- a/src/bts.cpp
+++ b/src/bts.cpp
@@ -918,7 +918,7 @@ send_imm_ass_rej:
plen = Encoding::write_immediate_assignment(
&bts->trx[trx_no].pdch[ts_no], tbf, bv,
false, rip->ra, Fn, ta, usf, false, sb_fn,
- bts->pcu->vty.alpha, bts->pcu->vty.gamma, -1,
+ bts_get_ms_pwr_alpha(bts), bts->pcu->vty.gamma, -1,
rip->burst_type);
bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_UL_TBF);
}
@@ -999,7 +999,7 @@ void bts_snd_dl_ass(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf, bo
tbf, immediate_assignment, true, 125,
(tbf->pdch[ts_no]->last_rts_fn + 21216) % GSM_MAX_FN,
tbf->ta(), 7, poll, tbf->poll_fn,
- bts->pcu->vty.alpha, bts->pcu->vty.gamma, -1,
+ bts_get_ms_pwr_alpha(bts), bts->pcu->vty.gamma, -1,
GSM_L1_BURST_TYPE_ACCESS_0);
if (plen >= 0) {
bts_do_rate_ctr_inc(bts, CTR_IMMEDIATE_ASSIGN_DL_TBF);
@@ -1292,3 +1292,14 @@ const struct llist_head* bts_ms_list(struct gprs_rlcmac_bts *bts)
{
return bts_ms_store(bts)->ms_list();
}
+
+uint8_t bts_get_ms_pwr_alpha(const struct gprs_rlcmac_bts *bts)
+{
+ if (bts->pcu->vty.force_alpha != (uint8_t)-1)
+ return bts->pcu->vty.force_alpha;
+ if (bts->si13_is_set)
+ return bts->si31_ro_decoded.pwr_ctrl_pars.alpha;
+ /* default if no SI13 is received yet: closed loop control, TS 44.060
+ * B.2 Closed loop control */
+ return 0;
+}
diff --git a/src/bts.h b/src/bts.h
index e67668c3..90367ac2 100644
--- a/src/bts.h
+++ b/src/bts.h
@@ -35,6 +35,7 @@ extern "C" {
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gsm/l1sap.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm48_rest_octets.h>
#include <osmocom/gsm/gsm48.h>
#include "mslot_class.h"
#include "gsm_rlcmac.h"
@@ -224,6 +225,7 @@ struct gprs_rlcmac_bts {
uint8_t si3[GSM_MACBLOCK_LEN];
bool si3_is_set;
uint8_t si13[GSM_MACBLOCK_LEN];
+ struct osmo_gsm48_si13_info si31_ro_decoded;
bool si13_is_set;
/* State for dynamic algorithm selection */
@@ -346,6 +348,7 @@ void bts_set_max_mcs_dl(struct gprs_rlcmac_bts *bts, uint8_t mcs_dl);
void bts_set_max_mcs_ul(struct gprs_rlcmac_bts *bts, uint8_t mcs_ul);
bool bts_cs_dl_is_supported(const struct gprs_rlcmac_bts *bts, enum CodingScheme cs);
const struct llist_head* bts_ms_list(struct gprs_rlcmac_bts *bts);
+uint8_t bts_get_ms_pwr_alpha(const struct gprs_rlcmac_bts *bts);
#ifdef __cplusplus
}
#endif
diff --git a/src/gprs_pcu.c b/src/gprs_pcu.c
index 554007ea..52e98255 100644
--- a/src/gprs_pcu.c
+++ b/src/gprs_pcu.c
@@ -65,7 +65,7 @@ struct gprs_pcu *gprs_pcu_alloc(void *ctx)
pcu->vty.max_cs_dl = MAX_GPRS_CS;
pcu->vty.max_mcs_ul = MAX_EDGE_MCS;
pcu->vty.max_mcs_dl = MAX_EDGE_MCS;
- pcu->vty.alpha = 0; /* a = 0.0 */
+ pcu->vty.force_alpha = (uint8_t)-1; /* don't force by default, use BTS SI13 provided value */
pcu->vty.dl_tbf_preemptive_retransmission = true;
/* By default resegmentation is supported in DL can also be configured
* through VTY */
diff --git a/src/gprs_pcu.h b/src/gprs_pcu.h
index 9f75fb80..76e3937a 100644
--- a/src/gprs_pcu.h
+++ b/src/gprs_pcu.h
@@ -90,7 +90,7 @@ struct gprs_pcu {
uint8_t max_cs_dl, max_cs_ul;
uint8_t max_mcs_dl, max_mcs_ul;
uint8_t force_two_phase;
- uint8_t alpha, gamma;
+ uint8_t force_alpha, gamma;
bool dl_tbf_preemptive_retransmission;
enum egprs_arq_type dl_arq_type; /* EGPRS_ARQ1 to support resegmentation in DL, EGPRS_ARQ2 for no reseg */
bool cs_adj_enabled; /* whether cs_adj_{upper,lower}_limit are used to adjust DL CS */
diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp
index b6d67862..7753557b 100644
--- a/src/pcu_l1_if.cpp
+++ b/src/pcu_l1_if.cpp
@@ -42,6 +42,7 @@ extern "C" {
#include <osmocom/gprs/gprs_ns2.h>
#include <osmocom/gsm/l1sap.h>
#include <osmocom/gsm/protocol/gsm_04_08.h>
+#include <osmocom/gsm/gsm48_rest_octets.h>
#include <osmocom/gsm/sysinfo.h>
}
@@ -291,6 +292,7 @@ int pcu_rx_data_ind_pdtch(struct gprs_rlcmac_bts *bts, uint8_t trx_no, uint8_t t
static int pcu_rx_data_ind_bcch(struct gprs_rlcmac_bts *bts, uint8_t *data, uint8_t len)
{
+ const uint8_t *si_ro;
switch (len) {
case 0:
/* Due to historical reasons also accept a completely empty message as
@@ -337,6 +339,9 @@ static int pcu_rx_data_ind_bcch(struct gprs_rlcmac_bts *bts, uint8_t *data, uint
case GSM48_MT_RR_SYSINFO_13:
memcpy(bts->si13, data, GSM_MACBLOCK_LEN);
bts->si13_is_set = true;
+ si_ro = ((struct gsm48_system_information_type_13*)data)->rest_octets;
+ if (osmo_gsm48_rest_octets_si13_decode(&bts->si31_ro_decoded, si_ro) < 0)
+ LOGP(DPCU, LOGL_ERROR, "Error decoding SI13\n");
break;
default:
LOGP(DL1IF, LOGL_ERROR,
diff --git a/src/pcu_vty.c b/src/pcu_vty.c
index 92ff8eb4..c2de92c6 100644
--- a/src/pcu_vty.c
+++ b/src/pcu_vty.c
@@ -230,7 +230,8 @@ static int config_write_pcu(struct vty *vty)
vty_out(vty, " alloc-algorithm dynamic%s", VTY_NEWLINE);
if (the_pcu->vty.force_two_phase)
vty_out(vty, " two-phase-access%s", VTY_NEWLINE);
- vty_out(vty, " alpha %d%s", the_pcu->vty.alpha, VTY_NEWLINE);
+ if (the_pcu->vty.force_alpha != (uint8_t)-1)
+ vty_out(vty, " alpha %u%s", the_pcu->vty.force_alpha, VTY_NEWLINE);
vty_out(vty, " gamma %d%s", the_pcu->vty.gamma * 2, VTY_NEWLINE);
if (!the_pcu->vty.dl_tbf_preemptive_retransmission)
vty_out(vty, " no dl-tbf-preemptive-retransmission%s", VTY_NEWLINE);
@@ -735,13 +736,19 @@ DEFUN_ATTR(cfg_pcu_no_two_phase,
DEFUN_ATTR(cfg_pcu_alpha,
cfg_pcu_alpha_cmd,
- "alpha <0-10>",
+ "alpha (si13|<0-10>)",
"Alpha parameter for MS power control in units of 0.1 (see TS 05.08) "
"NOTE: Be sure to set Alpha value at System information 13 too.\n"
- "Alpha in units of 0.1\n",
- CMD_ATTR_IMMEDIATE)
+ "Use value received from BSC in System Intormation 13 (default)\n"
+ "Force Alpha in units of 0.1\n",
+ CMD_ATTR_IMMEDIATE | CMD_ATTR_DEPRECATED)
{
- the_pcu->vty.alpha = atoi(argv[0]);
+ vty_out(vty, "%% 'alpha <0-10>' is now deprecated: use osmo-bsc's 'gprs power-control alpha <0-10>' instead%s",
+ VTY_NEWLINE);
+ if (strcmp(argv[0], "si13") == 0)
+ the_pcu->vty.force_alpha = (uint8_t) -1;
+ else
+ the_pcu->vty.force_alpha = atoi(argv[0]);
return CMD_SUCCESS;
}
diff --git a/src/tbf.cpp b/src/tbf.cpp
index 7caa2cea..18859271 100644
--- a/src/tbf.cpp
+++ b/src/tbf.cpp
@@ -930,7 +930,7 @@ struct msgb *gprs_rlcmac_tbf::create_dl_ass(uint32_t fn, uint8_t ts)
Encoding::write_packet_downlink_assignment(mac_control_block,
old_tfi_is_valid, m_tfi, (direction == GPRS_RLCMAC_DL_TBF),
new_dl_tbf, poll_ass_dl, rrbp,
- the_pcu->vty.alpha, the_pcu->vty.gamma, -1, 0,
+ bts_get_ms_pwr_alpha(new_dl_tbf->bts), the_pcu->vty.gamma, -1, 0,
is_egprs_enabled());
LOGP(DTBF, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Downlink Assignment +++++++++++++++++++++++++\n");
rc = encode_gsm_rlcmac_downlink(&bv, mac_control_block);
@@ -1033,7 +1033,7 @@ struct msgb *gprs_rlcmac_tbf::create_ul_ass(uint32_t fn, uint8_t ts)
mac_control_block = (RlcMacDownlink_t *)talloc_zero(tall_pcu_ctx, RlcMacDownlink_t);
Encoding::write_packet_uplink_assignment(mac_control_block, m_tfi,
(direction == GPRS_RLCMAC_DL_TBF), tlli(),
- is_tlli_valid(), new_tbf, 1, rrbp, the_pcu->vty.alpha,
+ is_tlli_valid(), new_tbf, 1, rrbp, bts_get_ms_pwr_alpha(new_tbf->bts),
the_pcu->vty.gamma, -1, is_egprs_enabled());
LOGP(DTBF, LOGL_DEBUG, "+++++++++++++++++++++++++ TX : Packet Uplink Assignment +++++++++++++++++++++++++\n");
diff --git a/tests/emu/pcu_emu.cpp b/tests/emu/pcu_emu.cpp
index 082f8ea3..7c9baa94 100644
--- a/tests/emu/pcu_emu.cpp
+++ b/tests/emu/pcu_emu.cpp
@@ -77,7 +77,6 @@ static void init_pcu(struct gprs_pcu *pcu)
if (!pcu->alloc_algorithm)
pcu->alloc_algorithm = alloc_algorithm_b;
pcu->vty.fc_interval = 100;
- pcu->vty.alpha = 0; /* a = 0.0 */
}
static void bvci_unblocked(struct gprs_bssgp_pcu *pcu)