diff options
Diffstat (limited to 'src/osmo-bts-sysmo/oml.c')
-rw-r--r-- | src/osmo-bts-sysmo/oml.c | 53 |
1 files changed, 51 insertions, 2 deletions
diff --git a/src/osmo-bts-sysmo/oml.c b/src/osmo-bts-sysmo/oml.c index 53ad45ba..056ef5d2 100644 --- a/src/osmo-bts-sysmo/oml.c +++ b/src/osmo-bts-sysmo/oml.c @@ -1,5 +1,5 @@ /* (C) 2011 by Harald Welte <laforge@gnumonks.org> - * (C) 2013 by Holger Hans Peter Freyther + * (C) 2013-2014 by Holger Hans Peter Freyther * * All Rights Reserved * @@ -35,6 +35,7 @@ #include <osmo-bts/amr.h> #include <osmo-bts/bts.h> #include <osmo-bts/bts_model.h> +#include <osmo-bts/handover.h> #include "l1_if.h" #include "femtobts.h" @@ -460,6 +461,10 @@ static const struct sapi_dir pdtch_sapis[] = { #endif }; +static const struct sapi_dir ho_sapis[] = { + { GsmL1_Sapi_Rach, GsmL1_Dir_RxUplink }, +}; + struct lchan_sapis { const struct sapi_dir *sapis; unsigned int num_sapis; @@ -488,6 +493,11 @@ static const struct lchan_sapis sapis_for_lchan[_GSM_LCHAN_MAX] = { }, }; +static const struct lchan_sapis sapis_for_ho = { + .sapis = ho_sapis, + .num_sapis = ARRAY_SIZE(ho_sapis), +}; + static int mph_send_activate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd); static int mph_send_deactivate_req(struct gsm_lchan *lchan, struct sapi_cmd *cmd); static int mph_send_config_ciphering(struct gsm_lchan *lchan, struct sapi_cmd *cmd); @@ -939,6 +949,11 @@ int lchan_activate(struct gsm_lchan *lchan) "%s Trying to activate lchan, but commands in queue\n", gsm_lchan_name(lchan)); + /* override the regular SAPIs if this is the first hand-over + * related activation of the LCHAN */ + if (lchan->ho.active == HANDOVER_ENABLED) + s4l = &sapis_for_ho; + for (i = 0; i < s4l->num_sapis; i++) { int sapi = s4l->sapis[i].sapi; int dir = s4l->sapis[i].dir; @@ -1370,6 +1385,18 @@ static int check_sapi_release(struct gsm_lchan *lchan, int sapi, int dir) return enqueue_sapi_deact_cmd(lchan, sapi, dir); } +static int release_sapis_for_ho(struct gsm_lchan *lchan) +{ + int res = 0; + int i; + + const struct lchan_sapis *s4l = &sapis_for_ho; + + for (i = s4l->num_sapis-1; i >= 0; i--) + res |= check_sapi_release(lchan, + s4l->sapis[i].sapi, s4l->sapis[i].dir); + return res; +} static int lchan_deactivate_sapis(struct gsm_lchan *lchan) { @@ -1389,6 +1416,9 @@ static int lchan_deactivate_sapis(struct gsm_lchan *lchan) res |= check_sapi_release(lchan, s4l->sapis[i].sapi, s4l->sapis[i].dir); } + /* always attempt to disable the RACH burst */ + res |= release_sapis_for_ho(lchan); + /* nothing was queued */ if (res == 0) { LOGP(DL1C, LOGL_ERROR, "%s all SAPIs already released?\n", @@ -1583,7 +1613,26 @@ int bts_model_rsl_chan_act(struct gsm_lchan *lchan, struct tlv_parsed *tp) */ int bts_model_rsl_chan_mod(struct gsm_lchan *lchan) { - return -1; + const struct lchan_sapis *s4l = &sapis_for_lchan[lchan->type]; + unsigned int i; + + if (lchan->ho.active == HANDOVER_NONE) + return -1; + + LOGP(DHO, LOGL_ERROR, "%s modifying channel for handover\n", + gsm_lchan_name(lchan)); + + /* Give up listening to RACH bursts */ + release_sapis_for_ho(lchan); + + /* Activate the normal SAPIs */ + for (i = 0; i < s4l->num_sapis; i++) { + int sapi = s4l->sapis[i].sapi; + int dir = s4l->sapis[i].dir; + enqueue_sapi_act_cmd(lchan, sapi, dir); + } + + return 0; } int bts_model_rsl_chan_rel(struct gsm_lchan *lchan) |