aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-05-30 14:49:30 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2017-12-01 03:37:43 +0100
commit8b24130c0b14c57ca565f458830f20e5811fd48c (patch)
tree2ab2b9e4ef69daf4f578a5be87efa56efce5966e
parent3d2d487410377532030e328adeff1a224a884fb8 (diff)
HO: Store bearer capabilities of MS at connection structure for later use
Handover might require change in codec, especially when switching between AFS (AMR on TCH/F) and AHS (AMR on TCH/H). In this case the handover decision must know if a different target rate is supported by the MS or not.
-rw-r--r--include/osmocom/bsc/gsm_data.h3
-rw-r--r--src/libmsc/gsm_04_08.c10
2 files changed, 13 insertions, 0 deletions
diff --git a/include/osmocom/bsc/gsm_data.h b/include/osmocom/bsc/gsm_data.h
index 8822b9b3e..6f6b5b909 100644
--- a/include/osmocom/bsc/gsm_data.h
+++ b/include/osmocom/bsc/gsm_data.h
@@ -140,6 +140,9 @@ struct gsm_subscriber_connection {
/* penalty timers for handover */
struct llist_head ho_penalty_timers;
+
+ /* phone's bearer capabilities */
+ struct gsm_mncc_bearer_cap bcap;
};
diff --git a/src/libmsc/gsm_04_08.c b/src/libmsc/gsm_04_08.c
index 1a104fec7..75a77f5f5 100644
--- a/src/libmsc/gsm_04_08.c
+++ b/src/libmsc/gsm_04_08.c
@@ -1947,6 +1947,8 @@ static int gsm48_cc_rx_setup(struct gsm_trans *trans, struct msgb *msg)
setup.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&setup.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ memcpy(&trans->conn->bcap, &setup.bearer_cap,
+ sizeof(struct gsm_mncc_bearer_cap));
apply_codec_restrictions(trans->conn->bts, &setup.bearer_cap);
}
/* facility */
@@ -2101,6 +2103,8 @@ static int gsm48_cc_rx_call_conf(struct gsm_trans *trans, struct msgb *msg)
call_conf.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&call_conf.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ memcpy(&trans->conn->bcap, &call_conf.bearer_cap,
+ sizeof(struct gsm_mncc_bearer_cap));
apply_codec_restrictions(trans->conn->bts, &call_conf.bearer_cap);
}
/* cause */
@@ -2790,6 +2794,8 @@ static int gsm48_cc_rx_modify(struct gsm_trans *trans, struct msgb *msg)
modify.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ memcpy(&trans->conn->bcap, &modify.bearer_cap,
+ sizeof(struct gsm_mncc_bearer_cap));
apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
@@ -2833,6 +2839,8 @@ static int gsm48_cc_rx_modify_complete(struct gsm_trans *trans, struct msgb *msg
modify.fields |= MNCC_F_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ memcpy(&trans->conn->bcap, &modify.bearer_cap,
+ sizeof(struct gsm_mncc_bearer_cap));
apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
@@ -2874,6 +2882,8 @@ static int gsm48_cc_rx_modify_reject(struct gsm_trans *trans, struct msgb *msg)
modify.fields |= GSM48_IE_BEARER_CAP;
gsm48_decode_bearer_cap(&modify.bearer_cap,
TLVP_VAL(&tp, GSM48_IE_BEARER_CAP)-1);
+ memcpy(&trans->conn->bcap, &modify.bearer_cap,
+ sizeof(struct gsm_mncc_bearer_cap));
apply_codec_restrictions(trans->conn->bts, &modify.bearer_cap);
}
/* cause */