aboutsummaryrefslogtreecommitdiffstats
path: root/src/osmo-bts-sysmo/oml.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/osmo-bts-sysmo/oml.c')
-rw-r--r--src/osmo-bts-sysmo/oml.c53
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)