aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeels Hofmeyr <neels@hofmeyr.de>2018-04-23 17:05:19 +0200
committerNeels Hofmeyr <neels@hofmeyr.de>2018-04-30 14:16:49 +0200
commit3413cd01d944885e5ae841826d033a777b667987 (patch)
tree1c3a2e900cd8f048526759875454a7f8ed4db8ec
parent7b62154be04c6459199c7659f69c7f8fecae392a (diff)
wip
-rw-r--r--include/osmocom/bsc/signal.h1
-rw-r--r--src/libbsc/abis_nm.c11
-rw-r--r--src/libbsc/bsc_init.c2
-rw-r--r--src/libbsc/bts_ipaccess_nanobts.c43
-rw-r--r--src/libbsc/chan_alloc.c82
-rw-r--r--tests/handover/handover_test.c1
6 files changed, 127 insertions, 13 deletions
diff --git a/include/osmocom/bsc/signal.h b/include/osmocom/bsc/signal.h
index 9c0d5a3de..1dde26772 100644
--- a/include/osmocom/bsc/signal.h
+++ b/include/osmocom/bsc/signal.h
@@ -71,6 +71,7 @@ enum signal_nm {
S_NM_STATECHG_OPER, /* Operational State changed*/
S_NM_STATECHG_ADM, /* Administrative State changed */
S_NM_OM2K_CONF_RES, /* OM2K Configuration Result */
+ S_NM_OPSTART_ACK, /* Received OPSTART ACK, arg is struct abis_om_fom_hdr* */
};
/* SS_LCHAN signals */
diff --git a/src/libbsc/abis_nm.c b/src/libbsc/abis_nm.c
index e3c440813..b2cfa531d 100644
--- a/src/libbsc/abis_nm.c
+++ b/src/libbsc/abis_nm.c
@@ -678,6 +678,14 @@ static int abis_nm_rx_lmt_event(struct msgb *mb)
return 0;
}
+static int abis_nm_rx_opstart_ack(struct msgb *mb)
+{
+ struct abis_om_fom_hdr *foh = msgb_l3(mb);
+ DEBUGPFOH(DNM, foh, "Opstart ACK\n");
+ osmo_signal_dispatch(SS_NM, S_NM_OPSTART_ACK, foh);
+ return 0;
+}
+
bool all_trx_rsl_connected_unlocked(const struct gsm_bts *bts)
{
const struct gsm_bts_trx *trx;
@@ -802,7 +810,7 @@ static int abis_nm_rcvmsg_fom(struct msgb *mb)
ret = abis_nm_rx_lmt_event(mb);
break;
case NM_MT_OPSTART_ACK:
- DEBUGPFOH(DNM, foh, "Opstart ACK\n");
+ abis_nm_rx_opstart_ack(mb);
break;
case NM_MT_SET_CHAN_ATTR_ACK:
DEBUGPFOH(DNM, foh, "Set Channel Attributes ACK\n");
@@ -1896,6 +1904,7 @@ int abis_nm_set_channel_attr(struct gsm_bts_trx_ts *ts, uint8_t chan_comb)
if (bts->type == GSM_BTS_TYPE_BS11)
msgb_tlv_put(msg, 0x59, 1, &zero);
+ DEBUGPFOH(DNM, foh, "%s(): sending %s\n", __func__, msgb_hexdump(msg));
return abis_nm_sendmsg(bts, msg);
}
diff --git a/src/libbsc/bsc_init.c b/src/libbsc/bsc_init.c
index 429d3c7bf..dc0c70300 100644
--- a/src/libbsc/bsc_init.c
+++ b/src/libbsc/bsc_init.c
@@ -354,7 +354,7 @@ static void bootstrap_rsl(struct gsm_bts_trx *trx)
for (i = 0; i < ARRAY_SIZE(trx->ts); i++) {
generate_ma_for_ts(&trx->ts[i]);
- dyn_ts_init(&trx->ts[i]);
+ //dyn_ts_init(&trx->ts[i]);
}
}
diff --git a/src/libbsc/bts_ipaccess_nanobts.c b/src/libbsc/bts_ipaccess_nanobts.c
index d94a87889..3eb7e0e4d 100644
--- a/src/libbsc/bts_ipaccess_nanobts.c
+++ b/src/libbsc/bts_ipaccess_nanobts.c
@@ -294,6 +294,46 @@ static int sw_activ_rep(struct msgb *mb)
return 0;
}
+static struct gsm_bts_trx_ts *gsm_bts_trx_ts(struct gsm_network *net,
+ int bts_nr, int trx_nr, int ts_nr)
+{
+ struct gsm_bts *bts;
+ struct gsm_bts_trx *trx;
+ bts = gsm_bts_num(net, bts_nr);
+ if (!bts)
+ return NULL;
+ trx = gsm_bts_trx_by_nr(bts, trx_nr);
+ if (!trx)
+ return NULL;
+ if (ts_nr < 0 || ts_nr > ARRAY_SIZE(trx->ts))
+ return NULL;
+ return &trx->ts[ts_nr];
+}
+
+static void nm_rx_opstart_ack_chan(struct abis_om_fom_hdr *foh)
+{
+ struct gsm_bts_trx_ts *ts;
+ ts = gsm_bts_trx_ts(bsc_gsmnet, foh->obj_inst.bts_nr, foh->obj_inst.trx_nr, foh->obj_inst.ts_nr);
+ if (!ts) {
+ LOGP(DNM, LOGL_ERROR, "%s Channel OPSTART ACK for non-existent TS\n",
+ abis_nm_dump_foh(foh));
+ return;
+ }
+
+ dyn_ts_init(ts);
+}
+
+static void nm_rx_opstart_ack(struct abis_om_fom_hdr *foh)
+{
+ switch (foh->obj_class) {
+ case NM_OC_CHANNEL:
+ nm_rx_opstart_ack_chan(foh);
+ break;
+ default:
+ break;
+ }
+}
+
/* Callback function to be called every time we receive a signal from NM */
static int bts_ipa_nm_sig_cb(unsigned int subsys, unsigned int signal,
void *handler_data, void *signal_data)
@@ -307,6 +347,9 @@ static int bts_ipa_nm_sig_cb(unsigned int subsys, unsigned int signal,
case S_NM_STATECHG_OPER:
case S_NM_STATECHG_ADM:
return nm_statechg_event(signal, signal_data);
+ case S_NM_OPSTART_ACK:
+ nm_rx_opstart_ack(signal_data);
+ return 0;
default:
break;
}
diff --git a/src/libbsc/chan_alloc.c b/src/libbsc/chan_alloc.c
index e72ab3ca2..8511b8891 100644
--- a/src/libbsc/chan_alloc.c
+++ b/src/libbsc/chan_alloc.c
@@ -37,21 +37,33 @@
bool ts_is_usable(const struct gsm_bts_trx_ts *ts)
{
- if (!trx_is_usable(ts->trx))
+ if (!trx_is_usable(ts->trx)) {
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d not usable\n", ts->trx->bts->nr, ts->trx->nr);
return false;
+ }
/* If a TCH/F_PDCH TS is busy changing, it is already taken or not
* yet available. */
if (ts->pchan == GSM_PCHAN_TCH_F_PDCH) {
- if (ts->flags & TS_F_PDCH_PENDING_MASK)
+ if (ts->flags & TS_F_PDCH_PENDING_MASK) {
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d-ts%d %s"
+ " ts->flags & TS_F_PDCH_PENDING_MASK = 0x%x, not available\n",
+ ts->trx->bts->nr, ts->trx->nr, ts->nr, gsm_pchan_name(ts->pchan),
+ ts->flags & TS_F_PDCH_PENDING_MASK);
return false;
+ }
}
/* If a dynamic channel is busy changing, it is already taken or not
* yet available. */
if (ts->pchan == GSM_PCHAN_TCH_F_TCH_H_PDCH) {
- if (ts->dyn.pchan_is != ts->dyn.pchan_want)
+ if (ts->dyn.pchan_is != ts->dyn.pchan_want) {
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d-ts%d %s"
+ " dyn.pchan_is=%s != dyn.pchan_want=%s, not available\n",
+ ts->trx->bts->nr, ts->trx->nr, ts->nr, gsm_pchan_name(ts->pchan),
+ gsm_pchan_name(ts->dyn.pchan_is), gsm_pchan_name(ts->dyn.pchan_want));
return false;
+ }
}
return true;
@@ -141,8 +153,14 @@ _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
int j, start, stop, dir, ss;
int check_subslots;
- if (!trx_is_usable(trx))
+ if (!trx_is_usable(trx)) {
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d _lc_find_trx(%s as %s) trx not usable\n",
+ trx->bts->nr, trx->nr, gsm_pchan_name(pchan), gsm_pchan_name(dyn_as_pchan));
return NULL;
+ }
+
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d _lc_find_trx(%s as %s)\n",
+ trx->bts->nr, trx->nr, gsm_pchan_name(pchan), gsm_pchan_name(dyn_as_pchan));
if (trx->bts->chan_alloc_reverse) {
/* check TS 7..0 */
@@ -158,10 +176,17 @@ _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
for (j = start; j != stop; j += dir) {
ts = &trx->ts[j];
- if (!ts_is_usable(ts))
+ if (!ts_is_usable(ts)) {
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d _lc_find_trx(%s as %s) ts%d not usable\n",
+ trx->bts->nr, trx->nr, gsm_pchan_name(pchan), gsm_pchan_name(dyn_as_pchan), j);
continue;
- if (ts->pchan != pchan)
+ }
+ if (ts->pchan != pchan) {
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d _lc_find_trx(%s as %s) ts%d is %s != %s\n",
+ trx->bts->nr, trx->nr, gsm_pchan_name(pchan), gsm_pchan_name(dyn_as_pchan), j,
+ gsm_pchan_name(ts->pchan), gsm_pchan_name(pchan));
continue;
+ }
/*
* Allocation for fully dynamic timeslots
@@ -199,13 +224,24 @@ _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
* error states to be sure; in all cases the
* first lchan will be used. */
if (ts->lchan->state != LCHAN_S_NONE
- && ts->lchan->state != LCHAN_S_ACTIVE)
+ && ts->lchan->state != LCHAN_S_ACTIVE) {
+
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d _lc_find_trx(%s as %s) ts%d"
+ " state = %s, not suitable\n",
+ trx->bts->nr, trx->nr, gsm_pchan_name(pchan), gsm_pchan_name(dyn_as_pchan), j,
+ gsm_lchans_name(ts->lchan->state));
continue;
+ }
return ts->lchan;
}
- if (ts->dyn.pchan_is != dyn_as_pchan)
+ if (ts->dyn.pchan_is != dyn_as_pchan) {
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d _lc_find_trx(%s as %s) ts%d"
+ " dyn.pchan_is = %s, want %s, not suitable\n",
+ trx->bts->nr, trx->nr, gsm_pchan_name(pchan), gsm_pchan_name(dyn_as_pchan), j,
+ gsm_pchan_name(ts->dyn.pchan_is), gsm_pchan_name(dyn_as_pchan));
/* not applicable. */
continue;
+ }
/* The requested type matches the dynamic timeslot's
* current mode. A channel may still be available
* (think TCH/H). */
@@ -231,6 +267,10 @@ _lc_find_trx(struct gsm_bts_trx *trx, enum gsm_phys_chan_config pchan,
if (lc->type == GSM_LCHAN_NONE &&
lc->state == LCHAN_S_NONE)
return lc;
+ LOGP(DRLL, LOGL_DEBUG, "bts%d-trx%d _lc_find_trx(%s as %s) ts%d"
+ " ss %d type=%s state=%s, not suitable\n",
+ trx->bts->nr, trx->nr, gsm_pchan_name(pchan), gsm_pchan_name(dyn_as_pchan), j,
+ ss, gsm_lchant_name(lc->type), gsm_lchans_name(lc->state));
}
}
@@ -282,6 +322,8 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type,
struct gsm_lchan *lchan = NULL;
enum gsm_phys_chan_config first, first_cbch, second, second_cbch;
+ LOGP(DRLL, LOGL_DEBUG, "bts-%d lchan_alloc(%s)\n", bts->nr, gsm_lchant_name(type));
+
switch (type) {
case GSM_LCHAN_SDCCH:
if (bts->chan_alloc_reverse) {
@@ -377,18 +419,29 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type,
lchan = _lc_find_bts(bts, GSM_PCHAN_TCH_H);
/* If we don't have TCH/H available, fall-back to TCH/F */
if (!lchan) {
+ LOGP(DRLL, LOGL_DEBUG, "bts-%d lchan_alloc(%s) no TCH/H available, try TCH/F\n", bts->nr, gsm_lchant_name(type));
lchan = _lc_find_bts(bts, GSM_PCHAN_TCH_F);
- if (lchan)
+ if (lchan) {
+ LOGP(DRLL, LOGL_DEBUG, "bts-%d lchan_alloc(%s) found TCH/H %s\n",
+ bts->nr, gsm_lchant_name(type), gsm_lchan_name(lchan));
type = GSM_LCHAN_TCH_F;
+ }
}
/* No dedicated TCH/x available -- try fully dynamic
* TCH/F_TCH/H_PDCH */
if (!lchan) {
+ LOGP(DRLL, LOGL_DEBUG,
+ "bts-%d lchan_alloc(%s) no TCH/H nor TCH/F, try TCH/F_TCH/H_PDCH\n",
+ bts->nr, gsm_lchant_name(type));
lchan = _lc_dyn_find_bts(bts,
GSM_PCHAN_TCH_F_TCH_H_PDCH,
GSM_PCHAN_TCH_H);
- if (lchan)
+ if (lchan) {
+ LOGP(DRLL, LOGL_DEBUG,
+ "bts-%d lchan_alloc(%s) found TCH/F_TCH/H_PDCH %s\n",
+ bts->nr, gsm_lchant_name(type), gsm_lchan_name(lchan));
type = GSM_LCHAN_TCH_H;
+ }
}
/*
* No need to check TCH/F_TCH/H_PDCH channels for TCH/F:
@@ -396,9 +449,16 @@ struct gsm_lchan *lchan_alloc(struct gsm_bts *bts, enum gsm_chan_t type,
*/
/* If we don't have TCH/F either, try dynamic TCH/F_PDCH */
if (!lchan) {
+ LOGP(DRLL, LOGL_DEBUG,
+ "bts-%d lchan_alloc(%s) no TCH/H nor TCH/F nor TCH/F_TCH/H_PDCH, try TCH/F_PDCH\n",
+ bts->nr, gsm_lchant_name(type));
lchan = _lc_find_bts(bts, GSM_PCHAN_TCH_F_PDCH);
- if (lchan)
+ if (lchan) {
+ LOGP(DRLL, LOGL_DEBUG,
+ "bts-%d lchan_alloc(%s) found TCH/F_PDCH %s\n",
+ bts->nr, gsm_lchant_name(type), gsm_lchan_name(lchan));
type = GSM_LCHAN_TCH_F;
+ }
}
break;
default:
diff --git a/tests/handover/handover_test.c b/tests/handover/handover_test.c
index e5cbb9883..459b0e185 100644
--- a/tests/handover/handover_test.c
+++ b/tests/handover/handover_test.c
@@ -240,6 +240,7 @@ static struct gsm_bts *create_bts(int arfcn)
void create_conn(struct gsm_lchan *lchan)
{
+ struct gsm_subscriber_connection *conn;
static unsigned int next_imsi = 0;
char imsi[sizeof(lchan->conn->bsub->imsi)];
struct gsm_network *net = lchan->ts->trx->bts->network;