[[cs_handover]]
== CS Handover

Handover is the process of moving a continuously used channel (lchan) from one
cell to another. Usually, that is an ongoing call, so that phones are able to
move across cell coverage areas without interrupting the voice transmission.

A handover can

- stay within one given cell (intra-cell, i.e. simply a new RR Assignment Command);
- occur between two cells that belong to the same BSS (intra-BSC, via RR Handover Command);
- cross BSS boundaries (inter-BSC, via BSSMAP handover procedures);
- move to another MSC (inter-MSC, inter-PLMN);
- move to another RAN type, e.g. from 2G to 3G (inter-RAT, inter-Radio-Access-Technology).

The physical distance is by definition always very near, but handover
negotiation may range from being invisible to the MSC all the way to
orchestrating completely separate RAN stacks.

OsmoBSC currently supports handover within one BSS and between separate BSS.
Whether inter-MSC is supported depends on the MSC implementation (to the BSC,
inter-MSC handover looks identical to inter-BSC handover). Inter-RAT handover
is currently not implemented.  However, you may still advertise 3G and 4G neighbor cells
in order to facilitate cell/RAT re-selection to those neighbors.

Since 2019, OsmoMSC fully supports both inter-BSC and inter-MSC handover.

.Handover support in Osmocom at the time of writing
[cols="^,^,^,^,^"]
|====
|  | intra-BSC HO (local BSS) | inter-BSC HO (remote BSS) | inter-MSC HO | inter-RAT HO
| OsmoBSC | rxlev, load-based | rxlev | (planned) | -
| OsmoMSC | (not involved, except for codec changes) | (planned)  | (planned)  | -
|====

Most handover related procedures are explained in 3GPP TS 48.008.

=== How Handover Works

This chapter generally explains handover operations between 2G cells.

==== Internal / Intra-BSC Handover

The BSS is configured to know which cell is physically adjacent to which other
cells, its "neighbors". On the MS/BTS/BSS level, individual cells are
identified by ARFCN+BSIC (frequency + 6-bit identification code).

The BSC instructs each BTS with a list of ARFCNs (i.e. GSM frequency bands)
that qualify as neighbor cells, as part of the System Information Type 2. Each
MS served by a BTS receives the System Information Type 2 and thus knows which
ARFCNs to measure for potential handover. Each MS with an active channel then
returns up to 6 measurements of reception levels (RXLEV) to the BTS, to be
forwarded to the BSC in RSL Measurement Report messages.

Note that the BTS and MS are told only the ARFCNs, not the BSICs, of neighbor
cells; the BSICs are however included in the measurements that an MS returns to
BTS and BSC. Commonly, each ARFCN is owned by one specific operator, so, an MS
considers all visible cells on a given ARFCN as possible neighbors. However, as
soon as an MS reports RXLEV of a specific neighbor cell, the BSC needs to know
which exact cell to possibly handover to, which is why the MS pinpoints the
specific BSIC that it reported measurements for.

The BSC is the point of decision whether to do handover or not. This can be a
hugely complex combination of heuristics, knowledge of cell load and codec
capabilities. The most important indicator for handover though is: does an MS
report a neighbor with a better signal than the current cell? See
<<intra_bsc_ho_dot>>.

[[intra_bsc_ho_dot]]
.Intra-BSC Handover stays within the BSS (shows steps only up to activation of the new lchan -- this would be followed by an RR Handover Command, RACH causing Handover Detection, Handover Complete, ...)
[graphviz]
----
include::handover_intra_bsc.dot[]
----

If the BSC sees the need for handover, it will:

- activate a new lchan (with a handover reference ID),
- send an RR Handover Command to the current lchan, and
- wait for the MS to send a Handover RACH to the new lchan ("Handover Detect").
- The RTP stream then is switched over to the new lchan,
- an RSL Establish Indication is expected on the new lchan,
- and the old lchan is released.

Should handover fail at any point, e.g. the new lchan never receives a RACH, or
the MS reports a Handover Failure, then the new lchan is simply released again,
and the old lchan remains in use. If the RTP stream has already been switched
over to the new lchan, it is switched back to the old lchan.

This is simple enough if the new cell is managed by the same BSC: the OsmoMGW
is simply instructed to relay the BTS-side of the RTP stream to another IP
address and port, and the BSC continues to forward DTAP to the MSC
transparently. The operation happens completely within the BSS, except for the
BSSMAP Handover Performed message sent to the MSC once the handover is
completed (see 3GPP TS 48.008).

==== External / Inter-BSC Handover

If the handover target cell belongs to a different BSS, the RR procedure for
handover remains the same, but we need to tell the _remote_ BSC to allocate the
new lchan.

The only way to reach the remote BSC is via the MSC, so the MSC must be able
to:

- identify which other BSC we want to talk to,
- forward various BSSMAP Handover messages between old and new BSC,
- redirect the core-side RTP stream to the new BSS at the appropriate time,
- and must finally BSSMAP Clear the connection to the old BSS to conclude the
  inter-BSC handover.

[[inter_bsc_ho_dot]]
.Inter-BSC Handover requires the MSC to relay between two BSCs (shows steps only up to the BSSMAP Handover Command -- this would be followed by an RR Handover Command, RACH causing Handover Detection, Handover Complete, ...)
[graphviz]
----
include::handover_inter_bsc.dot[]
----

The first part, identifying the remote BSC, is not as trivial as it sounds: as
mentioned above, on the level of cell information seen by BTS and MS, the
neighbor cells are identified by ARFCN+BSIC. However, on the A-interface and in
the MSC, there is no knowledge of ARFCN+BSIC configurations. Instead, each
cell is identified by a LAC and CI (Location Area Code and Cell Identifier).

NOTE: There are several different cell identification types on the A-interface:
from Cell Global Identifier (MCC+MNC+LAC+CI) down to only LAC. OsmoBSC supports
most of these (see <<neighbor_conf_list>>). For simplicity, this description
focuses on LAC+CI identification.

Hence:

- the BSC needs to know which remote-BSS cells' ARFCN+BSIC correspond to
  exactly which global LAC+CI, and
- the MSC needs to know which LAC+CI are managed by which BSC.

In other words, each BSC requires prior knowledge about the cell configuration
of its remote-BSS neighbor cells, and the MSC requires prior knowledge about
each BSC's cell identifiers; i.e. these config items are spread reduntantly.

The most obvious reason for using LAC+CI in BSSMAP is that identical ARFCN+BSIC
are typically re-used across many cells of the same network operator: an
operator will have only very few ARFCNs available, and the 6bit BSIC opens only
a very limited range of distinction between cells. As long as each cell has no
more than one neighbor per given ARFCN+BSIC, these values can be re-used any
number of times across a network, and even between cells managed by one and the
same BSC.

[[config_neigh]]
=== Configuring Neighbors

The most important step to enable handover in OsmoBSC is to configure each cell
with the ARFCN+BSIC identities of its adjacent neighbors -- both local-BSS and
remote-BSS.

For a long time, OsmoBSC has offered configuration to manually enter the
ARFCN+BSIC sent out as neighbors on various System Information messages (all
`neighbor-list` related commands). This is still possible; however,
particularly for re-using ARFCN+BSIC within one BSS, this method will not work
well.

With the addition of inter-BSC handover support, the new `neighbor` config item
has been added to the `bts` config node, to maintain explicit cell-to-cell neighbor
relations, with the possibility to re-use ARFCN+BSIC in each cell.

It is recommended to completely replace `neighbor-list` configurations with the
new `neighbor` configuration described below.

[[neighbor_conf_list]]
.Overview of neighbor configuration on the `bts` config node
[frame="none",grid="none",cols="^10%,^10%,80%"]
|====
| Local | Remote BSS | type of `neighbor` config line, by example
| ✓ |   | `neighbor bts 5`
| ✓ |   | `neighbor lac 200`
| ✓ |   | `neighbor lac-ci 200 3`
| ✓ |   | `neighbor cgi 001 01 200 3`
| ✓ | ✓ | `neighbor lac 200 arfcn 123 bsic 1`
| ✓ | ✓ | `neighbor lac-ci 200 3 arfcn 123 bsic 1`
| ✓ | ✓ | `neighbor cgi 001 01 200 3 arfcn 123 bsic 1`
|====

==== Default: All Local Cells are Neighbors

For historical reasons, the default behavior of OsmoBSC is to add all local-BSS cells as neighbors for every other cell. To
maintain a backwards compatible configuration file format, this is still the case: as long as no explicit
neighbor cell is configured with a `neighbor` command (either none was configured, or all configured
`neighbor` lines have been removed again), a cell automatically lists all of the local-BSS cells as neighbors.
These are implicit mappings in terms of the legacy neighbor configuration scheme, and re-using ARFCN+BSIC
combinations within a BSS will not work well this way.

As soon as the first explicit `neighbor` relation is added to a cell, the legacy behavior is switched off,
and only explicit neighbors are in effect.

NOTE: If a cell is required to not have any neighbors, it is recommended to switch off handover
for that cell with `handover 0`.

==== Local-BSS Neighbors

Local neighbors can be configured by just the local BTS number, or by LAC+CI,
or any other supported A-interface type cell identification; also including the
ARFCN+BSIC is optional, it will be derived from the local configuration if
omitted.

OsmoBSC will log errors in case the configuration includes ambiguous ARFCN+BSIC
relations (when one given cell has more than one neighbor for any one
ARFCN+BSIC).

Neighbor relations must be configured explicitly in both directions, i.e. each
cell has to name all of its neighbors, even if the other cell already has an
identical neighbor relation in the reverse direction.

.Example: configuring neighbors within the local BSS in osmo-bsc.cfg, identified by local BTS number
----
network
 bts 0
  neighbor bts 1
 bts 1
  neighbor bts 0
----

.Example: configuring neighbors within the local BSS in osmo-bsc.cfg, identified by LAC+CI
----
network

 bts 0
  # this cell's LAC=23 CI=5
  location_area_code 23
  cell_identity 5
  # reference bts 1
  neighbor lac-ci 23 6

 bts 1
  # this cell's LAC=23 CI=6
  location_area_code 23
  cell_identity 6
  # reference bts 0
  neighbor lac-ci 23 5
----

It is allowed to include the ARFCN and BSIC of local neighbor cells, even
though that is redundant with the already known local configuration of the
target cell. The idea is to ease generating the neighbor configuration
automatically, in that local-BSS and remote-BSS neighbors can have identical
configuration formatting. If the cell identification (LAC+CI) matches a local
cell but a mismatching ARFCN+BSIC follows on the same config line, OsmoBSC will
report errors. For human readability and maintainability, it may instead be
desirable to use the `neighbor bts <0-255>` format, or omit the redundant
`arfcn` and `bsic`.

.Example: configuring neighbors within the local BSS in osmo-bsc.cfg, redundantly identified by LAC+CI as well as ARFCN+BSIC
----
network

 bts 0
  # this cell's LAC=23 CI=5
  location_area_code 23
  cell_identity 5
  # this cell's ARFCN=1 BSIC=1
  trx 0
   arfcn 1
  base_station_id_code 1
  # reference bts 1
  neighbor lac-ci 23 6 arfcn 2 bsic 2

 bts 1
  # LAC=23 CI=6
  location_area_code 23
  cell_identity 6
  # this cell's ARFCN=2 BSIC=2
  trx 0
   arfcn 2
  base_station_id_code 2
  # reference bts 0
  neighbor lac-ci 23 5 arfcn 1 bsic 1
----

==== Remote-BSS Neighbors

Remote-BSS neighbors always need to be configured with full A-interface
identification _and_ ARFCN+BSIC, to allow mapping a cell's neighbor ARFCN+BSIC
to a BSSMAP Cell Identifier (see 3GPP TS 48.008 3.1.5.1 Handover Required
Indication and 3.2.1.9 HANDOVER REQUIRED).

.Example: configuring remote-BSS neighbors in osmo-bsc.cfg, identified by LAC+CI (showing both BSCs' configurations)
----
# BSC Alpha's osmo-bsc.cfg
network
 bts 0
  # this cell's LAC=23 CI=6
  location_area_code 23
  cell_identity 6
  # this cell's ARFCN=2 BSIC=2
  trx 0
   arfcn 2
  base_station_id_code 2
  # fully describe the remote cell by LAC+CI and ARFCN+BSIC
  neighbor lac-ci 42 3 arfcn 1 bsic 3

# BSC Beta's osmo-bsc.cfg
network
 bts 0
  # this cell's LAC=42 CI=3
  location_area_code 42
  cell_identity 3
  # this cell's ARFCN=1 BSIC=3
  trx 0
   arfcn 1
  base_station_id_code 3
  # fully describe the remote cell by LAC+CI and ARFCN+BSIC
  neighbor lac-ci 23 6 arfcn 2 bsic 2
----

NOTE: It is strongly recommended to stick to a single format for remote-BSS
neighbors' cell identifiers all across an OsmoBSC configuration; i.e. decide
once to use `lac`, `lac-ci` or `cgi` and then stick to that within a given
osmo-bsc.cfg. The reason is that the _Cell Identifier List_ sent in the _BSSMAP
Handover Required_ message must have one single cell identifier type for all
list items. Hence, to be able to send several alternative remote neighbors to
the MSC, the configured cell identifiers must be of the same type. If in doubt,
use the full CGI identifier everywhere.

==== Reconfiguring Neighbors in a Running OsmoBSC

When modifying a cell's neighbor configuration in a telnet VTY session while a cell is already active,
the neighbor configuration will merely be cached in the BSC's local config. To take actual effect, it is
necessary to

- either, re-connect the cell to the BSC (e.g. via `drop bts connection <0-255> oml`)
- or, re-send the System Information using `bts <0-255> resend-system-information`.

=== Configuring Handover Decisions

For a long time, OsmoBSC has supported handover based on reception level
hysteresis (RXLEV) and distance (TA, Timing Advance), known as `algorithm 1`.

Since 2018, OsmoBSC also supports a load-based handover decision algorithm,
known as `algorithm 2`, which also takes cell load, available codecs and
oscillation into consideration. Algorithm 2 had actually been implemented for
the legacy OsmoNITB program many years before the OsmoMSC split, but remained
on a branch, until it was forward-ported to OsmoBSC in 2018.

.What handover decision algorithms take into account
[frame="none",grid="none",cols="^10%,^10%,80%"]
|====
| algorithm 1 | algorithm 2 |
| ✓ | ✓| RXLEV
| ✓ | ✓| RXQUAL
| ✓ | ✓| TA (distance)
| ✓ | ✓| interference (good RXLEV, bad RXQUAL)
|   | ✓| load (nr of free lchans, minimum RXLEV and RXQUAL)
|   | ✓| penalty time to avoid oscillation
|   | ✓| voice rate / codec bias
| ✓ |  | inter-BSC: RXLEV hysteresis
|   | ✓| inter-BSC: only below minimum RXLEV, RXQUAL
|====

==== Common Configuration

Handover is disabled by default; to disable/enable handover, use `handover
(0|1)`.

Once enabled, algorithm 1 is used by default; choose a handover algorithm with
`handover algorithm (1|2)`:

----
network
 # Enable handover
 handover 1

 # Choose algorithm
 handover algorithm 2

 # Tweak parameters for algorithm 2 (optional)
 handover2 min-free-slots tch/f 4
 handover2 penalty-time failed-ho 30
 handover2 retries 1
----

All handover algorithms share a common configuration scheme, with an overlay of
three levels:

* immutable compile-time default values,
* configuration on the `network` level for all cells,
* individual cells' configuration on each `bts` node.

Configuration settings relevant for algorithm 1 start with `handover1`, for
algorithm 2 with `handover2`.

The following example overrides the compile-time default for all cells, and
furthermore sets one particular cell on its own individual setting, for the
`min-free-slots tch/f` value:

----
network
 handover2 min-free-slots tch/f 4
 bts 23
  handover2 min-free-slots tch/f 2
----

The order in which these settings are issued makes no difference for the
overlay; i.e., the following configuration is perfectly identical to the above, and the
individual cell's value remains in force:

----
network
 bts 23
  handover2 min-free-slots tch/f 2
 handover2 min-free-slots tch/f 4
----

Each setting can be reset to a default value with the `default` keyword. When
resetting an individual cell's value, the globally configured value is used.
When resetting the global value, the compile-time default is used (unless
individual cells still have explicit values configured). For example, this
telnet VTY session removes above configuration first from the cell, then from
the global level:

----
OsmoBSC(config)# network
OsmoBSC(config-net)# bts 23
OsmoBSC(config-net-bts)# handover2 min-free-slots tch/f default
% 'handover2 min-free-slots tch/f' setting removed, now is 4
OsmoBSC(config-net-bts)# exit
OsmoBSC(config-net)# handover2 min-free-slots tch/f default
% 'handover2 min-free-slots tch/f' setting removed, now is 0
----

==== Handover Algorithm 1

Algorithm 1 takes action only when RR Measurement Reports are received from a
BTS. As soon as a neighbor's average RXLEV is higher than the current cell's
average RXLEV plus a hysteresis distance, handover is triggered.

If a handover fails, algorithm 1 will again attempt handover to the same cell
with the next Measurement Report received.

Configuration settings relevant for algorithm 1 start with `handover1`. For
further details, please refer to the OsmoBSC VTY Reference
(<<vty-ref-osmobsc>>) or the telnet VTY online documentation. See the
`handover1` settings on the `config-net` and `config-net-bts` nodes.

==== Handover Algorithm 2

Algorithm 2 is specifically designed to distribute load across cells. A
subscriber will not necessarily remain attached to the cell that has the best
RXLEV average, if that cell is heavily loaded and a less loaded neighbor is
above the minimum allowed RXLEV.

Algorithm 2 also features penalty timers to avoid oscillation: for each
subscriber, if handover to a specific neighbor failed (for a configurable
number of retries), a holdoff timer prevents repeated attempts to handover to
that same neighbor. Several hold-off timeouts following specific situations are
configurable (see `handover2 penalty-time` configuration items).

Configuration settings relevant for algorithm 2 start with `handover2`. For
further details, please refer to the OsmoBSC VTY Reference
<<vty-ref-osmobsc>> or the telnet VTY online documentation. See the `handover2`
settings on the `config-net` and `config-net-bts` nodes.

===== Load Distribution

Load distribution is only supported by algorithm 2.

Load distribution occurs:

- explicitly: every N seconds, OsmoBSC considers all local cells and actively
  triggers handover operations to reduce congestion, if any. See
  `min-free-slots` below, and the `congestion-check` setting.

- implicitly: when choosing the best neighbor candidate for a handover
  triggered otherwise, a congested cell (in terms of `min-free-slots`) is only
  used as handover target if there is no alternative that causes less cell
  load.

In either case, load distribution will only occur towards neighbor cells that
adhere to minimum reception levels and distance, see `min rxlev` and `max
distance`.

Load distribution will take effect only for already established channels.
For example, an MS will always first establish a voice call with its current cell choice; in
load situations, it might be moved to another cell shortly after that.
Considering the best neighbor _before_ starting a new voice call might be
desirable, but is currently not implemented. Consider that RXLEV/RXQUAL ratings
are averaged over a given number of measurement reports, so that the neighbor
ratings may not be valid/reliable yet during early call establishment. In
consequence, it is recommended to ensure a sufficient number of unused logical
channels at all times, though there is no single correct configuration for all
situations.

Most important for load distribution are the `min-free-slots tch/f` and
`min-free-slots tch/h` settings. The default is zero, meaning _no_ load
distribution. To enable, set `min-free-slots` >= 1 for `tch/f` and/or `tch/h`
as appropriate. This setting refers to the minimum number of voice channels
that should ideally remain unused in each individual BTS at all times.

NOTE: it is not harmful to configure `min-free-slots` for a TCH kind that is
not actually present. Such settings will simply be ignored.

NOTE: the number of TCH/F timeslots corresponds 1:1 to the number indicated by
`min-free-slots tch/f`, because each TCH/F physical channel has exactly one
logical channel. In contrast, for each TCH/H timeslot, there are two logical
channels, hence `min-free-slots tch/h` corresponds to twice the number of TCH/H
timeslots configured per cell. In fact, a more accurate naming would have been
"min-free-lchans".

Think of the `min-free-slots` setting as the threshold at which load
distribution is considered. If as many logical channels as required by this
setting are available in a given cell, only changes in RXLEV/RXQUAL/TA trigger
handover away from that cell. As soon as less logical channels remain free, the
periodical congestion check attempts to distribute MS to less loaded neighbor
cells. Every time, the one MS that will suffer the least RXLEV loss while still
reducing congestion will be instructed to move first.

If a cell and its neighbors are all loaded past their `min-free-slots` settings,
the algorithmic aim is to improve the percentage of load above the
`min-free-slots` setting: a load-based handover always requires the target cell
to have a lower load percentage after handover than the source cell had before
handover.

The min-free-slots setting is a tradeoff between immediate voice service
availability and optimal reception levels. A sane choice could be:

- Start off with `min-free-slots` set to half the available logical channels.
- Increase `min-free-slots` if you see MS being rejected too often even though
  close neighbors had unused logical channels.
- Decrease `min-free-slots` if you see too many handovers happening for no
  apparent reason.

Choosing the optimal setting is not trivial, consider these examples:

- Configure `min-free-slots` = 1: load distribution to other cells will occur
  exactly when the last available logical channel has become occupied. The next
  time the congestion check runs, at most one handover will occur, so that one
  channel is available again. In the intermediate time, all channels will be
  occupied, and some MS might be denied immediate voice service because of
  that, even though, possibly, other neighbor cells would have provided
  excellent reception levels and were completely unloaded. For those MS that
  are already in an ongoing voice call and are not physically moving, though,
  this almost guarantees service by the closest/best cell.

- Set `min-free-slots` = 2: up to two MS can successfully request voice service
  simultaneously (e.g. one MS is establishing a new voice call while another MS
  is travelling into this cell). Ideally, two slots have been kept open and are
  immediately available. But if a third MS is also traveling into this cell at
  the same time, it will not be able to handover into this cell until load
  distribution has again taken action to make logical channels available. The
  same scenario applies to any arbitrary number of MS asking for voice channels
  simultaneously. The operator needs to choose where to draw the line.

- Set `min-free-slots` >= the number of available channels: as soon as any
  neighbor is less loaded than a given cell, handover will be attempted. But
  imagine there are only two active voice calls on this cell with plenty of
  logical channels still unused, and the closest neighbor rates only just above
  `min rxlev`; then moving one of the MS _for no good reason_ causes all of:
  increased power consumption, reduced reception stability and channel
  management overhead.

NOTE: In the presence of dynamic timeslots to provide GPRS service, the number
of voice timeslots left unused also determines the amount of bandwidth
available for GPRS.

==== External / Inter-BSC Handover Considerations

There currently is a profound difference for inter-BSC handover between
algorithm 1 and 2:

For algorithm 1, inter-BSC handover is triggered as soon as the Measurement
Reports and hysteresis indicate a better neighbor than the current cell,
period.

For algorithm 2, a subscriber is "sticky" to the current BSS, and inter-BSC
handover is only even considered when RXLEV/TA drop below minimum requirements.

- If your network topology is such that each OsmoBSC instance manages a single
  BTS, and you would like to encourage handover between these, choose handover
  algorithm 1. Load balancing will not be available, but RXLEV hysteresis will.

- If your network topology has many cells per BSS, and/or if your BSS
  boundaries in tendency correspond to physical/semantic boundaries that favor
  handover to remain within a BSS, then choose handover algorithm 2.

The reason for the difference between algorithm 1 and 2 for remote-BSS
handovers is, in summary, the young age of the inter-BSC handover feature in
OsmoBSC:

- So far the mechanisms to communicate cell load to remote-BSS available in the
  BSSMAP Handover messages are not implemented, so, a handover due to cell load
  across BSS boundaries would be likely to cause handover oscillation between
  the two BSS (continuous handover of the same MS back and forth between the
  same two cells).
- Algorithm 1 has no `min rxlev` setting.
- Algorithm 1 does not actually use any information besides the Measurement
  Reports, and hence can trivially treat all neighbor cells identically.

=== Advertising 3G/4G neighbors

Despite osmo-bsc not supporting inter-RAT hand-over at this point, it
still makes sense to advertise neighbor cells of other network
technologies like UMTS/UTRAN (3G) and LTE/EUTRAN (4G).  This will help
phones with idle-mode re-selection of the best available radio access
technology (RAT).

For more information on the inter-RAT cell re-selection algorithm and its
parameters, see 3GPP TS 45.008 - particularly Section 6.6.4 describing
measurements on cells of other (non-GSM) RATs.

Such neighbors are advertised as part of the SI2quater (System
Information Type 2quater).

==== UMTS/UTRAN/3G neighbors

In order to advertise a 3G neighbor cell you have to specify the
following properties:

* the UARFCN (UTRAN Absolute Radio Channel Number) on which the cell
  broadcasts
* the Scrambling Code of the cell
* whether or not the cell uses diversity


In the following example, we're configuring a 3G neighbor cell on UARFCN
1234 using the scrambling code 511 with no diversity:

----
network
 bts 0
  si2quater neighbor-list add uarfcn 1234 511 0
----

3G neighbor cells can be removed using the same command, just replacing
`add` with `del`.

==== LTE/EUTRAN/4G neighbors

In order to advertise a 4G neighbor cell you have to specify the
following properties:

* EARFCN (EUTRAN Absolute Radio Channel Number) on which the cell
  broadcasts
* Reselection thresholds towards E-UTRAN cells:

[width="30%"]
|====
| 0 | 0 dB
| 1 | 2 dB
| 2 | 4 dB
| 3 | 6 dB
| ... | ...
| 31 | 62 dB
|====

* Priority of E-UTRAN frequency: 0 = lowest priority, ..., 7 = highest priority
* QRXLEVMIN parameter: Minimum required RX level in the UTRAN FDD cell
  (dBm), see 3GPP TS 25.304.

[width="30%"]
|====
| 0 | -140 dBm
| 1 | -138 dBm
| 2 | -136 dBm
| ... | ...
| 31 | -78 dBm
|====

* Measurement bandwidth in MHz, see 3GPP TS 44.018 and 3GPP TS 44.060.
  This field specifies the minimum value of the channel bandwidth of all
  valid E-UTRAN cells on the specified EARFCN. It is defined by the
  parameter Transmission Bandwidth Configuration, N RB (see 3GPP TS
  36.104). The values indicate the number of resource blocks over which
  the mobile station could measure if the mobile station does not
  support wideband RSRQ measurements (see 3GPP TS 24.008). A mobile
  station supporting wideband RSRQ measurements shall measure over the
  indicated number of resource blocks. The field is coded according to
  the following table:

[width="30%"]
|====
| 0 | N_RB = 6
| 1 | N_RB = 15
| 2 | N_RB = 25
| 3 | N_RB = 50
| 4 | N_RB = 75
| 5 | N_RB = 100
|====

In the following example we're configuring a 4G neighbor on EARFCN 2342
with a higher reselection threshold of 40dB, a lower reselection
threshold of 20dB, priority 5, QRXLEVMIN of -140 dBm and a measurement
bandwidth of 100 resource blocks:

----
network
 bts 0
  si2quater neighbor-list add earfcn 2342 thresh-hi 20 thresh-lo 10 prio 5 qrxlv 0 meas 5
----

4G neighbor cells can be removed using the same command, just replacing
`add` with `del`.

[[ps_handover]]
== PS Handover

Packet Switch Handover is mostly managed by the packet switching nodes such as
PCU, SGSN and GGSN. However, the PCU encounters a similar difficulty to that
explained in <<cs_handover>>: that is, it must find a way to translate
ARFCN+BSIC identifiers provided by the MS into the sort of identifiers
understood by the Core Network (SGSN). These identifiers are in this case
composed of RAC+CI (instead LAC+CI), or more specifically, CGI+RAC (named as
"Packet Switched CGI" or "CGI-PS" from now on for convenience).

Hence, it feels natural extending the <<config_neigh>> storage in the BSC to
also provide Packet Switched related identifiers in order to provide the PCU the
required information to do the translations, instead of duplicating the whole
neighbor information in two different network nodes.

This can be done, similarly to already presented CS related commands in
<<config_neigh>>, by using the `neighbor cgi-ps` VTY command, which allows for
specifying the extra identifier (RAC) required by PS related translations:

.Example: configuring PS neighbors within the local BSS in osmo-bsc.cfg, identified by CGI-PS (CGI+RAC)
----
network
 bts 0
neighbor cgi-ps <MCC> <MNC> <LAC> <RAC> <CI> arfcn <0-1023> bsic (<0-63>|any)
----

This information should already be present by default if one uses the `local BTS
number` to identify the network, as long as that BTS is properly configured to
have GPRS enabled and the RAC code is set by `gprs routing area <0-255>`
command:

.Example: configuring PS neighbors within the local BSS in osmo-bsc.cfg, identified by local BTS number
----
network
 bts 0
  gprs mode gprs
  gprs routing area 45
  neighbor bts 1
  ...
 bts 1
  gprs mode egprs
  gprs routing area 48
  neighbor bts 0
  ...
----

This PS information is solely used by the Neighbor Resolution Service, aimed at
nodes other than BSC itself, and described below.

=== Neighbor Resolution Service CTRL interface

This service is provided in order to provide the PCU a way to translate
ARCFCN+BSIC into CGI-PS in order to use RIM services and accomplish PS
Handovers.

This interface is Osmocom specific, since the standard doesn't provide any
specifications on how to provide this kind of information to the PCU.

Since the PCU can be either BSC-colocated or BTS-colocated (hence on a different
host than BSC), this must be a network-based interface. Since the service is
Osmocom-specific, it was decided to re-use the CTRL interface available in most
Osmocom processes (see <<control>>).

Due to security concerns, the set of CTRL commands available in this
service is configured in a different IP address and port, since the service
needs to be reachable by all PCU under the BSC. This way the user can still
constrain the regular CTRL port (which may contains lots of configuration
related commands) listening in a more constrained address (eg. localhost).

By default, this interface is disabled, and it is enabled by configuring the
desired IP address to bind to (and optionally a different port other than
well-known `4248`):

.Example: Enable and configure Neighbor Resolution Service CTRL interface
----
network
 neighbor-resolution bind 127.0.0.1 5000
----

osmo-pcu will then be able to connect to the BSC and query for resolution during
eg. NACC requests from MS.

The relevant commands are::

* neighbor_resolve_cgi_ps_from_lac_ci:
----
GET neighbor_resolve_cgi_ps_from_lac_ci.<src_lac>.<src_cell_id>.<dst_arfcn>.<dst_bsic>
GET_REPLY <MCC>-<MNC>-<LAC>-<RAC>-<CI>
----

Where the `src_lac` and `src_ci` are provided by BTS/BSC over `PCUIF` interface
during startup (`INFO IND`), and `dst_arfcn` and `dst_bsic` are those of the
neighbor the PCU is willing to request the CGI-PS information. Hence, from the
`src` params the BSC is able to look up the BTS and afterwards apply the
translation of `dst` parameters based on the neighbor information available for
that BTS.
