aboutsummaryrefslogtreecommitdiffstats
path: root/include/osmocom/bsc/handover.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/osmocom/bsc/handover.h')
-rw-r--r--include/osmocom/bsc/handover.h81
1 files changed, 30 insertions, 51 deletions
diff --git a/include/osmocom/bsc/handover.h b/include/osmocom/bsc/handover.h
index aa117cc24..322913da4 100644
--- a/include/osmocom/bsc/handover.h
+++ b/include/osmocom/bsc/handover.h
@@ -5,72 +5,38 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/timer.h>
#include <osmocom/gsm/gsm_utils.h>
+#include <osmocom/gsm/gsm0808.h>
#include <osmocom/bsc/neighbor_ident.h>
+#include <osmocom/bsc/gsm_data.h>
+struct gsm_network;
struct gsm_lchan;
struct gsm_bts;
struct gsm_subscriber_connection;
struct gsm_meas_rep mr;
-#define LOGPHOLCHANTOLCHAN(old_lchan, new_lchan, level, fmt, args...) \
- 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, \
- old_lchan->ts->trx->bts->nr, \
- old_lchan->ts->trx->nr, \
- old_lchan->ts->trx->arfcn, \
- old_lchan->ts->nr, \
- old_lchan->nr, \
- gsm_lchant_name(old_lchan->type), \
- gsm48_chan_mode_name(old_lchan->tch_mode), \
- new_lchan->ts->trx->bts->nr, \
- new_lchan->ts->trx->nr, \
- new_lchan->ts->trx->arfcn, \
- new_lchan->ts->nr, \
- new_lchan->nr, \
- gsm_pchan_name(new_lchan->ts->pchan), \
- bsc_subscr_name(old_lchan->conn? old_lchan->conn->bsub : NULL), \
- ## args)
-
-#define LOGPHO(struct_bsc_handover, level, fmt, args ...) \
- LOGPHOLCHANTOLCHAN(struct_bsc_handover->old_lchan, struct_bsc_handover->new_lchan, level, fmt, ## args)
-
-enum hodec_id {
- HODEC_NONE,
- HODEC1 = 1,
- HODEC2 = 2,
+enum handover_result {
+ HO_RESULT_OK,
+ HO_RESULT_FAIL_NO_CHANNEL,
+ HO_RESULT_FAIL_RR_HO_FAIL,
+ HO_RESULT_FAIL_TIMEOUT,
+ HO_RESULT_CONN_RELEASE,
+ HO_RESULT_ERROR,
};
-struct bsc_handover {
- struct llist_head list;
-
- /* Initial details of what is requested */
- struct gsm_lchan *old_lchan;
- struct gsm_bts *new_bts;
- enum gsm_chan_t new_lchan_type;
- bool async;
-
- /* Derived and resulting state */
- bool inter_cell;
- uint8_t ho_ref;
- enum hodec_id from_hodec_id;
- struct gsm_lchan *new_lchan;
- struct osmo_timer_list T3103;
-};
+extern const struct value_string handover_result_names[];
+inline static const char *handover_result_name(enum handover_result val)
+{ return get_value_string(handover_result_names, val); }
-int bsc_handover_start(enum hodec_id from_hodec_id, struct gsm_lchan *old_lchan, struct gsm_bts *new_bts,
- enum gsm_chan_t new_lchan_type);
-int bsc_handover_start_gscon(struct gsm_subscriber_connection *conn);
-void bsc_clear_handover(struct gsm_subscriber_connection *conn, int free_lchan);
-struct gsm_lchan *bsc_handover_pending(struct gsm_lchan *new_lchan);
-
-int bsc_ho_count(struct gsm_bts *bts, bool inter_cell);
+int bts_handover_count(struct gsm_bts *bts, int ho_scopes);
/* Handover decision algorithms' actions to take on incoming handover-relevant events.
*
* All events that are interesting for handover decision are actually communicated by S_LCHAN_* signals,
* so theoretically, each handover algorithm could evaluate those. However, handover_logic.c cleans up
* handover operation state upon receiving some of these signals. To allow a handover decision algorithm
- * to take advantage of e.g. the struct bsc_handover before it is discarded, the handover decision event
+ * to take advantage of e.g. the struct handover before it is discarded, the handover decision event
* handler needs to be invoked before handover_logic.c discards the state. For example, if the handover
* decision wants to place a penalty timer upon a handover failure, it still needs to know which target
* cell the handover failed for; handover_logic.c erases that knowledge on handover failure, since it
@@ -90,13 +56,26 @@ struct handover_decision_callbacks {
int hodec_id;
void (*on_measurement_report)(struct gsm_meas_rep *mr);
- void (*on_ho_chan_activ_nack)(struct bsc_handover *ho);
- void (*on_ho_failure)(struct bsc_handover *ho);
+ void (*on_handover_end)(struct gsm_subscriber_connection *conn, enum handover_result result);
};
void handover_decision_callbacks_register(struct handover_decision_callbacks *hdc);
struct handover_decision_callbacks *handover_decision_callbacks_get(int hodec_id);
+int bsc_tx_bssmap_ho_required(struct gsm_lchan *lchan, const struct gsm0808_cell_id_list2 *target_cells);
+int bsc_tx_bssmap_ho_request_ack(struct gsm_subscriber_connection *conn,
+ struct msgb *rr_ho_command);
+int bsc_tx_bssmap_ho_detect(struct gsm_subscriber_connection *conn);
+enum handover_result bsc_tx_bssmap_ho_complete(struct gsm_subscriber_connection *conn,
+ struct gsm_lchan *lchan);
+void bsc_tx_bssmap_ho_failure(struct gsm_subscriber_connection *conn);
+
struct gsm_bts *bts_by_neighbor_ident(const struct gsm_network *net,
const struct neighbor_ident_key *search_for);
struct neighbor_ident_key *bts_ident_key(const struct gsm_bts *bts);
+
+void handover_parse_inter_bsc_mt(struct gsm_subscriber_connection *conn,
+ struct msgb *ho_request_msg);
+
+void handover_mt_allocate_lchan(struct handover *ho);
+int handover_mt_send_rr_ho_command(struct handover *ho);