blob: 322913da458c6bf8844c60963d216e01d7d94295 [file] [log] [blame]
Neels Hofmeyra2733ae2017-11-28 00:29:25 +01001#pragma once
Holger Hans Peter Freytherf2553a62010-06-30 12:58:14 +08002
Neels Hofmeyr45e46d22018-02-15 14:10:12 +01003#include <stdint.h>
4
5#include <osmocom/core/linuxlist.h>
6#include <osmocom/core/timer.h>
Harald Welte3561bd42018-01-28 03:04:16 +01007#include <osmocom/gsm/gsm_utils.h>
Neels Hofmeyr31f525e2018-05-14 18:14:15 +02008#include <osmocom/gsm/gsm0808.h>
Neels Hofmeyr45e46d22018-02-15 14:10:12 +01009
Neels Hofmeyr19bed232018-03-22 04:54:57 +010010#include <osmocom/bsc/neighbor_ident.h>
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020011#include <osmocom/bsc/gsm_data.h>
Neels Hofmeyr19bed232018-03-22 04:54:57 +010012
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020013struct gsm_network;
Neels Hofmeyra2733ae2017-11-28 00:29:25 +010014struct gsm_lchan;
15struct gsm_bts;
Holger Hans Peter Freytherf2553a62010-06-30 12:58:14 +080016struct gsm_subscriber_connection;
Harald Welte3561bd42018-01-28 03:04:16 +010017struct gsm_meas_rep mr;
Holger Hans Peter Freytherf2553a62010-06-30 12:58:14 +080018
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020019enum handover_result {
20 HO_RESULT_OK,
21 HO_RESULT_FAIL_NO_CHANNEL,
22 HO_RESULT_FAIL_RR_HO_FAIL,
23 HO_RESULT_FAIL_TIMEOUT,
24 HO_RESULT_CONN_RELEASE,
25 HO_RESULT_ERROR,
Neels Hofmeyr45e46d22018-02-15 14:10:12 +010026};
27
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020028extern const struct value_string handover_result_names[];
29inline static const char *handover_result_name(enum handover_result val)
30{ return get_value_string(handover_result_names, val); }
Neels Hofmeyr45e46d22018-02-15 14:10:12 +010031
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020032int bts_handover_count(struct gsm_bts *bts, int ho_scopes);
Neels Hofmeyr45e46d22018-02-15 14:10:12 +010033
34/* Handover decision algorithms' actions to take on incoming handover-relevant events.
35 *
36 * All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals,
37 * so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up
38 * handover operation state upon receiving some of these signals. To allow a handover decision algorithm
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020039 * to take advantage of e.g. the struct handover before it is discarded, the handover decision event
Neels Hofmeyr45e46d22018-02-15 14:10:12 +010040 * handler needs to be invoked before handover_logic.c discards the state. For example, if the handover
41 * decision wants to place a penalty timer upon a handover failure, it still needs to know which target
42 * cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it
43 * needs to clean up the lchan's handover state.
44 *
45 * The most explicit and safest way to ensure the correct order of event handling is to invoke the
46 * handover decision algorithm's actions from handover_logic.c itself, before cleaning up. This struct
47 * provides the callback functions for this purpose.
48 *
49 * For consistency, also handle signals in this way that aren't actually in danger of interference from
50 * handover_logic.c (which also saves repeated lookup of handover state for lchans). Thus, handover
51 * decision algorithms should not register any signal handler at all.
52 */
53struct handover_decision_callbacks {
54 struct llist_head entry;
55
56 int hodec_id;
57
58 void (*on_measurement_report)(struct gsm_meas_rep *mr);
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020059 void (*on_handover_end)(struct gsm_subscriber_connection *conn, enum handover_result result);
Neels Hofmeyr45e46d22018-02-15 14:10:12 +010060};
61
62void handover_decision_callbacks_register(struct handover_decision_callbacks *hdc);
63struct handover_decision_callbacks *handover_decision_callbacks_get(int hodec_id);
Neels Hofmeyr19bed232018-03-22 04:54:57 +010064
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020065int bsc_tx_bssmap_ho_required(struct gsm_lchan *lchan, const struct gsm0808_cell_id_list2 *target_cells);
66int bsc_tx_bssmap_ho_request_ack(struct gsm_subscriber_connection *conn,
67 struct msgb *rr_ho_command);
68int bsc_tx_bssmap_ho_detect(struct gsm_subscriber_connection *conn);
69enum handover_result bsc_tx_bssmap_ho_complete(struct gsm_subscriber_connection *conn,
70 struct gsm_lchan *lchan);
71void bsc_tx_bssmap_ho_failure(struct gsm_subscriber_connection *conn);
72
Neels Hofmeyr19bed232018-03-22 04:54:57 +010073struct gsm_bts *bts_by_neighbor_ident(const struct gsm_network *net,
74 const struct neighbor_ident_key *search_for);
75struct neighbor_ident_key *bts_ident_key(const struct gsm_bts *bts);
Neels Hofmeyr31f525e2018-05-14 18:14:15 +020076
77void handover_parse_inter_bsc_mt(struct gsm_subscriber_connection *conn,
78 struct msgb *ho_request_msg);
79
80void handover_mt_allocate_lchan(struct handover *ho);
81int handover_mt_send_rr_ho_command(struct handover *ho);