summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndreas Eversberg <jolly@eversberg.eu>2013-05-30 14:49:30 +0200
committerAndreas Eversberg <jolly@eversberg.eu>2013-07-29 12:44:08 +0200
commitedb02c611709c0252aa6535df3e3b10bf6829ce8 (patch)
treeee700817d29cca2a161144189191133877dee6b6
parent587eaf10edadef1356e0fa3be4ba82f2ddf128ac (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--openbsc/include/openbsc/gsm_data.h3
-rw-r--r--openbsc/src/libmsc/gsm_04_08.c10
2 files changed, 13 insertions, 0 deletions
diff --git a/openbsc/include/openbsc/gsm_data.h b/openbsc/include/openbsc/gsm_data.h
index 8822b9b3e..6f6b5b909 100644
--- a/openbsc/include/openbsc/gsm_data.h
+++ b/openbsc/include/openbsc/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/openbsc/src/libmsc/gsm_04_08.c b/openbsc/src/libmsc/gsm_04_08.c
index 1a104fec7..75a77f5f5 100644
--- a/openbsc/src/libmsc/gsm_04_08.c
+++ b/openbsc/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 */