From 3413cd01d944885e5ae841826d033a777b667987 Mon Sep 17 00:00:00 2001 From: Neels Hofmeyr Date: Mon, 23 Apr 2018 17:05:19 +0200 Subject: wip Change-Id: I5de14b502329212180d2861ae2bf47475fa18f8c --- include/osmocom/bsc/signal.h | 1 + src/libbsc/abis_nm.c | 11 +++++- src/libbsc/bsc_init.c | 2 +- src/libbsc/bts_ipaccess_nanobts.c | 43 ++++++++++++++++++++ src/libbsc/chan_alloc.c | 82 +++++++++++++++++++++++++++++++++------ tests/handover/handover_test.c | 1 + 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; -- cgit v1.2.3