mirror of
https://gitea.osmocom.org/cellular-infrastructure/osmo-pcu.git
synced 2025-11-03 21:53:32 +00:00
Compare commits
9 Commits
zecke/hack
...
jolly/test
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a2ea42fca | ||
|
|
65d589bb24 | ||
|
|
047a1a5e39 | ||
|
|
2d4a477a0f | ||
|
|
a004e6a823 | ||
|
|
783aa4bcb8 | ||
|
|
b6bb55d88c | ||
|
|
7dac4862bc | ||
|
|
72075f0e00 |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -20,3 +20,5 @@ ltmain.sh
|
||||
|
||||
core
|
||||
core.*
|
||||
|
||||
osmoappdesc.pyc
|
||||
|
||||
13
Makefile.am
13
Makefile.am
@@ -1,3 +1,16 @@
|
||||
AUTOMAKE_OPTIONS = foreign dist-bzip2 1.6
|
||||
|
||||
SUBDIRS = src examples
|
||||
EXTRA_DIST = osmoappdesc.py
|
||||
|
||||
if ENABLE_VTY_TESTS
|
||||
python-tests: $(BUILT_SOURCES)
|
||||
osmotestvty.py -p $(top_srcdir) -w $(builddir) -v
|
||||
osmotestconfig.py -p $(top_srcdir) -w $(builddir) -v
|
||||
else
|
||||
python-tests: $(BUILT_SOURCES)
|
||||
@echo "Not running python-based tests (determined at configure-time)"
|
||||
endif
|
||||
|
||||
check-local: $(BUILT_SOURCES)
|
||||
$(MAKE) $(AM_MAKEFLAGS) python-tests
|
||||
|
||||
15
configure.ac
15
configure.ac
@@ -42,6 +42,21 @@ AC_ARG_ENABLE(sysmocom-dsp,
|
||||
AC_MSG_RESULT([$enable_sysmocom_dsp])
|
||||
AM_CONDITIONAL(ENABLE_SYSMODSP, test "x$enable_sysmocom_dsp" = "xyes")
|
||||
|
||||
AC_ARG_ENABLE([vty_tests],
|
||||
AC_HELP_STRING([--enable-vty-tests],
|
||||
[Include the VTY tests in make check [default=no]]),
|
||||
[enable_vty_tests="$enableval"],[enable_vty_tests="no"])
|
||||
if test "x$enable_vty_tests" = "xyes" ; then
|
||||
AM_PATH_PYTHON
|
||||
AC_CHECK_PROG(OSMOTESTVTY_CHECK,osmotestvty.py,yes)
|
||||
if test "x$OSMOTESTVTY_CHECK" != "xyes" ; then
|
||||
AC_MSG_ERROR([Please install osmocom-python to run the vty tests.])
|
||||
fi
|
||||
fi
|
||||
AC_MSG_CHECKING([whether to enable VTY tests])
|
||||
AC_MSG_RESULT([$enable_vty_tests])
|
||||
AM_CONDITIONAL(ENABLE_VTY_TESTS, test "x$enable_vty_tests" = "xyes")
|
||||
|
||||
AC_OUTPUT(
|
||||
src/Makefile
|
||||
examples/Makefile
|
||||
|
||||
26
osmoappdesc.py
Normal file
26
osmoappdesc.py
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
# (C) 2013 by Katerina Barone-Adesi <kat.obsc@gmail.com>
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
app_configs = {
|
||||
"osmo-pcu": ["examples/osmo-pcu.cfg"]
|
||||
}
|
||||
|
||||
apps = [(4240, "src/osmo-pcu", "Osmo-PCU", "osmo-pcu"),
|
||||
]
|
||||
|
||||
vty_command = ["src/osmo-pcu", "-c", "examples/osmo-pcu.cfg"]
|
||||
|
||||
vty_app = apps[0]
|
||||
@@ -196,6 +196,7 @@ int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp)
|
||||
uint8_t trx, ta, ss;
|
||||
int8_t use_trx;
|
||||
struct gprs_rlcmac_tbf *old_tbf;
|
||||
int rc;
|
||||
|
||||
/* check for uplink data, so we copy our informations */
|
||||
tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF);
|
||||
@@ -207,7 +208,19 @@ int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp)
|
||||
old_tbf = tbf;
|
||||
} else {
|
||||
use_trx = -1;
|
||||
ta = 0; /* FIXME: initial TA */
|
||||
/* we already have an uplink TBF, so we use that TA */
|
||||
if (tbf)
|
||||
ta = tbf->ta;
|
||||
else {
|
||||
/* recall TA */
|
||||
rc = recall_timing_advance(tlli);
|
||||
if (rc < 0) {
|
||||
LOGP(DRLCMAC, LOGL_NOTICE, "TA unknown"
|
||||
", assuming 0\n");
|
||||
ta = 0;
|
||||
} else
|
||||
ta = rc;
|
||||
}
|
||||
ss = 1; /* PCH assignment only allows one timeslot */
|
||||
old_tbf = NULL;
|
||||
}
|
||||
@@ -455,7 +468,7 @@ int bssgp_prim_cb(struct osmo_prim_hdr *oph, void *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb *msg, uint16_t bvci)
|
||||
int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb *msg, uint16_t bvci)
|
||||
{
|
||||
int rc = 0;
|
||||
switch (event) {
|
||||
@@ -577,18 +590,11 @@ int gprs_bssgp_create(uint16_t local_port, uint32_t sgsn_ip,
|
||||
if (bctx)
|
||||
return 0; /* if already created, must return 0: no error */
|
||||
|
||||
bssgp_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_pcu_ctx);
|
||||
if (!bssgp_nsi) {
|
||||
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
gprs_ns_vty_init(bssgp_nsi);
|
||||
bssgp_nsi->nsip.local_port = local_port;
|
||||
rc = gprs_ns_nsip_listen(bssgp_nsi);
|
||||
if (rc < 0) {
|
||||
LOGP(DBSSGP, LOGL_ERROR, "Failed to create socket\n");
|
||||
gprs_ns_destroy(bssgp_nsi);
|
||||
bssgp_nsi = NULL;
|
||||
gprs_ns_close(bssgp_nsi);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@@ -599,17 +605,16 @@ int gprs_bssgp_create(uint16_t local_port, uint32_t sgsn_ip,
|
||||
nsvc = gprs_ns_nsip_connect(bssgp_nsi, &dest, nsei, nsvci);
|
||||
if (!nsvc) {
|
||||
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NSVCt\n");
|
||||
gprs_ns_destroy(bssgp_nsi);
|
||||
bssgp_nsi = NULL;
|
||||
gprs_ns_close(bssgp_nsi);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
bctx = btsctx_alloc(bvci, nsei);
|
||||
if (!bctx) {
|
||||
LOGP(DBSSGP, LOGL_ERROR, "Failed to create BSSGP context\n");
|
||||
gprs_nsvc_delete(nsvc);
|
||||
nsvc = NULL;
|
||||
gprs_ns_destroy(bssgp_nsi);
|
||||
bssgp_nsi = NULL;
|
||||
gprs_ns_close(bssgp_nsi);
|
||||
return -EINVAL;
|
||||
}
|
||||
bctx->ra_id.mcc = spoof_mcc ? : mcc;
|
||||
@@ -624,13 +629,12 @@ int gprs_bssgp_create(uint16_t local_port, uint32_t sgsn_ip,
|
||||
|
||||
bvc_timer.cb = bvc_timeout;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void gprs_bssgp_destroy(void)
|
||||
{
|
||||
if (!bssgp_nsi)
|
||||
if (!bctx)
|
||||
return;
|
||||
|
||||
if (osmo_timer_pending(&bvc_timer))
|
||||
@@ -638,6 +642,7 @@ void gprs_bssgp_destroy(void)
|
||||
|
||||
osmo_signal_unregister_handler(SS_L_NS, nsvc_signal_cb, NULL);
|
||||
|
||||
gprs_nsvc_delete(nsvc);
|
||||
nsvc = NULL;
|
||||
|
||||
/* FIXME: move this to libgb: btsctx_free() */
|
||||
@@ -647,7 +652,6 @@ void gprs_bssgp_destroy(void)
|
||||
|
||||
/* FIXME: blocking... */
|
||||
|
||||
gprs_ns_destroy(bssgp_nsi);
|
||||
bssgp_nsi = NULL;
|
||||
gprs_ns_close(bssgp_nsi);
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,8 @@ int gprs_bssgp_pcu_rx_sign(struct msgb *msg, struct tlv_parsed *tp, struct bssgp
|
||||
|
||||
int gprs_bssgp_pcu_rcvmsg(struct msgb *msg);
|
||||
|
||||
int sgsn_ns_cb(enum gprs_ns_evt event, struct gprs_nsvc *nsvc, struct msgb *msg, uint16_t bvci);
|
||||
|
||||
int gprs_bssgp_create(uint16_t local_port, uint32_t sgsn_ip, uint16_t
|
||||
sgsn_port, uint16_t nsei, uint16_t nsvci, uint16_t bvci,
|
||||
uint16_t mcc, uint16_t mnc, uint16_t lac, uint16_t rac,
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
/* default categories */
|
||||
|
||||
static const struct log_info_cat default_categories[] = {
|
||||
{"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_INFO, 0},
|
||||
{"DCSN1", "\033[1;31m", "Concrete Syntax Notation One (CSN1)", LOGL_ERROR, 0},
|
||||
{"DL1IF", "\033[1;32m", "GPRS PCU L1 interface (L1IF)", LOGL_INFO, 1},
|
||||
{"DRLCMAC", "\033[0;33m", "GPRS RLC/MAC layer (RLCMAC)", LOGL_NOTICE, 1},
|
||||
{"DRLCMACDATA", "\033[0;33m", "GPRS RLC/MAC layer Data (RLCMAC)", LOGL_NOTICE, 1},
|
||||
@@ -41,6 +41,7 @@ static const struct log_info_cat default_categories[] = {
|
||||
{"DRLCMACUL", "\033[1;36m", "GPRS RLC/MAC layer Uplink (RLCMAC)", LOGL_NOTICE, 1},
|
||||
{"DRLCMACSCHED", "\033[0;36m", "GPRS RLC/MAC layer Scheduling (RLCMAC)", LOGL_NOTICE, 1},
|
||||
{"DRLCMACMEAS", "\033[1;31m", "GPRS RLC/MAC layer Measurements (RLCMAC)", LOGL_INFO, 1},
|
||||
{"DNS","\033[0;34m", "GPRS Network Service (NS)", LOGL_INFO , 1},
|
||||
{"DBSSGP","\033[1;34m", "GPRS BSS Gateway Protocol (BSSGP)", LOGL_INFO , 1},
|
||||
{"DPCU", "\033[1;35m", "GPRS Packet Control Unit (PCU)", LOGL_NOTICE, 1},
|
||||
};
|
||||
|
||||
@@ -39,6 +39,7 @@ enum {
|
||||
DRLCMACUL,
|
||||
DRLCMACSCHED,
|
||||
DRLCMACMEAS,
|
||||
DNS,
|
||||
DBSSGP,
|
||||
DPCU,
|
||||
aDebug_LastEntry
|
||||
|
||||
@@ -1819,3 +1819,107 @@ int gprs_rlcmac_paging_request(uint8_t *ptmsi, uint16_t ptmsi_len,
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* timing advance memory
|
||||
*/
|
||||
|
||||
/* enable to debug timing advance memory */
|
||||
//#define DEBUG_TA
|
||||
|
||||
static LLIST_HEAD(gprs_rlcmac_ta_list);
|
||||
static int gprs_rlcmac_ta_num = 0;
|
||||
|
||||
struct gprs_rlcmac_ta {
|
||||
struct llist_head list;
|
||||
uint32_t tlli;
|
||||
uint8_t ta;
|
||||
};
|
||||
|
||||
/* remember timing advance of a given TLLI */
|
||||
int remember_timing_advance(uint32_t tlli, uint8_t ta)
|
||||
{
|
||||
struct gprs_rlcmac_ta *ta_entry;
|
||||
|
||||
/* check for existing entry */
|
||||
llist_for_each_entry(ta_entry, &gprs_rlcmac_ta_list, list) {
|
||||
if (ta_entry->tlli == tlli) {
|
||||
#ifdef DEBUG_TA
|
||||
fprintf(stderr, "update %08x %d\n", tlli, ta);
|
||||
#endif
|
||||
ta_entry->ta = ta;
|
||||
/* relink to end of list */
|
||||
llist_del(&ta_entry->list);
|
||||
llist_add_tail(&ta_entry->list, &gprs_rlcmac_ta_list);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEBUG_TA
|
||||
fprintf(stderr, "remember %08x %d\n", tlli, ta);
|
||||
#endif
|
||||
/* if list is full, remove oldest entry */
|
||||
if (gprs_rlcmac_ta_num == 30) {
|
||||
ta_entry = llist_entry(gprs_rlcmac_ta_list.next,
|
||||
struct gprs_rlcmac_ta, list);
|
||||
llist_del(&ta_entry->list);
|
||||
talloc_free(ta_entry);
|
||||
gprs_rlcmac_ta_num--;
|
||||
}
|
||||
|
||||
/* create new TA entry */
|
||||
ta_entry = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_ta);
|
||||
if (!ta_entry)
|
||||
return -ENOMEM;
|
||||
|
||||
ta_entry->tlli = tlli;
|
||||
ta_entry->ta = ta;
|
||||
llist_add_tail(&ta_entry->list, &gprs_rlcmac_ta_list);
|
||||
gprs_rlcmac_ta_num++;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int recall_timing_advance(uint32_t tlli)
|
||||
{
|
||||
struct gprs_rlcmac_ta *ta_entry;
|
||||
uint8_t ta;
|
||||
|
||||
llist_for_each_entry(ta_entry, &gprs_rlcmac_ta_list, list) {
|
||||
if (ta_entry->tlli == tlli) {
|
||||
ta = ta_entry->ta;
|
||||
#ifdef DEBUG_TA
|
||||
fprintf(stderr, "recall %08x %d\n", tlli, ta);
|
||||
#endif
|
||||
return ta;
|
||||
}
|
||||
}
|
||||
#ifdef DEBUG_TA
|
||||
fprintf(stderr, "no entry for %08x\n", tlli);
|
||||
#endif
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
int flush_timing_advance(void)
|
||||
{
|
||||
struct gprs_rlcmac_ta *ta_entry;
|
||||
int count = 0;
|
||||
|
||||
while (!llist_empty(&gprs_rlcmac_ta_list)) {
|
||||
ta_entry = llist_entry(gprs_rlcmac_ta_list.next,
|
||||
struct gprs_rlcmac_ta, list);
|
||||
#ifdef DEBUG_TA
|
||||
fprintf(stderr, "flush entry %08x %d\n", ta_entry->tlli,
|
||||
ta_entry->ta);
|
||||
#endif
|
||||
llist_del(&ta_entry->list);
|
||||
talloc_free(ta_entry);
|
||||
count++;
|
||||
}
|
||||
gprs_rlcmac_ta_num = 0;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
@@ -374,6 +374,8 @@ void tbf_timer_cb(void *_tbf);
|
||||
|
||||
int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf);
|
||||
|
||||
int gprs_rlcmac_sba_timeout(struct gprs_rlcmac_sba *sba);
|
||||
|
||||
int gprs_rlcmac_rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta);
|
||||
|
||||
int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts,
|
||||
@@ -421,6 +423,12 @@ struct gprs_rlcmac_paging *gprs_rlcmac_dequeue_paging(
|
||||
struct msgb *gprs_rlcmac_send_packet_paging_request(
|
||||
struct gprs_rlcmac_pdch *pdch);
|
||||
|
||||
int remember_timing_advance(uint32_t tlli, uint8_t ta);
|
||||
|
||||
int recall_timing_advance(uint32_t tlli);
|
||||
|
||||
int flush_timing_advance(void);
|
||||
|
||||
extern "C" {
|
||||
#endif
|
||||
int alloc_algorithm_a(struct gprs_rlcmac_tbf *old_tbf,
|
||||
|
||||
@@ -206,6 +206,15 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int gprs_rlcmac_sba_timeout(struct gprs_rlcmac_sba *sba)
|
||||
{
|
||||
LOGP(DRLCMAC, LOGL_NOTICE, "Poll timeout for SBA\n");
|
||||
llist_del(&sba->list);
|
||||
talloc_free(sba);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap)
|
||||
{
|
||||
int i;
|
||||
@@ -263,6 +272,7 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts,
|
||||
int8_t tfi = 0; /* must be signed */
|
||||
uint32_t tlli = 0;
|
||||
struct gprs_rlcmac_tbf *tbf;
|
||||
struct gprs_rlcmac_sba *sba;
|
||||
int rc;
|
||||
|
||||
RlcMacUplink_t * ul_control_block = (RlcMacUplink_t *)talloc_zero(tall_pcu_ctx, RlcMacUplink_t);
|
||||
@@ -420,6 +430,7 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts,
|
||||
if (!tbf) {
|
||||
uint8_t ms_class = 0;
|
||||
struct gprs_rlcmac_tbf *dl_tbf;
|
||||
uint8_t ta;
|
||||
|
||||
if ((dl_tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) {
|
||||
LOGP(DRLCMACUL, LOGL_NOTICE, "Got RACH from "
|
||||
@@ -431,12 +442,28 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts,
|
||||
LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF "
|
||||
"in packet ressource request of single "
|
||||
"block, so we provide one:\n");
|
||||
sba = sba_find(trx, ts, fn);
|
||||
if (!sba) {
|
||||
LOGP(DRLCMAC, LOGL_NOTICE, "MS requests UL TBF "
|
||||
"in packet ressource request of single "
|
||||
"block, but there is no resource request "
|
||||
"scheduled!\n");
|
||||
rc = recall_timing_advance(tlli);
|
||||
if (rc >= 0)
|
||||
ta = rc;
|
||||
else
|
||||
ta = 0;
|
||||
} else {
|
||||
ta = sba->ta;
|
||||
remember_timing_advance(tlli, ta);
|
||||
llist_del(&sba->list);
|
||||
talloc_free(sba);
|
||||
}
|
||||
if (ul_control_block->u.Packet_Resource_Request.Exist_MS_Radio_Access_capability)
|
||||
ms_class = get_ms_class_by_capability(&ul_control_block->u.Packet_Resource_Request.MS_Radio_Access_capability);
|
||||
if (!ms_class)
|
||||
LOGP(DRLCMAC, LOGL_NOTICE, "MS does not give us a class.\n");
|
||||
tbf = alloc_ul_tbf(trx, ms_class, tlli, 0, NULL);
|
||||
#warning FIXME TA!!!
|
||||
tbf = alloc_ul_tbf(trx, ms_class, tlli, ta, NULL);
|
||||
if (!tbf)
|
||||
break;
|
||||
/* set control ts to current MS's TS, until assignment complete */
|
||||
@@ -469,6 +496,17 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts,
|
||||
LOGP(DRLCMAC, LOGL_ERROR, "RX: [PCU <- BTS] %s TFI: %u TLLI: 0x%08x FIXME: Packet ressource request\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf->tlli);
|
||||
break;
|
||||
case MT_PACKET_MEASUREMENT_REPORT:
|
||||
sba = sba_find(trx, ts, fn);
|
||||
if (!sba) {
|
||||
LOGP(DRLCMAC, LOGL_NOTICE, "MS send measurement "
|
||||
"in packet ressource request of single "
|
||||
"block, but there is no resource request "
|
||||
"scheduled!\n");
|
||||
} else {
|
||||
remember_timing_advance(ul_control_block->u.Packet_Measurement_Report.TLLI, sba->ta);
|
||||
llist_del(&sba->list);
|
||||
talloc_free(sba);
|
||||
}
|
||||
gprs_rlcmac_meas_rep(&ul_control_block->u.Packet_Measurement_Report);
|
||||
break;
|
||||
default:
|
||||
@@ -888,6 +926,8 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts,
|
||||
}
|
||||
/* mark TLLI valid now */
|
||||
tbf->tlli_valid = 1;
|
||||
/* store current timing advance */
|
||||
remember_timing_advance(tbf->tlli, tbf->ta);
|
||||
/* already have TLLI, but we stille get another one */
|
||||
} else if (rh->ti) {
|
||||
uint32_t tlli;
|
||||
|
||||
@@ -78,11 +78,8 @@ uint32_t sched_sba(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr)
|
||||
sba_fn ++;
|
||||
sba_fn = sba_fn % 2715648;
|
||||
sba = sba_find(trx, ts, sba_fn);
|
||||
if (sba) {
|
||||
llist_del(&sba->list);
|
||||
talloc_free(sba);
|
||||
if (sba)
|
||||
return sba_fn;
|
||||
}
|
||||
|
||||
return 0xffffffff;
|
||||
}
|
||||
@@ -260,7 +257,7 @@ int gprs_rlcmac_rcv_rts_block(uint8_t trx, uint8_t ts, uint16_t arfcn,
|
||||
? "UL" : "DL", poll_tbf->tfi);
|
||||
/* use free USF */
|
||||
/* else. check for sba */
|
||||
else if ((sba_fn = sched_sba(trx, ts, fn, block_nr) != 0xffffffff))
|
||||
else if ((sba_fn = sched_sba(trx, ts, fn, block_nr)) != 0xffffffff)
|
||||
LOGP(DRLCMACSCHED, LOGL_DEBUG, "Received RTS for PDCH: TRX=%d "
|
||||
"TS=%d FN=%d block_nr=%d scheduling free USF for "
|
||||
"single block allocation at FN=%d\n", trx, ts, fn,
|
||||
|
||||
@@ -516,6 +516,7 @@ bssgp_failed:
|
||||
static int pcu_rx_time_ind(struct gsm_pcu_if_time_ind *time_ind)
|
||||
{
|
||||
struct gprs_rlcmac_tbf *tbf;
|
||||
struct gprs_rlcmac_sba *sba, *sba2;
|
||||
uint32_t elapsed;
|
||||
uint8_t fn13 = time_ind->fn % 13;
|
||||
|
||||
@@ -531,18 +532,27 @@ static int pcu_rx_time_ind(struct gsm_pcu_if_time_ind *time_ind)
|
||||
/* check for poll timeout */
|
||||
llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) {
|
||||
if (tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) {
|
||||
elapsed = (frame_number - tbf->poll_fn) % 2715648;
|
||||
if (elapsed >= 20 && elapsed < 200)
|
||||
elapsed = (frame_number + 2715648 - tbf->poll_fn)
|
||||
% 2715648;
|
||||
if (elapsed >= 20 && elapsed < 2715400)
|
||||
gprs_rlcmac_poll_timeout(tbf);
|
||||
}
|
||||
}
|
||||
llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) {
|
||||
if (tbf->poll_state == GPRS_RLCMAC_POLL_SCHED) {
|
||||
elapsed = (frame_number - tbf->poll_fn) % 2715648;
|
||||
if (elapsed >= 20 && elapsed < 200)
|
||||
elapsed = (frame_number + 2715648 - tbf->poll_fn)
|
||||
% 2715648;
|
||||
if (elapsed >= 20 && elapsed < 2715400)
|
||||
gprs_rlcmac_poll_timeout(tbf);
|
||||
}
|
||||
}
|
||||
llist_for_each_entry_safe(sba, sba2, &gprs_rlcmac_sbas, list) {
|
||||
elapsed = (frame_number + 2715648 - sba->fn) % 2715648;
|
||||
if (elapsed >= 20 && elapsed < 2715400) {
|
||||
/* sba will be freed here */
|
||||
gprs_rlcmac_sba_timeout(sba);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
#include <unistd.h>
|
||||
#include <getopt.h>
|
||||
#include <signal.h>
|
||||
#include <sched.h>
|
||||
extern "C" {
|
||||
#include "pcu_vty.h"
|
||||
#include <osmocom/vty/telnet_interface.h>
|
||||
@@ -41,6 +42,7 @@ extern struct vty_app_info pcu_vty_info;
|
||||
void *tall_pcu_ctx;
|
||||
extern void *bv_tall_ctx;
|
||||
static int quit = 0;
|
||||
static int rt_prio = -1;
|
||||
|
||||
#ifdef DEBUG_DIAGRAM
|
||||
extern struct timeval diagram_time;
|
||||
@@ -56,6 +58,8 @@ static void print_help()
|
||||
"provided by BTS\n"
|
||||
" -n --mnc MNC use given MNC instead of value "
|
||||
"provided by BTS\n"
|
||||
" -r --realtime PRIO Use SCHED_RR with the specified "
|
||||
"priority\n"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -70,10 +74,11 @@ static void handle_options(int argc, char **argv)
|
||||
{ "mcc", 1, 0, 'm' },
|
||||
{ "mnc", 1, 0, 'n' },
|
||||
{ "version", 0, 0, 'V' },
|
||||
{ "realtime", 1, 0, 'r' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
c = getopt_long(argc, argv, "hc:m:n:V",
|
||||
c = getopt_long(argc, argv, "hc:m:n:Vr:",
|
||||
long_options, &option_idx);
|
||||
if (c == -1)
|
||||
break;
|
||||
@@ -97,6 +102,9 @@ static void handle_options(int argc, char **argv)
|
||||
print_version(1);
|
||||
exit(0);
|
||||
break;
|
||||
case 'r':
|
||||
rt_prio = atoi(optarg);
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown option '%c'\n", c);
|
||||
exit(0);
|
||||
@@ -114,6 +122,7 @@ void sighandler(int sigset)
|
||||
|
||||
switch (sigset) {
|
||||
case SIGINT:
|
||||
case SIGTERM:
|
||||
/* If another signal is received afterwards, the program
|
||||
* is terminated without finishing shutdown process.
|
||||
*/
|
||||
@@ -140,6 +149,7 @@ void sighandler(int sigset)
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct sched_param param;
|
||||
struct gprs_rlcmac_bts *bts;
|
||||
int rc;
|
||||
|
||||
@@ -168,10 +178,19 @@ int main(int argc, char *argv[])
|
||||
msgb_set_talloc_ctx(tall_pcu_ctx);
|
||||
|
||||
osmo_init_logging(&gprs_log_info);
|
||||
bssgp_set_log_ss(DBSSGP);
|
||||
gprs_ns_set_log_ss(DNS);
|
||||
|
||||
vty_init(&pcu_vty_info);
|
||||
pcu_vty_init(&gprs_log_info);
|
||||
|
||||
bssgp_nsi = gprs_ns_instantiate(&sgsn_ns_cb, tall_pcu_ctx);
|
||||
if (!bssgp_nsi) {
|
||||
LOGP(DBSSGP, LOGL_ERROR, "Failed to create NS instance\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
gprs_ns_vty_init(bssgp_nsi);
|
||||
|
||||
handle_options(argc, argv);
|
||||
if ((!!spoof_mcc) + (!!spoof_mnc) == 1) {
|
||||
fprintf(stderr, "--mcc and --mnc must be specified "
|
||||
@@ -211,6 +230,18 @@ int main(int argc, char *argv[])
|
||||
signal(SIGUSR1, sighandler);
|
||||
signal(SIGUSR2, sighandler);
|
||||
|
||||
/* enable realtime priority for us */
|
||||
if (rt_prio != -1) {
|
||||
memset(¶m, 0, sizeof(param));
|
||||
param.sched_priority = rt_prio;
|
||||
rc = sched_setscheduler(getpid(), SCHED_RR, ¶m);
|
||||
if (rc != 0) {
|
||||
fprintf(stderr, "Setting SCHED_RR priority(%d) failed: %s\n",
|
||||
param.sched_priority, strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
while (!quit) {
|
||||
osmo_gsm_timers_check();
|
||||
osmo_gsm_timers_prepare();
|
||||
@@ -226,6 +257,11 @@ int main(int argc, char *argv[])
|
||||
|
||||
pcu_l1if_close();
|
||||
|
||||
gprs_ns_destroy(bssgp_nsi);
|
||||
bssgp_nsi = NULL;
|
||||
|
||||
flush_timing_advance();
|
||||
|
||||
talloc_free(gprs_rlcmac_bts);
|
||||
|
||||
talloc_report_full(tall_pcu_ctx, stderr);
|
||||
|
||||
Reference in New Issue
Block a user