<p>Neels Hofmeyr <strong>merged</strong> this change.</p><p><a href="https://gerrit.osmocom.org/10058">View Change</a></p><div style="white-space:pre-wrap">Approvals:
Jenkins Builder: Verified
Harald Welte: Looks good to me, approved
</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">hodec2 log: less verbose, more concise logging<br><br>Drop numerous log statements that merely bloat the ho decision log.<br><br>Logging HO candidates: log more compact in a single line, do not use LOGPC and<br>multiline output. The result is more useful information in a quarter of the log<br>lines.<br><br>LOGPHOLCHAN(), LOGPHOLCHANTOBTS():<br>- log lchan->type instead of lchan->ts->pchan<br>- always log the speech mode<br><br>===== Before =====<br><br>DHODEC handover_decision_2.c:1131 (lchan 0.010 TCH/F) (subscr IMSI:000001) MEASUREMENT REPORT (1 neighbors)<br>DHODEC handover_decision_2.c:1136 (lchan 0.010 TCH/F) (subscr IMSI:000001) 0: arfcn=871 bsic=63 neigh_idx=0 rxlev=30 flags=0<br>DHODEC handover_decision_2.c:261 (lchan 0.010 TCH/F) (subscr IMSI:000001) neigh 871 rxlev=30 last_seen_nr=3<br>DHODEC handover_decision_2.c:1158 (lchan 0.010 TCH/F) (subscr IMSI:000001) HODEC2: evaluating measurement report<br>DHODEC handover_decision_2.c:1175 (lchan 0.010 TCH/F) (subscr IMSI:000001) Measurement report: average RX level = -110<br>DHODEC handover_decision_2.c:1190 (lchan 0.010 TCH/F) (subscr IMSI:000001) Virtually improving RX level from -110 to -105, due to AFS bias<br>DHODEC handover_decision_2.c:1220 (lchan 0.010 TCH/F) (subscr IMSI:000001) Attempting handover/assignment due to low rxlev<br>DHODEC handover_decision_2.c:899 (lchan 0.010 TCH/F) (subscr IMSI:000001) Collecting candidates for Assignment and Handover<br>DHODEC handover_decision_2.c:407 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) tch_mode='SPEECH_AMR' type='TCH_F'<br>DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) FR3 supported<br>DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) HR3 supported<br>DHODEC handover_decision_2.c:489 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) removing TCH/F, already on TCH/F in this cell<br>DHODEC handover_decision_2.c:573 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) TCH/H would not be congested after HO<br>DHODEC handover_decision_2.c:605 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) TCH/H would not be less congested in target than source cell after HO<br>DHODEC handover_decision_2.c:609 (lchan 0.010 TCH/F)->(BTS 0) (subscr IMSI:000001) requirements=0x30<br>DHODEC handover_decision_2.c:704 - current BTS 0, RX level -110<br>DHODEC handover_decision_2.c:707 o free TCH/F slots 3, minimum required 0<br>DHODEC handover_decision_2.c:709 o free TCH/H slots 4, minimum required 0<br>DHODEC handover_decision_2.c:714 o no requirement fulfilled for TCHF (no assignment possible)<br>DHODEC handover_decision_2.c:737 o requirement A B fulfilled for TCHH (not congested after assignment)<br>DHODEC handover_decision_2.c:407 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) tch_mode='SPEECH_AMR' type='TCH_F'<br>DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) FR3 supported<br>DHODEC handover_decision_2.c:313 (lchan 0.010 TCH/F) (subscr IMSI:000001) HR3 supported<br>DHODEC handover_decision_2.c:563 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/F would not be congested after HO<br>DHODEC handover_decision_2.c:573 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/H would not be congested after HO<br>DHODEC handover_decision_2.c:595 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/F would not be less congested in target than source cell after HO<br>DHODEC handover_decision_2.c:605 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) TCH/H would not be less congested in target than source cell after HO<br>DHODEC handover_decision_2.c:609 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) requirements=0x33<br>DHODEC handover_decision_2.c:701 - neighbor BTS 1, RX level -110 -> -80<br>DHODEC handover_decision_2.c:707 o free TCH/F slots 4, minimum required 0<br>DHODEC handover_decision_2.c:709 o free TCH/H slots 4, minimum required 0<br>DHODEC handover_decision_2.c:712 o requirement A B fulfilled for TCHF (not congested after handover)<br>DHODEC handover_decision_2.c:737 o requirement A B fulfilled for TCHH (not congested after handover)<br>DHODEC handover_decision_2.c:914 (lchan 0.010 TCH/F) (subscr IMSI:000001) adding 2 candidates from 1 neighbors, total 2<br>DHODEC handover_decision_2.c:1020 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Best candidate, RX level -80<br>DHODEC handover_decision_2.c:625 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Triggering Handover<br>DHODEC handover_decision_2.c:688 (lchan 0.010 TCH/F)->(BTS 1) (subscr IMSI:000001) Triggering handover to TCH/F, due to low rxlevel<br>DHO handover_logic.c:133 (BTS 0 trx 0 ts 1 lchan 0 TCH/F)->(BTS 1 lchan TCH_F) Initiating Handover...<br>DMSC handover_logic.c:135 SUBSCR_CONN[0x612000000520]{ACTIVE}: Received Event HO_START<br>DHODEC handover_logic.c:172 (BTS 0 trx 0 arfcn 870 ts 1 lchan 0 TCH/F)->(BTS 1 trx 0 arfcn 871 ts 1 lchan 0 TCH/F) (subscr IMSI:000001) Triggering Handover<br><br>===== After =====<br><br>DHODEC handover_decision_2.c:1039 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) MEASUREMENT REPORT (1 neighbors)<br>DHODEC handover_decision_2.c:1044 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) 0: arfcn=871 bsic=63 neigh_idx=0 rxlev=30 flags=0<br>DHODEC handover_decision_2.c:1097 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) Avg RX level = -110 dBm, +5 dBm AFS bias = -105 dBm; Avg RX quality = -1 (invalid), +0 AFS bias = -1<br>DHODEC handover_decision_2.c:1122 (lchan 0.010 TCH_F SPEECH_AMR) (subscr IMSI:000001) RX level is TOO LOW: -105 < -100<br>DHODEC handover_decision_2.c:677 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 0) (subscr IMSI:000001) RX level -110; TCH/F={free 3 (want 0), [-] not a candidate}; TCH/H={free 4 (want 0), [ABC] good}<br>DHODEC handover_decision_2.c:671 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) RX level -110 -> -80; TCH/F={free 4 (want 0), [ABC] good}; TCH/H={free 4 (want 0), [ABC] good}<br>DHODEC handover_decision_2.c:928 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) Best candidate, RX level -80<br>DHODEC handover_decision_2.c:641 (lchan 0.010 TCH_F SPEECH_AMR)->(BTS 1) (subscr IMSI:000001) Triggering handover to TCH/F, due to low rxlevel<br>DMSC handover_logic.c:125 SUBSCR_CONN[0x612000000520]{ACTIVE}: Received Event HO_START<br>DHODEC handover_logic.c:169 (BTS 0 trx 0 arfcn 870 ts 1 lchan 0 TCH_F SPEECH_AMR)->(BTS 1 trx 0 arfcn 871 ts 1 lchan 0 TCH/F) (subscr IMSI:000001) Triggering Handover<br><br>Change-Id: If1add9b57a051d32b67a4a08ab47a9655aa9dd17<br>---<br>M include/osmocom/bsc/handover.h<br>M src/osmo-bsc/handover_decision.c<br>M src/osmo-bsc/handover_decision_2.c<br>M src/osmo-bsc/handover_logic.c<br>4 files changed, 81 insertions(+), 222 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/include/osmocom/bsc/handover.h b/include/osmocom/bsc/handover.h</span><br><span>index eb03f6a..772ab98 100644</span><br><span>--- a/include/osmocom/bsc/handover.h</span><br><span>+++ b/include/osmocom/bsc/handover.h</span><br><span>@@ -12,13 +12,14 @@</span><br><span> struct gsm_meas_rep mr;</span><br><span> </span><br><span> #define LOGPHOLCHANTOLCHAN(old_lchan, new_lchan, level, fmt, args...) \</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, level, "(BTS %u trx %u arfcn %u ts %u lchan %u %s)->(BTS %u trx %u arfcn %u ts %u lchan %u %s) (subscr %s) " fmt, \</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DHODEC, level, "(BTS %u trx %u arfcn %u ts %u lchan %u %s %s)->(BTS %u trx %u arfcn %u ts %u lchan %u %s) (subscr %s) " fmt, \</span><br><span> old_lchan->ts->trx->bts->nr, \</span><br><span> old_lchan->ts->trx->nr, \</span><br><span> old_lchan->ts->trx->arfcn, \</span><br><span> old_lchan->ts->nr, \</span><br><span> old_lchan->nr, \</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_pchan_name(old_lchan->ts->pchan), \</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_lchant_name(old_lchan->type), \</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm48_chan_mode_name(old_lchan->tch_mode), \</span><br><span> new_lchan->ts->trx->bts->nr, \</span><br><span> new_lchan->ts->trx->nr, \</span><br><span> new_lchan->ts->trx->arfcn, \</span><br><span>diff --git a/src/osmo-bsc/handover_decision.c b/src/osmo-bsc/handover_decision.c</span><br><span>index 887c299..0e79023 100644</span><br><span>--- a/src/osmo-bsc/handover_decision.c</span><br><span>+++ b/src/osmo-bsc/handover_decision.c</span><br><span>@@ -201,7 +201,10 @@</span><br><span> struct gsm_bts *bts = mr->lchan->ts->trx->bts;</span><br><span> struct neigh_meas_proc *best_cell = NULL;</span><br><span> unsigned int best_better_db = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- int i, rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ int i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ho_get_ho_active(bts->ho))</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</span><br><span> </span><br><span> /* find the best cell in this report that is at least RXLEV_HYST</span><br><span> * better than the current serving cell */</span><br><span>@@ -231,28 +234,7 @@</span><br><span> if (!best_cell)</span><br><span> return 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_INFO, "%s: Cell on ARFCN %u is better: ",</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_ts_name(mr->lchan->ts), best_cell->arfcn);</span><br><span style="color: hsl(0, 100%, 40%);">- if (!ho_get_ho_active(bts->ho)) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_INFO, "Skipping, Handover disabled\n");</span><br><span style="color: hsl(0, 100%, 40%);">- return 0;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- rc = handover_to_arfcn_bsic(mr->lchan, best_cell->arfcn, best_cell->bsic);</span><br><span style="color: hsl(0, 100%, 40%);">- switch (rc) {</span><br><span style="color: hsl(0, 100%, 40%);">- case 0:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_INFO, "Starting handover: meas report number %d \n", mr->nr);</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case -ENOSPC:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_INFO, "No channel available\n");</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- case -EBUSY:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_INFO, "Handover already active\n");</span><br><span style="color: hsl(0, 100%, 40%);">- break;</span><br><span style="color: hsl(0, 100%, 40%);">- default:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_ERROR, "Unknown error\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- return rc;</span><br><span style="color: hsl(120, 100%, 40%);">+ return handover_to_arfcn_bsic(mr->lchan, best_cell->arfcn, best_cell->bsic);</span><br><span> }</span><br><span> </span><br><span> /* process an already parsed measurement report and decide if we want to</span><br><span>diff --git a/src/osmo-bsc/handover_decision_2.c b/src/osmo-bsc/handover_decision_2.c</span><br><span>index 7ac54df..e514b6c 100644</span><br><span>--- a/src/osmo-bsc/handover_decision_2.c</span><br><span>+++ b/src/osmo-bsc/handover_decision_2.c</span><br><span>@@ -40,22 +40,24 @@</span><br><span> LOGP(DHODEC, level, "(BTS %u) " fmt, bts->nr, ## args)</span><br><span> </span><br><span> #define LOGPHOLCHAN(lchan, level, fmt, args...) \</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, level, "(lchan %u.%u%u%u %s) (subscr %s) " fmt, \</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DHODEC, level, "(lchan %u.%u%u%u %s %s) (subscr %s) " fmt, \</span><br><span> lchan->ts->trx->bts->nr, \</span><br><span> lchan->ts->trx->nr, \</span><br><span> lchan->ts->nr, \</span><br><span> lchan->nr, \</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_pchan_name(lchan->ts->pchan), \</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_lchant_name(lchan->type), \</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm48_chan_mode_name(lchan->tch_mode), \</span><br><span> bsc_subscr_name(lchan->conn? lchan->conn->bsub : NULL), \</span><br><span> ## args)</span><br><span> </span><br><span> #define LOGPHOLCHANTOBTS(lchan, new_bts, level, fmt, args...) \</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, level, "(lchan %u.%u%u%u %s)->(BTS %u) (subscr %s) " fmt, \</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGP(DHODEC, level, "(lchan %u.%u%u%u %s %s)->(BTS %u) (subscr %s) " fmt, \</span><br><span> lchan->ts->trx->bts->nr, \</span><br><span> lchan->ts->trx->nr, \</span><br><span> lchan->ts->nr, \</span><br><span> lchan->nr, \</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_pchan_name(lchan->ts->pchan), \</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm_lchant_name(lchan->type), \</span><br><span style="color: hsl(120, 100%, 40%);">+ gsm48_chan_mode_name(lchan->tch_mode), \</span><br><span> new_bts->nr, \</span><br><span> bsc_subscr_name(lchan->conn? lchan->conn->bsub : NULL), \</span><br><span> ## args)</span><br><span>@@ -257,13 +259,9 @@</span><br><span> if (mrc) {</span><br><span> nmp->rxlev[idx] = mrc->rxlev;</span><br><span> nmp->last_seen_nr = mr->nr;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(mr->lchan, LOGL_DEBUG, "neigh %u rxlev=%d last_seen_nr=%u\n",</span><br><span style="color: hsl(0, 100%, 40%);">- nmp->arfcn, mrc->rxlev, nmp->last_seen_nr);</span><br><span> mrc->flags |= MRC_F_PROCESSED;</span><br><span> } else {</span><br><span> nmp->rxlev[idx] = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(mr->lchan, LOGL_DEBUG, "neigh %u not in report (last_seen_nr=%u)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- nmp->arfcn, nmp->last_seen_nr);</span><br><span> }</span><br><span> nmp->rxlev_cnt++;</span><br><span> }</span><br><span>@@ -308,11 +306,8 @@</span><br><span> }</span><br><span> </span><br><span> for (i = 0; i < clist->len; i++) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (clist->codec[i].type == type) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(conn->lchan, LOGL_DEBUG, "%s supported\n",</span><br><span style="color: hsl(0, 100%, 40%);">- gsm0808_speech_codec_type_name(type));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (clist->codec[i].type == type)</span><br><span> return true;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> }</span><br><span> LOGPHOLCHAN(conn->lchan, LOGL_DEBUG, "Codec not supported by MS or not allowed by MSC: %s\n",</span><br><span> gsm0808_speech_codec_type_name(type));</span><br><span>@@ -402,10 +397,6 @@</span><br><span> return 0;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG, "tch_mode='%s' type='%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">- get_value_string(gsm48_chan_mode_names, lchan->tch_mode),</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_lchant_name(lchan->type));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* compatibility check for codecs.</span><br><span> * if so, the candidates for full rate and half rate are selected */</span><br><span> switch (lchan->tch_mode) {</span><br><span>@@ -413,9 +404,6 @@</span><br><span> switch (lchan->type) {</span><br><span> case GSM_LCHAN_TCH_F: /* mandatory */</span><br><span> requirement |= REQUIREMENT_A_TCHF;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG, "tch_mode='%s' type='%s' supported\n",</span><br><span style="color: hsl(0, 100%, 40%);">- get_value_string(gsm48_chan_mode_names, lchan->tch_mode),</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_lchant_name(lchan->type));</span><br><span> break;</span><br><span> case GSM_LCHAN_TCH_H:</span><br><span> if (!bts->codec.hr) {</span><br><span>@@ -485,13 +473,9 @@</span><br><span> if (bts == current_bts) {</span><br><span> switch (lchan->type) {</span><br><span> case GSM_LCHAN_TCH_F:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "removing TCH/F, already on TCH/F in this cell\n");</span><br><span> requirement &= ~(REQUIREMENT_A_TCHF);</span><br><span> break;</span><br><span> case GSM_LCHAN_TCH_H:</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "removing TCH/H, already on TCH/H in this cell\n");</span><br><span> requirement &= ~(REQUIREMENT_A_TCHH);</span><br><span> break;</span><br><span> default:</span><br><span>@@ -558,24 +542,12 @@</span><br><span> /* the minimum free timeslots that are defined for this cell must</span><br><span> * be maintained _after_ handover/assignment */</span><br><span> if (requirement & REQUIREMENT_A_TCHF) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (tchf_count - 1 >= ho_get_hodec2_tchf_min_slots(bts->ho)) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "TCH/F would not be congested after HO\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (tchf_count - 1 >= ho_get_hodec2_tchf_min_slots(bts->ho))</span><br><span> requirement |= REQUIREMENT_B_TCHF;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "TCH/F would be congested after HO\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> }</span><br><span> if (requirement & REQUIREMENT_A_TCHH) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (tchh_count - 1 >= ho_get_hodec2_tchh_min_slots(bts->ho)) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "TCH/H would not be congested after HO\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (tchh_count - 1 >= ho_get_hodec2_tchh_min_slots(bts->ho))</span><br><span> requirement |= REQUIREMENT_B_TCHH;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "TCH/H would be congested after HO\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> }</span><br><span> </span><br><span> /* Requirement C */</span><br><span>@@ -584,30 +556,16 @@</span><br><span> * free slots of the current cell _after_ handover/assignment */</span><br><span> count = bts_count_free_ts(current_bts,</span><br><span> (lchan->type == GSM_LCHAN_TCH_H) ?</span><br><span style="color: hsl(0, 100%, 40%);">- GSM_PCHAN_TCH_H : GSM_PCHAN_TCH_F);</span><br><span style="color: hsl(120, 100%, 40%);">+ GSM_PCHAN_TCH_H : GSM_PCHAN_TCH_F);</span><br><span> if (requirement & REQUIREMENT_A_TCHF) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (tchf_count - 1 >= count + 1) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "TCH/F would be less congested in target than source cell after HO\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (tchf_count - 1 >= count + 1)</span><br><span> requirement |= REQUIREMENT_C_TCHF;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "TCH/F would not be less congested in target than source cell after HO\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> }</span><br><span> if (requirement & REQUIREMENT_A_TCHH) {</span><br><span style="color: hsl(0, 100%, 40%);">- if (tchh_count - 1 >= count + 1) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "TCH/H would be less congested in target than source cell after HO\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ if (tchh_count - 1 >= count + 1)</span><br><span> requirement |= REQUIREMENT_C_TCHH;</span><br><span style="color: hsl(0, 100%, 40%);">- } else {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG,</span><br><span style="color: hsl(0, 100%, 40%);">- "TCH/H would not be less congested in target than source cell after HO\n");</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, bts, LOGL_DEBUG, "requirements=0x%x\n", requirement);</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* return mask of fulfilled requirements */</span><br><span> return requirement;</span><br><span> }</span><br><span>@@ -619,11 +577,6 @@</span><br><span> int afs_bias = 0;</span><br><span> bool full_rate = false;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (current_bts == new_bts)</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_NOTICE, "Triggering Assignment\n");</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, new_bts, LOGL_NOTICE, "Triggering Handover\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* afs_bias becomes > 0, if AFS is used and is improved */</span><br><span> if (lchan->tch_mode == GSM48_CMODE_SPEECH_AMR)</span><br><span> afs_bias = ho_get_hodec2_afs_bias_rxlev(new_bts->ho);</span><br><span>@@ -682,7 +635,7 @@</span><br><span> full_rate ? "TCH/F" : "TCH/H",</span><br><span> ho_reason_name(global_ho_reason));</span><br><span> else</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHANTOBTS(lchan, new_bts, LOGL_NOTICE,</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPHOLCHANTOBTS(lchan, new_bts, LOGL_INFO,</span><br><span> "Triggering handover to %s, due to %s\n",</span><br><span> full_rate ? "TCH/F" : "TCH/H",</span><br><span> ho_reason_name(global_ho_reason));</span><br><span>@@ -692,71 +645,36 @@</span><br><span> }</span><br><span> </span><br><span> /* debug collected candidates */</span><br><span style="color: hsl(0, 100%, 40%);">-static inline void debug_candidate(struct ho_candidate *candidate,</span><br><span style="color: hsl(0, 100%, 40%);">- int neighbor, int8_t rxlev, int tchf_count, int tchh_count)</span><br><span style="color: hsl(120, 100%, 40%);">+static inline void debug_candidate(struct gsm_lchan *lchan, struct ho_candidate *candidate,</span><br><span style="color: hsl(120, 100%, 40%);">+ struct gsm_bts *neighbor, int8_t rxlev, int tchf_count, int tchh_count)</span><br><span> {</span><br><span style="color: hsl(120, 100%, 40%);">+#define HO_CANDIDATE_FMT(tchx, TCHX) "TCH/" #TCHX "={free %d (want %d), [%s%s%s]%s}"</span><br><span style="color: hsl(120, 100%, 40%);">+#define HO_CANDIDATE_ARGS(tchx, TCHX) \</span><br><span style="color: hsl(120, 100%, 40%);">+ tch##tchx##_count, ho_get_hodec2_tch##tchx##_min_slots(candidate->bts->ho), \</span><br><span style="color: hsl(120, 100%, 40%);">+ candidate->requirements & REQUIREMENT_A_TCH##TCHX ? "A" : \</span><br><span style="color: hsl(120, 100%, 40%);">+ (candidate->requirements & REQUIREMENT_TCH##TCHX##_MASK) == 0? "-" : "", \</span><br><span style="color: hsl(120, 100%, 40%);">+ candidate->requirements & REQUIREMENT_B_TCH##TCHX ? "B" : "", \</span><br><span style="color: hsl(120, 100%, 40%);">+ candidate->requirements & REQUIREMENT_B_TCH##TCHX ? "C" : "", \</span><br><span style="color: hsl(120, 100%, 40%);">+ (candidate->requirements & REQUIREMENT_TCH##TCHX##_MASK) == 0 ? " not a candidate" : \</span><br><span style="color: hsl(120, 100%, 40%);">+ ((candidate->requirements & REQUIREMENT_TCH##TCHX##_MASK) == REQUIREMENT_A_TCH##TCHX ? \</span><br><span style="color: hsl(120, 100%, 40%);">+ " more congestion" : \</span><br><span style="color: hsl(120, 100%, 40%);">+ (candidate->requirements & REQUIREMENT_B_TCH##TCHX ? \</span><br><span style="color: hsl(120, 100%, 40%);">+ " good" : \</span><br><span style="color: hsl(120, 100%, 40%);">+ /* now has to be candidate->requirements & REQUIREMENT_C_TCHX != 0: */ \</span><br><span style="color: hsl(120, 100%, 40%);">+ " less-or-equal congestion"))</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> if (neighbor)</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, " - neighbor BTS %d, RX level "</span><br><span style="color: hsl(0, 100%, 40%);">- "%d -> %d\n", candidate->bts->nr, rxlev2dbm(rxlev),</span><br><span style="color: hsl(0, 100%, 40%);">- rxlev2dbm(candidate->avg));</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPHOLCHANTOBTS(lchan, neighbor, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "RX level %d -> %d; "</span><br><span style="color: hsl(120, 100%, 40%);">+ HO_CANDIDATE_FMT(f, F) "; " HO_CANDIDATE_FMT(h, H) "\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rxlev2dbm(rxlev), rxlev2dbm(candidate->avg),</span><br><span style="color: hsl(120, 100%, 40%);">+ HO_CANDIDATE_ARGS(f, F), HO_CANDIDATE_ARGS(h, H));</span><br><span> else</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, " - current BTS %d, RX level %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">- candidate->bts->nr, rxlev2dbm(candidate->avg));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, " o free TCH/F slots %d, minimum required "</span><br><span style="color: hsl(0, 100%, 40%);">- "%d\n", tchf_count, ho_get_hodec2_tchf_min_slots(candidate->bts->ho));</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, " o free TCH/H slots %d, minimum required "</span><br><span style="color: hsl(0, 100%, 40%);">- "%d\n", tchh_count, ho_get_hodec2_tchh_min_slots(candidate->bts->ho));</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if ((candidate->requirements & REQUIREMENT_TCHF_MASK))</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, " o requirement ");</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, " o no requirement ");</span><br><span style="color: hsl(0, 100%, 40%);">- if ((candidate->requirements & REQUIREMENT_A_TCHF))</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, "A ");</span><br><span style="color: hsl(0, 100%, 40%);">- if ((candidate->requirements & REQUIREMENT_B_TCHF))</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, "B ");</span><br><span style="color: hsl(0, 100%, 40%);">- if ((candidate->requirements & REQUIREMENT_C_TCHF))</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, "C ");</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, "fulfilled for TCHF");</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(candidate->requirements & REQUIREMENT_TCHF_MASK)) /* nothing */</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, " (no %s possible)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- (neighbor) ? "handover" : "assignment");</span><br><span style="color: hsl(0, 100%, 40%);">- else if ((candidate->requirements & REQUIREMENT_TCHF_MASK)</span><br><span style="color: hsl(0, 100%, 40%);">- == REQUIREMENT_A_TCHF) /* only A */</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, " (more congestion after %s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- (neighbor) ? "handover" : "assignment");</span><br><span style="color: hsl(0, 100%, 40%);">- else if ((candidate->requirements & REQUIREMENT_B_TCHF)) /* B incl. */</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, " (not congested after %s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- (neighbor) ? "handover" : "assignment");</span><br><span style="color: hsl(0, 100%, 40%);">- else /* so it must include C */</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, " (less or equally congested after "</span><br><span style="color: hsl(0, 100%, 40%);">- "%s)\n", (neighbor) ? "handover" : "assignment");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- if ((candidate->requirements & REQUIREMENT_TCHH_MASK))</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, " o requirement ");</span><br><span style="color: hsl(0, 100%, 40%);">- else</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, " o no requirement ");</span><br><span style="color: hsl(0, 100%, 40%);">- if ((candidate->requirements & REQUIREMENT_A_TCHH))</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, "A ");</span><br><span style="color: hsl(0, 100%, 40%);">- if ((candidate->requirements & REQUIREMENT_B_TCHH))</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, "B ");</span><br><span style="color: hsl(0, 100%, 40%);">- if ((candidate->requirements & REQUIREMENT_C_TCHH))</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, "C ");</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, "fulfilled for TCHH");</span><br><span style="color: hsl(0, 100%, 40%);">- if (!(candidate->requirements & REQUIREMENT_TCHH_MASK)) /* nothing */</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, " (no %s possible)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- (neighbor) ? "handover" : "assignment");</span><br><span style="color: hsl(0, 100%, 40%);">- else if ((candidate->requirements & REQUIREMENT_TCHH_MASK)</span><br><span style="color: hsl(0, 100%, 40%);">- == REQUIREMENT_A_TCHH) /* only A */</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, " (more congestion after %s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- (neighbor) ? "handover" : "assignment");</span><br><span style="color: hsl(0, 100%, 40%);">- else if ((candidate->requirements & REQUIREMENT_B_TCHH)) /* B incl. */</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, " (not congested after %s)\n",</span><br><span style="color: hsl(0, 100%, 40%);">- (neighbor) ? "handover" : "assignment");</span><br><span style="color: hsl(0, 100%, 40%);">- else /* so it must include C */</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPC(DHODEC, LOGL_DEBUG, " (less or equally congested after "</span><br><span style="color: hsl(0, 100%, 40%);">- "%s)\n", (neighbor) ? "handover" : "assignment");</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPHOLCHANTOBTS(lchan, lchan->ts->trx->bts, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "RX level %d; "</span><br><span style="color: hsl(120, 100%, 40%);">+ HO_CANDIDATE_FMT(f, F) "; " HO_CANDIDATE_FMT(h, H) "\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rxlev2dbm(candidate->avg),</span><br><span style="color: hsl(120, 100%, 40%);">+ HO_CANDIDATE_ARGS(f, F), HO_CANDIDATE_ARGS(h, H));</span><br><span> }</span><br><span> </span><br><span> /* add candidate for re-assignment within the current cell */</span><br><span>@@ -775,7 +693,7 @@</span><br><span> c->bts = bts;</span><br><span> c->requirements = check_requirements(lchan, bts, tchf_count, tchh_count);</span><br><span> c->avg = av_rxlev;</span><br><span style="color: hsl(0, 100%, 40%);">- debug_candidate(c, 0, 0, tchf_count, tchh_count);</span><br><span style="color: hsl(120, 100%, 40%);">+ debug_candidate(lchan, c, NULL, 0, tchf_count, tchh_count);</span><br><span> (*candidates)++;</span><br><span> }</span><br><span> </span><br><span>@@ -855,7 +773,7 @@</span><br><span> c->requirements = check_requirements(lchan, neighbor_bts, tchf_count,</span><br><span> tchh_count);</span><br><span> c->avg = avg;</span><br><span style="color: hsl(0, 100%, 40%);">- debug_candidate(c, 1, av_rxlev, tchf_count, tchh_count);</span><br><span style="color: hsl(120, 100%, 40%);">+ debug_candidate(lchan, c, neighbor_bts, av_rxlev, tchf_count, tchh_count);</span><br><span> (*candidates)++;</span><br><span> }</span><br><span> </span><br><span>@@ -865,14 +783,12 @@</span><br><span> {</span><br><span> struct gsm_bts *bts = lchan->ts->trx->bts;</span><br><span> int av_rxlev;</span><br><span style="color: hsl(0, 100%, 40%);">- unsigned int candidates_was;</span><br><span> bool assignment;</span><br><span> bool handover;</span><br><span> int neighbors_count = 0;</span><br><span> unsigned int rxlev_avg_win = ho_get_hodec2_rxlev_avg_win(bts->ho);</span><br><span> </span><br><span> OSMO_ASSERT(candidates);</span><br><span style="color: hsl(0, 100%, 40%);">- candidates_was = *candidates;</span><br><span> </span><br><span> /* caculate average rxlev for this cell over the window */</span><br><span> av_rxlev = get_meas_rep_avg(lchan,</span><br><span>@@ -893,11 +809,6 @@</span><br><span> assignment = ho_get_hodec2_as_active(bts->ho);</span><br><span> handover = ho_get_ho_active(bts->ho);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_DEBUG, "Collecting candidates for%s%s%s\n",</span><br><span style="color: hsl(0, 100%, 40%);">- assignment ? " Assignment" : "",</span><br><span style="color: hsl(0, 100%, 40%);">- assignment && handover ? " and" : "",</span><br><span style="color: hsl(0, 100%, 40%);">- handover ? " Handover" : "");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> if (assignment)</span><br><span> collect_assignment_candidate(lchan, clist, candidates, av_rxlev);</span><br><span> </span><br><span>@@ -909,9 +820,6 @@</span><br><span> include_weaker_rxlev, av_rxlev, &neighbors_count);</span><br><span> }</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_DEBUG, "adding %u candidates from %u neighbors, total %u\n",</span><br><span style="color: hsl(0, 100%, 40%);">- *candidates - candidates_was, neighbors_count, *candidates);</span><br><span> }</span><br><span> </span><br><span> /*</span><br><span>@@ -1155,8 +1063,6 @@</span><br><span> return;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_DEBUG, "HODEC2: evaluating measurement report\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> /* get average levels. if not enought measurements yet, value is < 0 */</span><br><span> av_rxlev = get_meas_rep_avg(lchan,</span><br><span> ho_get_hodec2_full_tdma(bts->ho) ?</span><br><span>@@ -1170,34 +1076,29 @@</span><br><span> LOGPHOLCHAN(lchan, LOGL_INFO, "Skipping, Not enough recent measurements\n");</span><br><span> return;</span><br><span> }</span><br><span style="color: hsl(0, 100%, 40%);">- if (av_rxlev >= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_DEBUG, "Measurement report: average RX level = %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">- rxlev2dbm(av_rxlev));</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (av_rxqual >= 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_DEBUG, "Measurement report: average RX quality = %d\n",</span><br><span style="color: hsl(0, 100%, 40%);">- av_rxqual);</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span> </span><br><span> /* improve levels in case of AFS, if defined */</span><br><span> if (lchan->type == GSM_LCHAN_TCH_F</span><br><span> && lchan->tch_mode == GSM48_CMODE_SPEECH_AMR) {</span><br><span style="color: hsl(120, 100%, 40%);">+ int av_rxlev_was = av_rxlev;</span><br><span style="color: hsl(120, 100%, 40%);">+ int av_rxqual_was = av_rxqual;</span><br><span> int rxlev_bias = ho_get_hodec2_afs_bias_rxlev(bts->ho);</span><br><span> int rxqual_bias = ho_get_hodec2_afs_bias_rxqual(bts->ho);</span><br><span style="color: hsl(0, 100%, 40%);">- if (av_rxlev >= 0 && rxlev_bias) {</span><br><span style="color: hsl(0, 100%, 40%);">- int imp = av_rxlev + rxlev_bias;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_INFO, "Virtually improving RX level from %d to %d,"</span><br><span style="color: hsl(0, 100%, 40%);">- " due to AFS bias\n", rxlev2dbm(av_rxlev), rxlev2dbm(imp));</span><br><span style="color: hsl(0, 100%, 40%);">- av_rxlev = imp;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(0, 100%, 40%);">- if (av_rxqual >= 0 && rxqual_bias) {</span><br><span style="color: hsl(0, 100%, 40%);">- int imp = av_rxqual - rxqual_bias;</span><br><span style="color: hsl(0, 100%, 40%);">- if (imp < 0)</span><br><span style="color: hsl(0, 100%, 40%);">- imp = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_INFO, "Virtually improving RX quality from %d to %d,"</span><br><span style="color: hsl(0, 100%, 40%);">- " due to AFS bias\n", rxlev2dbm(av_rxqual), rxlev2dbm(imp));</span><br><span style="color: hsl(0, 100%, 40%);">- av_rxqual = imp;</span><br><span style="color: hsl(0, 100%, 40%);">- }</span><br><span style="color: hsl(120, 100%, 40%);">+ if (av_rxlev >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ av_rxlev = av_rxlev + rxlev_bias;</span><br><span style="color: hsl(120, 100%, 40%);">+ if (av_rxqual >= 0)</span><br><span style="color: hsl(120, 100%, 40%);">+ av_rxqual = OSMO_MAX(0, av_rxqual - rxqual_bias);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPHOLCHAN(lchan, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Avg RX level = %d dBm, %+d dBm AFS bias = %d dBm;"</span><br><span style="color: hsl(120, 100%, 40%);">+ " Avg RX quality = %d%s, %+d AFS bias = %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rxlev2dbm(av_rxlev_was), rxlev_bias, rxlev2dbm(av_rxlev),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_MAX(-1, av_rxqual_was), av_rxqual_was < 0 ? " (invalid)" : "",</span><br><span style="color: hsl(120, 100%, 40%);">+ -rxqual_bias, OSMO_MAX(-1, av_rxqual));</span><br><span style="color: hsl(120, 100%, 40%);">+ } else {</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPHOLCHAN(lchan, LOGL_DEBUG, "Avg RX level = %d dBm; Avg RX quality = %d%s\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rxlev2dbm(av_rxlev),</span><br><span style="color: hsl(120, 100%, 40%);">+ OSMO_MAX(-1, av_rxqual), av_rxqual < 0 ? " (invalid)" : "");</span><br><span> }</span><br><span> </span><br><span> /* Bad Quality */</span><br><span>@@ -1217,7 +1118,8 @@</span><br><span> /* Low Level */</span><br><span> if (av_rxlev >= 0 && rxlev2dbm(av_rxlev) < ho_get_hodec2_min_rxlev(bts->ho)) {</span><br><span> global_ho_reason = HO_REASON_LOW_RXLEVEL;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_INFO, "Attempting handover/assignment due to low rxlev\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPHOLCHAN(lchan, LOGL_NOTICE, "RX level is TOO LOW: %d < %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ rxlev2dbm(av_rxlev), ho_get_hodec2_min_rxlev(bts->ho));</span><br><span> find_alternative_lchan(lchan, true);</span><br><span> return;</span><br><span> }</span><br><span>@@ -1226,7 +1128,8 @@</span><br><span> if (lchan->meas_rep_count > 0</span><br><span> && lchan->rqd_ta > ho_get_hodec2_max_distance(bts->ho)) {</span><br><span> global_ho_reason = HO_REASON_MAX_DISTANCE;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_INFO, "Attempting handover due to high TA\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPHOLCHAN(lchan, LOGL_NOTICE, "TA is TOO HIGH: %u > %d\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ lchan->rqd_ta, ho_get_hodec2_max_distance(bts->ho));</span><br><span> /* start penalty timer to prevent comming back too</span><br><span> * early. it must be started before selecting a better cell,</span><br><span> * so there is no assignment selected, due to running</span><br><span>@@ -1242,7 +1145,6 @@</span><br><span> </span><br><span> /* try handover to a better cell */</span><br><span> if (av_rxlev >= 0 && (mr->nr % pwr_interval) == 0) {</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(lchan, LOGL_INFO, "Looking whether a cell has better RXLEV\n");</span><br><span> global_ho_reason = HO_REASON_BETTER_CELL;</span><br><span> find_alternative_lchan(lchan, false);</span><br><span> }</span><br><span>@@ -1439,12 +1341,10 @@</span><br><span> /* perform handover, if there is a candidate */</span><br><span> if (best_cand) {</span><br><span> any_ho = 1;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOLCHAN(best_cand->lchan, LOGL_INFO,</span><br><span style="color: hsl(0, 100%, 40%);">- "Best candidate BTS %u (RX level %d) without congestion found\n",</span><br><span style="color: hsl(0, 100%, 40%);">- best_cand->bts->nr, rxlev2dbm(best_cand->avg));</span><br><span style="color: hsl(0, 100%, 40%);">- if (is_improved)</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_INFO, "(is improved due to "</span><br><span style="color: hsl(0, 100%, 40%);">- "AHS -> AFS)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ LOGPHOLCHAN(best_cand->lchan, LOGL_DEBUG,</span><br><span style="color: hsl(120, 100%, 40%);">+ "Best candidate BTS %u (RX level %d%s) without congestion found\n",</span><br><span style="color: hsl(120, 100%, 40%);">+ best_cand->bts->nr, rxlev2dbm(best_cand->avg),</span><br><span style="color: hsl(120, 100%, 40%);">+ is_improved ? ", RX quality improved by AHS->AFS" : "");</span><br><span> trigger_handover_or_assignment(best_cand->lchan, best_cand->bts,</span><br><span> best_cand->requirements & REQUIREMENT_B_MASK);</span><br><span> #if 0</span><br><span>@@ -1468,9 +1368,6 @@</span><br><span> goto exit;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOBTS(bts, LOGL_DEBUG, "Did not find a best candidate that fulfills requirement B"</span><br><span style="color: hsl(0, 100%, 40%);">- " (omitting change from AHS to AFS)\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #if 0</span><br><span> next_b2:</span><br><span> #endif</span><br><span>@@ -1504,8 +1401,6 @@</span><br><span> is_improved = 1;</span><br><span> } else</span><br><span> is_improved = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, "candidate %d: avg=%d worst_avg_db=%d\n", i, avg,</span><br><span style="color: hsl(0, 100%, 40%);">- worst_avg_db);</span><br><span> if (avg < worst_avg_db) {</span><br><span> worst_cand = &clist[i];</span><br><span> worst_avg_db = avg;</span><br><span>@@ -1517,11 +1412,9 @@</span><br><span> if (worst_cand) {</span><br><span> any_ho = 1;</span><br><span> LOGP(DHODEC, LOGL_INFO, "Worst candidate for assignment "</span><br><span style="color: hsl(0, 100%, 40%);">- "(RX level %d) from TCH/H -> TCH/F without congestion "</span><br><span style="color: hsl(0, 100%, 40%);">- "found\n", rxlev2dbm(worst_cand->avg));</span><br><span style="color: hsl(0, 100%, 40%);">- if (is_improved)</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_INFO, "(is improved due to "</span><br><span style="color: hsl(0, 100%, 40%);">- "AHS -> AFS)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ "(RX level %d%s) from TCH/H -> TCH/F without congestion "</span><br><span style="color: hsl(120, 100%, 40%);">+ "found\n", rxlev2dbm(worst_cand->avg),</span><br><span style="color: hsl(120, 100%, 40%);">+ is_improved ? ", RX quality improved by AHS->AFS" : "");</span><br><span> trigger_handover_or_assignment(worst_cand->lchan,</span><br><span> worst_cand->bts,</span><br><span> worst_cand->requirements & REQUIREMENT_B_MASK);</span><br><span>@@ -1543,9 +1436,6 @@</span><br><span> goto exit;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- LOGPHOBTS(bts, LOGL_DEBUG, "Did not find a worst candidate that fulfills requirement B,"</span><br><span style="color: hsl(0, 100%, 40%);">- " selecting candidates that change from AHS to AFS only\n");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> #if 0</span><br><span> next_c1:</span><br><span> #endif</span><br><span>@@ -1584,7 +1474,6 @@</span><br><span> is_improved = 1;</span><br><span> } else</span><br><span> is_improved = 0;</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_DEBUG, "candidate %d: avg=%d best_avg_db=%d\n", i, avg, best_avg_db);</span><br><span> if (avg > best_avg_db) {</span><br><span> best_cand = &clist[i];</span><br><span> best_avg_db = avg;</span><br><span>@@ -1672,11 +1561,9 @@</span><br><span> if (worst_cand) {</span><br><span> any_ho = 1;</span><br><span> LOGP(DHODEC, LOGL_INFO, "Worst candidate for assignment "</span><br><span style="color: hsl(0, 100%, 40%);">- "(RX level %d) from TCH/H -> TCH/F with less or equal "</span><br><span style="color: hsl(0, 100%, 40%);">- "congestion found\n", rxlev2dbm(worst_cand->avg));</span><br><span style="color: hsl(0, 100%, 40%);">- if (is_improved)</span><br><span style="color: hsl(0, 100%, 40%);">- LOGP(DHODEC, LOGL_INFO, "(is improved due to "</span><br><span style="color: hsl(0, 100%, 40%);">- "AHS -> AFS)\n");</span><br><span style="color: hsl(120, 100%, 40%);">+ "(RX level %d%s) from TCH/H -> TCH/F with less or equal "</span><br><span style="color: hsl(120, 100%, 40%);">+ "congestion found\n", rxlev2dbm(worst_cand->avg),</span><br><span style="color: hsl(120, 100%, 40%);">+ is_improved ? ", RX quality improved by AHS->AFS" : "");</span><br><span> trigger_handover_or_assignment(worst_cand->lchan,</span><br><span> worst_cand->bts,</span><br><span> worst_cand->requirements & REQUIREMENT_C_MASK);</span><br><span>diff --git a/src/osmo-bsc/handover_logic.c b/src/osmo-bsc/handover_logic.c</span><br><span>index 064615c..509de53 100644</span><br><span>--- a/src/osmo-bsc/handover_logic.c</span><br><span>+++ b/src/osmo-bsc/handover_logic.c</span><br><span>@@ -122,17 +122,6 @@</span><br><span> llist_add(&ho->list, &bsc_handovers);</span><br><span> </span><br><span> conn->ho = ho;</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span style="color: hsl(0, 100%, 40%);">- DEBUGP(DHO, "(BTS %u trx %u ts %u lchan %u %s)->(BTS %u lchan %s) Initiating %s...\n",</span><br><span style="color: hsl(0, 100%, 40%);">- old_lchan->ts->trx->bts->nr,</span><br><span style="color: hsl(0, 100%, 40%);">- old_lchan->ts->trx->nr,</span><br><span style="color: hsl(0, 100%, 40%);">- old_lchan->ts->nr,</span><br><span style="color: hsl(0, 100%, 40%);">- old_lchan->nr,</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_pchan_name(old_lchan->ts->pchan),</span><br><span style="color: hsl(0, 100%, 40%);">- new_bts->nr,</span><br><span style="color: hsl(0, 100%, 40%);">- gsm_lchant_name(new_lchan_type),</span><br><span style="color: hsl(0, 100%, 40%);">- do_assignment ? "Assignment" : "Handover");</span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> rc = osmo_fsm_inst_dispatch(conn->fi, GSCON_EV_HO_START, NULL);</span><br><span> </span><br><span> if (rc < 0) {</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.osmocom.org/10058">change 10058</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.osmocom.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.osmocom.org/10058"/><meta itemprop="name" content="View Change"/></div></div>
<div style="display:none"> Gerrit-Project: osmo-bsc </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-MessageType: merged </div>
<div style="display:none"> Gerrit-Change-Id: If1add9b57a051d32b67a4a08ab47a9655aa9dd17 </div>
<div style="display:none"> Gerrit-Change-Number: 10058 </div>
<div style="display:none"> Gerrit-PatchSet: 3 </div>
<div style="display:none"> Gerrit-Owner: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>
<div style="display:none"> Gerrit-Reviewer: Harald Welte <laforge@gnumonks.org> </div>
<div style="display:none"> Gerrit-Reviewer: Jenkins Builder </div>
<div style="display:none"> Gerrit-Reviewer: Neels Hofmeyr <nhofmeyr@sysmocom.de> </div>