== 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); - 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. At the time of writing, OsmoMSC's inter-BSC handover support is not complete yet, so OsmoBSC can perform handover between separate BSS only in conjunction with a 3rd party MSC implementation. .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) | - |==== === 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). Each BTS is told by the BSC which cells identified by ARFCN+BSIC are its adjacent cells. Via System Information, each MS receives a list of these ARFCN+BSIC, and the MS then return measurements of reception levels. 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 capabilites. 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 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 may actually be 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. If the voice codec has remained unchanged, the MSC/MNCC may not even be notified that anything has happened at all. ==== External / Inter-BSC Handover If the adjacent 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, and 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 <>). For simplicity, this description focuses on LAC+CI identification. The most obvious reason for using LAC+CI 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. The consequence of this is that - 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. === 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, 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 | | ✓ | | 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. To maintain a backwards compatible configuration file format, this is still the case: as soon as no explicit neighbor cell is configured with a `neighbor` command (either none was configured, or all configured neighbors 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 rather switch off handover for that cell with `handover 0`. An alternative solution is to set `neighbor-list mode manual` and not configure any `neighbor-list` entries. ==== 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 other cell. The idea is to ease generating the neighbor configuration automatically, since local-BSS and remote-BSS neighbors then share identical configuration formatting. For human readability and maintainability, it may instead be desirable to use the `neighbor bts <0-255>` format. .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 ---- If the cell identification matches a local cell, OsmoBSC will report errors if the provided ARFCN+BSIC do not match. ==== 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 has `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., this 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 (<>) or the telnet VTY online documentation. ==== 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 <> or the telnet VTY online documentation. ===== 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 voice channels. 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 equal load: a load-based handover will never cause the target cell to be more congested than the source cell. 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.