From Ivan.Kluchnikov at fairwaves.ru Tue Oct 1 06:03:39 2013 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Tue, 1 Oct 2013 10:03:39 +0400 Subject: [PATCH 1/3] tfi: The tfi_alloc doesn't allocate anything, rename the function In-Reply-To: <20130929052519.GA25274@xiaoyu.lan> References: <1377428496-21721-1-git-send-email-hfreyther@sysmocom.de> <20130929052519.GA25274@xiaoyu.lan> Message-ID: Hi Holger, I looked through these patches. Do you want to merge only these three patches or may be it makes sense to merge all patches from zecke/features/tbf-cleanup branch? 2013/9/29 Holger Hans Peter Freyther : > On Sun, Aug 25, 2013 at 01:01:34PM +0200, Holger Hans Peter Freyther wrote: >> From: Holger Hans Peter Freyther > > Hi, > > >> Call things by what they do and this function doesn't allocate >> anything but it is searching for the first unallocated tbf index. > > it appears that this patchset has not ben reviewed/merged. Do you > have time to review/test/merge these cleanups? > > holger > > > -- > - Holger Freyther http://www.sysmocom.de/ > ======================================================================= > * sysmocom - systems for mobile communications GmbH > * Schivelbeiner Str. 5 > * 10439 Berlin, Germany > * Sitz / Registered office: Berlin, HRB 134158 B > * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte > > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From hfreyther at sysmocom.de Tue Oct 1 07:02:28 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Tue, 1 Oct 2013 09:02:28 +0200 Subject: [PATCH 1/3] tfi: The tfi_alloc doesn't allocate anything, rename the function In-Reply-To: References: <1377428496-21721-1-git-send-email-hfreyther@sysmocom.de> <20130929052519.GA25274@xiaoyu.lan> Message-ID: <20131001070228.GG25860@xiaoyu.lan> On Tue, Oct 01, 2013 at 10:03:39AM +0400, Ivan Kluchnikov wrote: > Hi Holger, > > I looked through these patches. > Do you want to merge only these three patches or may be it makes sense > to merge all patches from zecke/features/tbf-cleanup branch? I prefer to establish a culture of review and feedback. I hope that by cleaning up this code in public the original author and others reading the mailinglist will reflect on the code and maybe improve. holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From Ivan.Kluchnikov at fairwaves.ru Wed Oct 2 14:15:58 2013 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Wed, 2 Oct 2013 18:15:58 +0400 Subject: [PATCH 1/3] tfi: The tfi_alloc doesn't allocate anything, rename the function In-Reply-To: <20131001070228.GG25860@xiaoyu.lan> References: <1377428496-21721-1-git-send-email-hfreyther@sysmocom.de> <20130929052519.GA25274@xiaoyu.lan> <20131001070228.GG25860@xiaoyu.lan> Message-ID: Ok, patches were merged to master and now I am ready for new patchset. 2013/10/1 Holger Hans Peter Freyther : > On Tue, Oct 01, 2013 at 10:03:39AM +0400, Ivan Kluchnikov wrote: >> Hi Holger, >> >> I looked through these patches. >> Do you want to merge only these three patches or may be it makes sense >> to merge all patches from zecke/features/tbf-cleanup branch? > > I prefer to establish a culture of review and feedback. I hope that > by cleaning up this code in public the original author and others > reading the mailinglist will reflect on the code and maybe improve. > > holger > > -- > - Holger Freyther http://www.sysmocom.de/ > ======================================================================= > * sysmocom - systems for mobile communications GmbH > * Schivelbeiner Str. 5 > * 10439 Berlin, Germany > * Sitz / Registered office: Berlin, HRB 134158 B > * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From hfreyther at sysmocom.de Wed Oct 16 14:23:41 2013 From: hfreyther at sysmocom.de (Holger Freyther) Date: Wed, 16 Oct 2013 16:23:41 +0200 Subject: [PATCH 1/8] tbf: Begin to add some structure to the tbf code Message-ID: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther The TBF should use the IMSI to identify a block flow but all handling is spread across the entire code. Start to clean this up by moving relevant code into the tbf file. Afterwards one can clean up and add more internal structure. --- src/Makefile.am | 6 +- src/gprs_bssgp_pcu.cpp | 121 +------------------------------------ src/tbf.cpp | 160 +++++++++++++++++++++++++++++++++++++++++++++++++ src/tbf.h | 27 +++++++++ 4 files changed, 194 insertions(+), 120 deletions(-) create mode 100644 src/tbf.cpp create mode 100644 src/tbf.h diff --git a/src/Makefile.am b/src/Makefile.am index 38a4b3c..6646f53 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,7 +40,8 @@ libgprs_la_SOURCES = \ gsm_timer.cpp \ bitvector.cpp \ pcu_l1_if.cpp \ - pcu_vty.c + pcu_vty.c \ + tbf.cpp if ENABLE_SYSMOBTS libgprs_la_SOURCES += \ @@ -72,7 +73,8 @@ noinst_HEADERS = \ bitvector.h \ pcu_vty.h \ sysmo_l1_if.h \ - femtobts.h + femtobts.h \ + tbf.h osmo_pcu_SOURCES = pcu_main.cpp diff --git a/src/gprs_bssgp_pcu.cpp b/src/gprs_bssgp_pcu.cpp index 4833af8..3432bca 100644 --- a/src/gprs_bssgp_pcu.cpp +++ b/src/gprs_bssgp_pcu.cpp @@ -21,6 +21,7 @@ #include #include #include +#include static struct gprs_bssgp_pcu the_pcu = { 0, }; @@ -103,12 +104,9 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) { struct bssgp_ud_hdr *budh; - int8_t tfi; /* must be signed */ - uint32_t tlli; uint8_t *data; uint16_t len; - struct gprs_rlcmac_tbf *tbf; char imsi[16] = "000"; budh = (struct bssgp_ud_hdr *)msgb_bssgph(msg); @@ -123,7 +121,7 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) data = (uint8_t *) TLVP_VAL(tp, BSSGP_IE_LLC_PDU); len = TLVP_LEN(tp, BSSGP_IE_LLC_PDU); - if (len > sizeof(tbf->llc_frame)) + if (len > sizeof(gprs_rlcmac_tbf::llc_frame)) { LOGP(DBSSGP, LOGL_NOTICE, "BSSGP TLLI=0x%08x Rx UL-UD IE_LLC_PDU too large\n", tlli); return bssgp_tx_status(BSSGP_CAUSE_COND_IE_ERR, NULL, msg); @@ -154,120 +152,7 @@ static int gprs_bssgp_pcu_rx_dl_ud(struct msgb *msg, struct tlv_parsed *tp) LOGP(DBSSGP, LOGL_INFO, "LLC [SGSN -> PCU] = TLLI: 0x%08x IMSI: %s len: %d\n", tlli, imsi, len); - /* check for existing TBF */ - if ((tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) { - LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli); - if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) { - LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state " - "(T3193), so reuse TBF\n"); - memcpy(tbf->llc_frame, data, len); - tbf->llc_length = len; - memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl)); /* reset - rlc states */ - tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; /* keep - to flags */ - tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); - if (!tbf->ms_class && ms_class) - tbf->ms_class = ms_class; - tbf_update(tbf); - gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL); - } else { - /* the TBF exists, so we must write it in the queue - * we prepend lifetime in front of PDU */ - struct timeval *tv; - struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv), - "llc_pdu_queue"); - if (!llc_msg) - return -ENOMEM; - tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv)); - if (the_pcu.bts->force_llc_lifetime) - delay_csec = the_pcu.bts->force_llc_lifetime; - /* keep timestap at 0 for infinite delay */ - if (delay_csec != 0xffff) { - /* calculate timestamp of timeout */ - gettimeofday(tv, NULL); - tv->tv_usec += (delay_csec % 100) * 10000; - tv->tv_sec += delay_csec / 100; - if (tv->tv_usec > 999999) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } - } - memcpy(msgb_put(llc_msg, len), data, len); - msgb_enqueue(&tbf->llc_queue, llc_msg); - /* set ms class for updating TBF */ - if (!tbf->ms_class && ms_class) - tbf->ms_class = ms_class; - } - } else { - 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); - if (tbf && tbf->dir.ul.contention_resolution_done - && !tbf->dir.ul.final_ack_sent) { - use_trx = tbf->trx; - ta = tbf->ta; - ss = 0; - old_tbf = tbf; - } else { - use_trx = -1; - /* 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; - } - - // Create new TBF (any TRX) - tfi = tfi_find_free(the_pcu.bts, GPRS_RLCMAC_DL_TBF, &trx, use_trx); - if (tfi < 0) { - LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); - /* FIXME: send reject */ - return -EBUSY; - } - /* set number of downlink slots according to multislot class */ - tbf = tbf_alloc(the_pcu.bts, tbf, GPRS_RLCMAC_DL_TBF, tfi, trx, ms_class, - ss); - if (!tbf) { - LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); - /* FIXME: send reject */ - return -EBUSY; - } - tbf->tlli = tlli; - tbf->tlli_valid = 1; - tbf->ta = ta; - - LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] START TFI: %d TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); - - /* new TBF, so put first frame */ - memcpy(tbf->llc_frame, data, len); - tbf->llc_length = len; - - /* trigger downlink assignment and set state to ASSIGN. - * we don't use old_downlink, so the possible uplink is used - * to trigger downlink assignment. if there is no uplink, - * AGCH is used. */ - gprs_rlcmac_trigger_downlink_assignment(tbf, old_tbf, imsi); - } - - /* store IMSI for debugging purpose */ - strncpy(tbf->meas.imsi, imsi, sizeof(tbf->meas.imsi) - 1); - - return 0; + return tbf_handle(the_pcu.bts, tlli, imsi, ms_class, delay_csec, data, len); } int gprs_bssgp_pcu_rx_paging_ps(struct msgb *msg, struct tlv_parsed *tp) diff --git a/src/tbf.cpp b/src/tbf.cpp new file mode 100644 index 0000000..816fdb8 --- /dev/null +++ b/src/tbf.cpp @@ -0,0 +1,160 @@ +/* Copied from gprs_bssgp_pcu.cpp + * + * Copyright (C) 2012 Ivan Klyuchnikov + * Copyright (C) 2013 by Holger Hans Peter Freyther + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include + +extern "C" { +#include +} + +#include +#include + +/** + * TODO: split into unit test-able parts... + */ +int tbf_handle(struct gprs_rlcmac_bts *bts, + const uint32_t tlli, const char *imsi, + const uint8_t ms_class, const uint16_t pdu_delay_csec, + const uint8_t *data, const uint16_t len) +{ + struct gprs_rlcmac_tbf *tbf; + int8_t tfi; /* must be signed */ + + /* check for existing TBF */ + if ((tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) { + LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli); + if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) { + LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state " + "(T3193), so reuse TBF\n"); + memcpy(tbf->llc_frame, data, len); + tbf->llc_length = len; + memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl)); /* reset + rlc states */ + tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; /* keep + to flags */ + tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); + if (!tbf->ms_class && ms_class) + tbf->ms_class = ms_class; + tbf_update(tbf); + gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL); + } else { + /* the TBF exists, so we must write it in the queue + * we prepend lifetime in front of PDU */ + struct timeval *tv; + struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv), + "llc_pdu_queue"); + if (!llc_msg) + return -ENOMEM; + tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv)); + + uint16_t delay_csec; + if (bts->force_llc_lifetime) + delay_csec = bts->force_llc_lifetime; + else + delay_csec = pdu_delay_csec; + /* keep timestap at 0 for infinite delay */ + if (delay_csec != 0xffff) { + /* calculate timestamp of timeout */ + gettimeofday(tv, NULL); + tv->tv_usec += (delay_csec % 100) * 10000; + tv->tv_sec += delay_csec / 100; + if (tv->tv_usec > 999999) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } + } + memcpy(msgb_put(llc_msg, len), data, len); + msgb_enqueue(&tbf->llc_queue, llc_msg); + /* set ms class for updating TBF */ + if (!tbf->ms_class && ms_class) + tbf->ms_class = ms_class; + } + } else { + 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); + if (tbf && tbf->dir.ul.contention_resolution_done + && !tbf->dir.ul.final_ack_sent) { + use_trx = tbf->trx; + ta = tbf->ta; + ss = 0; + old_tbf = tbf; + } else { + use_trx = -1; + /* 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; + } + + // Create new TBF (any TRX) + tfi = tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx, use_trx); + if (tfi < 0) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); + /* FIXME: send reject */ + return -EBUSY; + } + /* set number of downlink slots according to multislot class */ + tbf = tbf_alloc(bts, tbf, GPRS_RLCMAC_DL_TBF, tfi, trx, ms_class, + ss); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); + /* FIXME: send reject */ + return -EBUSY; + } + tbf->tlli = tlli; + tbf->tlli_valid = 1; + tbf->ta = ta; + + LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] START TFI: %d TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); + + /* new TBF, so put first frame */ + memcpy(tbf->llc_frame, data, len); + tbf->llc_length = len; + + /* trigger downlink assignment and set state to ASSIGN. + * we don't use old_downlink, so the possible uplink is used + * to trigger downlink assignment. if there is no uplink, + * AGCH is used. */ + gprs_rlcmac_trigger_downlink_assignment(tbf, old_tbf, imsi); + } + + /* store IMSI for debugging purpose */ + strncpy(tbf->meas.imsi, imsi, sizeof(tbf->meas.imsi) - 1); + return 0; +} diff --git a/src/tbf.h b/src/tbf.h new file mode 100644 index 0000000..1535e8c --- /dev/null +++ b/src/tbf.h @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2013 by Holger Hans Peter Freyther + * + * 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 2 + * 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, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#pragma once + +#include + +struct gprs_rlcmac_bts; + +int tbf_handle(struct gprs_rlcmac_bts *bts, + const uint32_t tlli, const char *imsi, const uint8_t ms_class, + const uint16_t delay_csec, const uint8_t *data, const uint16_t len); -- 1.8.4.rc3 From hfreyther at sysmocom.de Wed Oct 16 14:23:42 2013 From: hfreyther at sysmocom.de (Holger Freyther) Date: Wed, 16 Oct 2013 16:23:42 +0200 Subject: [PATCH 2/8] tbf: Separate the easy path out of the receive path In-Reply-To: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> References: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1381933428-4160-2-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther * Create a look up routine for the TBF that will allow us to easily find a TBF by IMSI... * Separate the code that works on an existing TBF. --- src/tbf.cpp | 119 +++++++++++++++++++++++++++++++++++------------------------- 1 file changed, 70 insertions(+), 49 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index 816fdb8..d242b52 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -29,66 +29,87 @@ extern "C" { #include #include +static struct gprs_rlcmac_tbf *tbf_lookup_dl(const uint32_t tlli, const char *imsi) +{ + /* TODO: look up by IMSI first, then tlli, then old_tlli */ + return tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF); +} + +static int tbf_append_data(struct gprs_rlcmac_tbf *tbf, + struct gprs_rlcmac_bts *bts, + const uint8_t ms_class, + const uint16_t pdu_delay_csec, + const uint8_t *data, const uint16_t len) +{ + LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli); + if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) { + LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state " + "(T3193), so reuse TBF\n"); + memcpy(tbf->llc_frame, data, len); + tbf->llc_length = len; + /* reset rlc states */ + memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl)); + /* keep to flags */ + tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; + tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); + if (!tbf->ms_class && ms_class) + tbf->ms_class = ms_class; + tbf_update(tbf); + gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL); + } else { + /* the TBF exists, so we must write it in the queue + * we prepend lifetime in front of PDU */ + struct timeval *tv; + struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv), + "llc_pdu_queue"); + if (!llc_msg) + return -ENOMEM; + tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv)); + + uint16_t delay_csec; + if (bts->force_llc_lifetime) + delay_csec = bts->force_llc_lifetime; + else + delay_csec = pdu_delay_csec; + /* keep timestap at 0 for infinite delay */ + if (delay_csec != 0xffff) { + /* calculate timestamp of timeout */ + gettimeofday(tv, NULL); + tv->tv_usec += (delay_csec % 100) * 10000; + tv->tv_sec += delay_csec / 100; + if (tv->tv_usec > 999999) { + tv->tv_usec -= 1000000; + tv->tv_sec++; + } + } + memcpy(msgb_put(llc_msg, len), data, len); + msgb_enqueue(&tbf->llc_queue, llc_msg); + /* set ms class for updating TBF */ + if (!tbf->ms_class && ms_class) + tbf->ms_class = ms_class; + } + + return 0; +} + /** * TODO: split into unit test-able parts... */ int tbf_handle(struct gprs_rlcmac_bts *bts, const uint32_t tlli, const char *imsi, - const uint8_t ms_class, const uint16_t pdu_delay_csec, + const uint8_t ms_class, const uint16_t delay_csec, const uint8_t *data, const uint16_t len) { struct gprs_rlcmac_tbf *tbf; int8_t tfi; /* must be signed */ /* check for existing TBF */ - if ((tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_DL_TBF))) { - LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli); - if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) { - LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state " - "(T3193), so reuse TBF\n"); - memcpy(tbf->llc_frame, data, len); - tbf->llc_length = len; - memset(&tbf->dir.dl, 0, sizeof(tbf->dir.dl)); /* reset - rlc states */ - tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; /* keep - to flags */ - tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); - if (!tbf->ms_class && ms_class) - tbf->ms_class = ms_class; - tbf_update(tbf); - gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL); - } else { - /* the TBF exists, so we must write it in the queue - * we prepend lifetime in front of PDU */ - struct timeval *tv; - struct msgb *llc_msg = msgb_alloc(len + sizeof(*tv), - "llc_pdu_queue"); - if (!llc_msg) - return -ENOMEM; - tv = (struct timeval *)msgb_put(llc_msg, sizeof(*tv)); - - uint16_t delay_csec; - if (bts->force_llc_lifetime) - delay_csec = bts->force_llc_lifetime; - else - delay_csec = pdu_delay_csec; - /* keep timestap at 0 for infinite delay */ - if (delay_csec != 0xffff) { - /* calculate timestamp of timeout */ - gettimeofday(tv, NULL); - tv->tv_usec += (delay_csec % 100) * 10000; - tv->tv_sec += delay_csec / 100; - if (tv->tv_usec > 999999) { - tv->tv_usec -= 1000000; - tv->tv_sec++; - } - } - memcpy(msgb_put(llc_msg, len), data, len); - msgb_enqueue(&tbf->llc_queue, llc_msg); - /* set ms class for updating TBF */ - if (!tbf->ms_class && ms_class) - tbf->ms_class = ms_class; - } + tbf = tbf_lookup_dl(tlli, imsi); + if (tbf) { + int rc = tbf_append_data(tbf, bts, ms_class, + delay_csec, data, len); + if (rc < 0) + return rc; } else { uint8_t trx, ta, ss; int8_t use_trx; -- 1.8.4.rc3 From hfreyther at sysmocom.de Wed Oct 16 14:23:44 2013 From: hfreyther at sysmocom.de (Holger Freyther) Date: Wed, 16 Oct 2013 16:23:44 +0200 Subject: [PATCH 4/8] tbf: Create an assign method for IMSI. In-Reply-To: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> References: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1381933428-4160-4-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther This will allow us to set flags (like IMSI) present and will be of help when fixing the tbf lookup. --- src/tbf.cpp | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index 5161e92..fc8d229 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -36,6 +36,12 @@ static inline void tbf_update_ms_class(struct gprs_rlcmac_tbf *tbf, tbf->ms_class = ms_class; } +static inline void tbf_assign_imsi(struct gprs_rlcmac_tbf *tbf, + const char *imsi) +{ + strncpy(tbf->meas.imsi, imsi, sizeof(tbf->meas.imsi) - 1); +} + static struct gprs_rlcmac_tbf *tbf_lookup_dl(const uint32_t tlli, const char *imsi) { /* TODO: look up by IMSI first, then tlli, then old_tlli */ @@ -179,7 +185,7 @@ int tbf_handle(struct gprs_rlcmac_bts *bts, gprs_rlcmac_trigger_downlink_assignment(tbf, old_tbf, imsi); } - /* store IMSI for debugging purpose */ - strncpy(tbf->meas.imsi, imsi, sizeof(tbf->meas.imsi) - 1); + /* store IMSI for debugging purpose. TODO: it is more than debugging */ + tbf_assign_imsi(tbf, imsi); return 0; } -- 1.8.4.rc3 From hfreyther at sysmocom.de Wed Oct 16 14:23:43 2013 From: hfreyther at sysmocom.de (Holger Freyther) Date: Wed, 16 Oct 2013 16:23:43 +0200 Subject: [PATCH 3/8] tbf: Move code that sets the tbf's ms_class to a central place In-Reply-To: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> References: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1381933428-4160-3-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther --- src/tbf.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index d242b52..5161e92 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -29,6 +29,13 @@ extern "C" { #include #include +static inline void tbf_update_ms_class(struct gprs_rlcmac_tbf *tbf, + const uint8_t ms_class) +{ + if (!tbf->ms_class && ms_class) + tbf->ms_class = ms_class; +} + static struct gprs_rlcmac_tbf *tbf_lookup_dl(const uint32_t tlli, const char *imsi) { /* TODO: look up by IMSI first, then tlli, then old_tlli */ @@ -52,8 +59,7 @@ static int tbf_append_data(struct gprs_rlcmac_tbf *tbf, /* keep to flags */ tbf->state_flags &= GPRS_RLCMAC_FLAG_TO_MASK; tbf->state_flags &= ~(1 << GPRS_RLCMAC_FLAG_CCCH); - if (!tbf->ms_class && ms_class) - tbf->ms_class = ms_class; + tbf_update_ms_class(tbf, ms_class); tbf_update(tbf); gprs_rlcmac_trigger_downlink_assignment(tbf, tbf, NULL); } else { @@ -84,9 +90,7 @@ static int tbf_append_data(struct gprs_rlcmac_tbf *tbf, } memcpy(msgb_put(llc_msg, len), data, len); msgb_enqueue(&tbf->llc_queue, llc_msg); - /* set ms class for updating TBF */ - if (!tbf->ms_class && ms_class) - tbf->ms_class = ms_class; + tbf_update_ms_class(tbf, ms_class); } return 0; -- 1.8.4.rc3 From hfreyther at sysmocom.de Wed Oct 16 14:23:47 2013 From: hfreyther at sysmocom.de (Holger Freyther) Date: Wed, 16 Oct 2013 16:23:47 +0200 Subject: [PATCH 7/8] tbf: Add more to do items for refactoring on the dl assignment In-Reply-To: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> References: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1381933428-4160-7-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther --- src/tbf.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/tbf.cpp b/src/tbf.cpp index 21b58ac..cb8fb19 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -114,6 +114,8 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts, int rc; /* check for uplink data, so we copy our informations */ +#warning "Do the same look up for IMSI, TLLI and OLD_TLLI" +#warning "Refactor the below lines... into a new method" tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); if (tbf && tbf->dir.ul.contention_resolution_done && !tbf->dir.ul.final_ack_sent) { -- 1.8.4.rc3 From hfreyther at sysmocom.de Wed Oct 16 14:23:45 2013 From: hfreyther at sysmocom.de (Holger Freyther) Date: Wed, 16 Oct 2013 16:23:45 +0200 Subject: [PATCH 5/8] tbf: Move the creation of a new tbf for the downlink to a new method In-Reply-To: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> References: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1381933428-4160-5-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther Move the code that is dedicated to handle the assignment of a new TFI/TBF for the downlink into a new method. --- src/tbf.cpp | 150 ++++++++++++++++++++++++++++++++---------------------------- 1 file changed, 80 insertions(+), 70 deletions(-) diff --git a/src/tbf.cpp b/src/tbf.cpp index fc8d229..8dad6bc 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -102,6 +102,81 @@ static int tbf_append_data(struct gprs_rlcmac_tbf *tbf, return 0; } +static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts, + const char *imsi, + const uint32_t tlli, const uint8_t ms_class, + const uint8_t *data, const uint16_t len) +{ + uint8_t trx, ta, ss; + int8_t use_trx; + struct gprs_rlcmac_tbf *old_tbf, *tbf; + int8_t tfi; /* must be signed */ + int rc; + + /* check for uplink data, so we copy our informations */ + tbf = tbf_by_tlli(tlli, GPRS_RLCMAC_UL_TBF); + if (tbf && tbf->dir.ul.contention_resolution_done + && !tbf->dir.ul.final_ack_sent) { + use_trx = tbf->trx; + ta = tbf->ta; + ss = 0; + old_tbf = tbf; + } else { + use_trx = -1; + /* 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; + } + + // Create new TBF (any TRX) + tfi = tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx, use_trx); + if (tfi < 0) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); + /* FIXME: send reject */ + return -EBUSY; + } + /* set number of downlink slots according to multislot class */ + tbf = tbf_alloc(bts, tbf, GPRS_RLCMAC_DL_TBF, tfi, trx, ms_class, ss); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); + /* FIXME: send reject */ + return -EBUSY; + } + tbf->tlli = tlli; + tbf->tlli_valid = 1; + tbf->ta = ta; + + LOGP(DRLCMAC, LOGL_DEBUG, + "TBF: [DOWNLINK] START TFI: %d TLLI: 0x%08x \n", + tbf->tfi, tbf->tlli); + + /* new TBF, so put first frame */ + memcpy(tbf->llc_frame, data, len); + tbf->llc_length = len; + + /* trigger downlink assignment and set state to ASSIGN. + * we don't use old_downlink, so the possible uplink is used + * to trigger downlink assignment. if there is no uplink, + * AGCH is used. */ + gprs_rlcmac_trigger_downlink_assignment(tbf, old_tbf, imsi); + + /* store IMSI for debugging purpose. TODO: it is more than debugging */ + tbf_assign_imsi(tbf, imsi); + return 0; +} + /** * TODO: split into unit test-able parts... */ @@ -111,81 +186,16 @@ int tbf_handle(struct gprs_rlcmac_bts *bts, const uint8_t *data, const uint16_t len) { struct gprs_rlcmac_tbf *tbf; - int8_t tfi; /* must be signed */ /* check for existing TBF */ tbf = tbf_lookup_dl(tlli, imsi); if (tbf) { int rc = tbf_append_data(tbf, bts, ms_class, delay_csec, data, len); - if (rc < 0) - return rc; - } else { - 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); - if (tbf && tbf->dir.ul.contention_resolution_done - && !tbf->dir.ul.final_ack_sent) { - use_trx = tbf->trx; - ta = tbf->ta; - ss = 0; - old_tbf = tbf; - } else { - use_trx = -1; - /* 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; - } - - // Create new TBF (any TRX) - tfi = tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx, use_trx); - if (tfi < 0) { - LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); - /* FIXME: send reject */ - return -EBUSY; - } - /* set number of downlink slots according to multislot class */ - tbf = tbf_alloc(bts, tbf, GPRS_RLCMAC_DL_TBF, tfi, trx, ms_class, - ss); - if (!tbf) { - LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); - /* FIXME: send reject */ - return -EBUSY; - } - tbf->tlli = tlli; - tbf->tlli_valid = 1; - tbf->ta = ta; + if (rc >= 0) + tbf_assign_imsi(tbf, imsi); + return rc; + } - LOGP(DRLCMAC, LOGL_DEBUG, "TBF: [DOWNLINK] START TFI: %d TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); - - /* new TBF, so put first frame */ - memcpy(tbf->llc_frame, data, len); - tbf->llc_length = len; - - /* trigger downlink assignment and set state to ASSIGN. - * we don't use old_downlink, so the possible uplink is used - * to trigger downlink assignment. if there is no uplink, - * AGCH is used. */ - gprs_rlcmac_trigger_downlink_assignment(tbf, old_tbf, imsi); - } - - /* store IMSI for debugging purpose. TODO: it is more than debugging */ - tbf_assign_imsi(tbf, imsi); - return 0; + return tbf_new_dl_assignment(bts, imsi, tlli, ms_class, data, len); } -- 1.8.4.rc3 From hfreyther at sysmocom.de Wed Oct 16 14:23:46 2013 From: hfreyther at sysmocom.de (Holger Freyther) Date: Wed, 16 Oct 2013 16:23:46 +0200 Subject: [PATCH 6/8] tbf: Warn about copy and paste between different tbf alloc routines In-Reply-To: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> References: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1381933428-4160-6-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther These need to be re-factored to use a common allocation routine. --- src/gprs_rlcmac_data.cpp | 2 ++ src/tbf.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 294753d..17e1fb9 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -238,6 +238,7 @@ static struct gprs_rlcmac_tbf *alloc_ul_tbf(int8_t use_trx, uint8_t ms_class, struct gprs_rlcmac_tbf *tbf; uint8_t tfi; +#warning "Copy and paste with tbf_new_dl_assignment" /* create new TBF, use sme TRX as DL TBF */ tfi = tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx, use_trx); if (tfi < 0) { @@ -1174,6 +1175,7 @@ int gprs_rlcmac_rcv_rach(uint8_t ra, uint32_t Fn, int16_t qta) "(AGCH)\n"); } else { // Create new TBF + #warning "Copy and pate with other routines.." tfi = tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx, -1); if (tfi < 0) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); diff --git a/src/tbf.cpp b/src/tbf.cpp index 8dad6bc..21b58ac 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -141,6 +141,7 @@ static int tbf_new_dl_assignment(struct gprs_rlcmac_bts *bts, } // Create new TBF (any TRX) +#warning "Copy and paste with alloc_ul_tbf" tfi = tfi_find_free(bts, GPRS_RLCMAC_DL_TBF, &trx, use_trx); if (tfi < 0) { LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH resource\n"); -- 1.8.4.rc3 From hfreyther at sysmocom.de Wed Oct 16 14:23:48 2013 From: hfreyther at sysmocom.de (Holger Freyther) Date: Wed, 16 Oct 2013 16:23:48 +0200 Subject: [PATCH 8/8] tbf: Move the alloc_ul_tbf into tbf.c and change signature In-Reply-To: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> References: <1381933428-4160-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1381933428-4160-8-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther Add the bts parameter to the method list. This would be a static method of the class (in case the TBF would be a class) --- src/gprs_rlcmac_data.cpp | 41 +++-------------------------------------- src/tbf.cpp | 35 +++++++++++++++++++++++++++++++++++ src/tbf.h | 5 +++++ 3 files changed, 43 insertions(+), 38 deletions(-) diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index 17e1fb9..bc55c57 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -21,6 +21,7 @@ #include #include #include +#include extern void *tall_pcu_ctx; @@ -230,42 +231,6 @@ static uint8_t get_ms_class_by_capability(MS_Radio_Access_capability_t *cap) return 0; } -static struct gprs_rlcmac_tbf *alloc_ul_tbf(int8_t use_trx, uint8_t ms_class, - uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf) -{ - struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; - uint8_t trx; - struct gprs_rlcmac_tbf *tbf; - uint8_t tfi; - -#warning "Copy and paste with tbf_new_dl_assignment" - /* create new TBF, use sme TRX as DL TBF */ - tfi = tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx, use_trx); - if (tfi < 0) { - LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); - /* FIXME: send reject */ - return NULL; - } - /* use multislot class of downlink TBF */ - tbf = tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx, ms_class, 0); - if (!tbf) { - LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); - /* FIXME: send reject */ - return NULL; - } - tbf->tlli = tlli; - tbf->tlli_valid = 1; /* no contention resolution */ - tbf->dir.ul.contention_resolution_done = 1; - tbf->ta = ta; /* use current TA */ - tbf_new_state(tbf, GPRS_RLCMAC_ASSIGN); - tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); - tbf_timer_start(tbf, 3169, bts->t3169, 0); - - return tbf; -} - - - /* Received Uplink RLC control block. */ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts, uint32_t fn) @@ -412,7 +377,7 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts, if (ul_control_block->u.Packet_Downlink_Ack_Nack.Exist_Channel_Request_Description) { LOGP(DRLCMAC, LOGL_DEBUG, "MS requests UL TBF in ack " "message, so we provide one:\n"); - alloc_ul_tbf(tbf->trx, tbf->ms_class, tbf->tlli, tbf->ta, tbf); + tbf_alloc_ul(bts, tbf->trx, tbf->ms_class, tbf->tlli, tbf->ta, tbf); /* schedule uplink assignment */ tbf->ul_ass_state = GPRS_RLCMAC_UL_ASS_SEND_ASS; } @@ -465,7 +430,7 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts, 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, ta, NULL); + tbf = tbf_alloc_ul(bts, trx, ms_class, tlli, ta, NULL); if (!tbf) break; /* set control ts to current MS's TS, until assignment complete */ diff --git a/src/tbf.cpp b/src/tbf.cpp index cb8fb19..79f1ea8 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1,6 +1,7 @@ /* Copied from gprs_bssgp_pcu.cpp * * Copyright (C) 2012 Ivan Klyuchnikov + * Copyright (C) 2012 Andreas Eversberg * Copyright (C) 2013 by Holger Hans Peter Freyther * * This program is free software; you can redistribute it and/or @@ -202,3 +203,37 @@ int tbf_handle(struct gprs_rlcmac_bts *bts, return tbf_new_dl_assignment(bts, imsi, tlli, ms_class, data, len); } + +struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, + int8_t use_trx, uint8_t ms_class, + uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf) +{ + uint8_t trx; + struct gprs_rlcmac_tbf *tbf; + uint8_t tfi; + +#warning "Copy and paste with tbf_new_dl_assignment" + /* create new TBF, use sme TRX as DL TBF */ + tfi = tfi_find_free(bts, GPRS_RLCMAC_UL_TBF, &trx, use_trx); + if (tfi < 0) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); + /* FIXME: send reject */ + return NULL; + } + /* use multislot class of downlink TBF */ + tbf = tbf_alloc(bts, dl_tbf, GPRS_RLCMAC_UL_TBF, tfi, trx, ms_class, 0); + if (!tbf) { + LOGP(DRLCMAC, LOGL_NOTICE, "No PDCH ressource\n"); + /* FIXME: send reject */ + return NULL; + } + tbf->tlli = tlli; + tbf->tlli_valid = 1; /* no contention resolution */ + tbf->dir.ul.contention_resolution_done = 1; + tbf->ta = ta; /* use current TA */ + tbf_new_state(tbf, GPRS_RLCMAC_ASSIGN); + tbf->state_flags |= (1 << GPRS_RLCMAC_FLAG_PACCH); + tbf_timer_start(tbf, 3169, bts->t3169, 0); + + return tbf; +} diff --git a/src/tbf.h b/src/tbf.h index 1535e8c..330eac1 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -22,6 +22,11 @@ struct gprs_rlcmac_bts; +/* dispatch Unitdata.DL messages */ int tbf_handle(struct gprs_rlcmac_bts *bts, const uint32_t tlli, const char *imsi, const uint8_t ms_class, const uint16_t delay_csec, const uint8_t *data, const uint16_t len); + +struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, + int8_t use_trx, uint8_t ms_class, + uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf); -- 1.8.4.rc3 From hfreyther at sysmocom.de Thu Oct 17 09:30:16 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Thu, 17 Oct 2013 11:30:16 +0200 Subject: Question regarding TS allocation algorithm(s) In-Reply-To: <20130929090505.GA25501@xiaoyu.lan> References: <20130929073142.GV25860@xiaoyu.lan> <5247E1B6.2040302@eversberg.eu> <20130929090505.GA25501@xiaoyu.lan> Message-ID: <20131017093016.GA31911@xiaoyu.lan> On Sun, Sep 29, 2013 at 11:05:05AM +0200, Holger Hans Peter Freyther wrote: > okay. I am currently cleaning up the pcu (including the allocations > algorithms), refactor and fix the subtle bugs that are due code > duplication (e.g. like the one reported by Vladimir Rolbin). This > also means that I will be busy and stall your osmo-bts changes > until I am done with the clean-up here. after more re-factoring and writing client code to utilize the allocation. The limiting factor in the DL is the USF assignment. So for alloc_a we are limited to 8 devices at a time (even with multiple PDCHs). holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From hfreyther at sysmocom.de Thu Oct 17 09:33:32 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Thu, 17 Oct 2013 11:33:32 +0200 Subject: TBF differences for Uplink and Downlink Message-ID: <20131017093332.GB31911@xiaoyu.lan> Hi, in my refactorings (creating a TBF class and moving code that modifes the internals into the TBF) I am trying to make gprs_rlcmac_ul_tbfs and gprs_rlcmac_dl_tbfs private and I notice code like: if (dir == GPRS_RLCMAC_UL_TBF) { llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->tlli == tlli && tbf->tlli_valid) return tbf; } } else { llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->tlli == tlli) return tbf; } } llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx_no == trx && tbf->control_ts == ts) return tbf; } llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx_no == trx && tbf->control_ts == ts) return tbf; } In the first code. Why is tlli_valid only checked for the UL TBF and not the downlink one? holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From hfreyther at sysmocom.de Thu Oct 17 09:44:11 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Thu, 17 Oct 2013 11:44:11 +0200 Subject: Fairness of sched_poll Message-ID: <20131017094411.GL17688@xiaoyu.lan> Good Morning, sched_poll is doing: llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { /* this trx, this ts */ if (tbf->trx_no != trx || tbf->control_ts != ts) continue; /* polling for next uplink block */ if (tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == poll_fn) *poll_tbf = tbf; if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_SEND_ACK) *ul_ack_tbf = tbf; if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_SEND_ASS) *dl_ass_tbf = tbf; if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_SEND_ASS) *ul_ass_tbf = tbf; } llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { /* this trx, this ts */ if (tbf->trx_no != trx || tbf->control_ts != ts) continue; /* polling for next uplink block */ if (tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == poll_fn) *poll_tbf = tbf; if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_SEND_ASS) *dl_ass_tbf = tbf; if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_SEND_ASS) *ul_ass_tbf = tbf; } New tbf's will be added to the front (llist_add). Is it on purpose that the dl_tbfs are preferred over ul_tbfs and that the last of each tbf's will be found? What is the reasoning for this? What will collect/catch poll_fn's that are in the past? holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From andreas at eversberg.eu Thu Oct 17 09:54:49 2013 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 17 Oct 2013 11:54:49 +0200 Subject: Question regarding TS allocation algorithm(s) In-Reply-To: <20131017093016.GA31911@xiaoyu.lan> References: <20130929073142.GV25860@xiaoyu.lan> <5247E1B6.2040302@eversberg.eu> <20130929090505.GA25501@xiaoyu.lan> <20131017093016.GA31911@xiaoyu.lan> Message-ID: <525FB3E9.4020402@eversberg.eu> Holger Hans Peter Freyther wrote: > after more re-factoring and writing client code to utilize the > allocation. The limiting factor in the DL is the USF assignment. > So for alloc_a we are limited to 8 devices at a time (even with > multiple PDCHs). > actually we are limited to 7 devices, because USF 7 is reserved. we need this for single block allocation or polling a response from a device. we do not want to have collisions with an ongoing uplink TBF. a way to provide more downlink/uplink TBFs, is to assign only a subset of PDCHs to each device, if the number of devices is high. it is possible to remove assigned PDCHs from devices when splitting of PDCHs (into a subset) is wanted. but this would make an algorithm more complex. at least for algorithm A (single slot) it would be simpler. From andreas at eversberg.eu Thu Oct 17 10:03:23 2013 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 17 Oct 2013 12:03:23 +0200 Subject: TBF differences for Uplink and Downlink In-Reply-To: <20131017093332.GB31911@xiaoyu.lan> References: <20131017093332.GB31911@xiaoyu.lan> Message-ID: <525FB5EB.8010005@eversberg.eu> Holger Hans Peter Freyther wrote: > In the first code. Why is tlli_valid only checked for the UL TBF > and not the downlink one? > there is a "one phase access", where devices request a channel for uplink TBF, but we don't know the TLLI until we get a valid RLC/MAC block. for every downlink TBF we know the TLLI for sure, because it is contained in the LLC data frame from SGSN. From hfreyther at sysmocom.de Thu Oct 17 11:05:47 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Thu, 17 Oct 2013 13:05:47 +0200 Subject: TBF differences for Uplink and Downlink In-Reply-To: <525FB5EB.8010005@eversberg.eu> References: <20131017093332.GB31911@xiaoyu.lan> <525FB5EB.8010005@eversberg.eu> Message-ID: <20131017110547.GM17688@xiaoyu.lan> On Thu, Oct 17, 2013 at 12:03:23PM +0200, Andreas Eversberg wrote: > there is a "one phase access", where devices request a channel for > uplink TBF, but we don't know the TLLI until we get a valid RLC/MAC > block. for every downlink TBF we know the TLLI for sure, because it is > contained in the LLC data frame from SGSN. thanks for the explanation. So the tlli is always valid in the DL direction and sometimes valid in the UL. Code duplication (as witnessed with the missing tfi assignment in (a) algorithm) has the danger that one codepath is fixed while the others are left broken. I will then use the version with tlli_valid and kill the code clones. holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From andreas at eversberg.eu Thu Oct 17 11:42:51 2013 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 17 Oct 2013 13:42:51 +0200 Subject: Fairness of sched_poll In-Reply-To: <20131017094411.GL17688@xiaoyu.lan> References: <20131017094411.GL17688@xiaoyu.lan> Message-ID: <525FCD3B.3000800@eversberg.eu> Holger Hans Peter Freyther wrote: > Good Morning, > > sched_poll is doing: > > llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { > /* this trx, this ts */ > if (tbf->trx_no != trx || tbf->control_ts != ts) > continue; > /* polling for next uplink block */ > if (tbf->poll_state == GPRS_RLCMAC_POLL_SCHED > && tbf->poll_fn == poll_fn) > *poll_tbf = tbf; > if (tbf->ul_ack_state == GPRS_RLCMAC_UL_ACK_SEND_ACK) > *ul_ack_tbf = tbf; > if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_SEND_ASS) > *dl_ass_tbf = tbf; > if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_SEND_ASS) > *ul_ass_tbf = tbf; > } > llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { > /* this trx, this ts */ > if (tbf->trx_no != trx || tbf->control_ts != ts) > continue; > /* polling for next uplink block */ > if (tbf->poll_state == GPRS_RLCMAC_POLL_SCHED > && tbf->poll_fn == poll_fn) > *poll_tbf = tbf; > if (tbf->dl_ass_state == GPRS_RLCMAC_DL_ASS_SEND_ASS) > *dl_ass_tbf = tbf; > if (tbf->ul_ass_state == GPRS_RLCMAC_UL_ASS_SEND_ASS) > *ul_ass_tbf = tbf; > } > > > New tbf's will be added to the front (llist_add). Is it on purpose > that the dl_tbfs are preferred over ul_tbfs and that the last of > each tbf's will be found? What is the reasoning for this? What will > collect/catch poll_fn's that are in the past? > > holger > > the function sched_poll() only refers to control messages and polling. for every frame number (fn) there is only one mobile that can be polled. polling is requested 13 frames earlier in a downlink RLC/MAC control block. because each downlink RLC/MAC control block addresses only one TBF, no more than one TBF will have the poll state set to GPRS_RLCMAC_POLL_SCHED for the current fn, and so there is no prio in the function above. generally: the uplink blocks that are polled have prio over normal uplink data blocks. (uplink traffic can wait, polled control messages not) the control messages (uplink ack, downlin/uplink assignment) have prio over normal downlink data blocks. (downlink traffic can wait, control messages not) assignment messges have prio over uplink ack messages. i did not implement any fairness for assignment control messages of each TBF, because the number of assignment control messages are always much lower than the number of data blocks, so there is no congestion, and i think there is no reason for any round-robin scheduling. if a poll_fn is in the past (time skew or no response), pcu_rx_time_ind() will discover that. From hfreyther at sysmocom.de Thu Oct 17 12:42:42 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Thu, 17 Oct 2013 14:42:42 +0200 Subject: Fairness of sched_poll In-Reply-To: <525FCD3B.3000800@eversberg.eu> References: <20131017094411.GL17688@xiaoyu.lan> <525FCD3B.3000800@eversberg.eu> Message-ID: <20131017124242.GN17688@xiaoyu.lan> On Thu, Oct 17, 2013 at 01:42:51PM +0200, Andreas Eversberg wrote: > if a poll_fn is in the past (time skew or no response), > pcu_rx_time_ind() will discover that. I stumbled on this code earlier today. From a software engineering point of view this code (and the other PCU code) is really problematic. The concern of the pcu_rx_time_ind is to convert from low-level hardware primtive to inform other parts of the system. It should not be responsible for TBF/SBA timeout handling. It is the application of information hiding (encapsulation) and this concept is quite old. If one manages to apply information hiding and create proper modules the complexity of the code is reduced (e.g. no unexpected side effects, modifications to internal state of a tbf) and one can start to test the parts of the application. In terms of software engineering one should always ask the question of what is the secret of this class/module/function... holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From andreas at eversberg.eu Thu Oct 17 13:17:17 2013 From: andreas at eversberg.eu (Andreas Eversberg) Date: Thu, 17 Oct 2013 15:17:17 +0200 Subject: Fairness of sched_poll In-Reply-To: <20131017124242.GN17688@xiaoyu.lan> References: <20131017094411.GL17688@xiaoyu.lan> <525FCD3B.3000800@eversberg.eu> <20131017124242.GN17688@xiaoyu.lan> Message-ID: <525FE35D.6020207@eversberg.eu> Holger Hans Peter Freyther wrote: > The concern of the pcu_rx_time_ind is to convert from low-level > hardware primtive to inform other parts of the system. It should > not be responsible for TBF/SBA timeout handling. It is the application > of information hiding (encapsulation) and this concept is quite > old. > it is some kind of a hack. since we don't get bad frame indications from bts for sure, i had to find a way to detect when frames have not been received. normally the pcu_rx_data_ind function should call the timeout function in case of a bad frame. in this case the timeout function should actually be renamed to some kind like gprs_rlcmac_bfi(). if there is a way to fix bad frame indications from sysmobts, i would change the osmo-bts-trx code too, so both will send bad frame indications and we can get rid of this hack. From hfreyther at sysmocom.de Thu Oct 17 14:50:50 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Thu, 17 Oct 2013 16:50:50 +0200 Subject: Fairness of sched_poll In-Reply-To: <525FE35D.6020207@eversberg.eu> References: <20131017094411.GL17688@xiaoyu.lan> <525FCD3B.3000800@eversberg.eu> <20131017124242.GN17688@xiaoyu.lan> <525FE35D.6020207@eversberg.eu> Message-ID: <20131017145050.GO17688@xiaoyu.lan> On Thu, Oct 17, 2013 at 03:17:17PM +0200, Andreas Eversberg wrote: > it is some kind of a hack. since we don't get bad frame indications from > bts for sure, i had to find a way to detect when frames have not been > received. normally the pcu_rx_data_ind function should call the timeout > function in case of a bad frame. in this case the timeout function > should actually be renamed to some kind like gprs_rlcmac_bfi(). if there > is a way to fix bad frame indications from sysmobts, i would change the > osmo-bts-trx code too, so both will send bad frame indications and we > can get rid of this hack. Andreas, the point is not about if polling should be used but how the code is structured. E.g. why does the polling belong into the part of pcu_rx_data_ind? For me the responsibility of pcu_l1if.c is to communicate with the BTS (dispatch indications, send primitives, handle the socket). I would have never expected this code to be in a function with that name. Mixing code like this is problematic because: * It is increasing the depdency between the pcu_l1if and the rest of the code. This means understanding the PCU is more complicated and modification is more difficult/dangerous * It makes it more difficult to test the different parts. E.g. a very basic test for pcu_rx_time_ind would be that the current fn is updated. Currently this can not be tested. -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From hfreyther at sysmocom.de Sat Oct 19 14:26:32 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sat, 19 Oct 2013 16:26:32 +0200 Subject: [PATCH 2/8] tbf: Move header definition from gprs_rlcmac to the tbf In-Reply-To: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> References: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1382192798-22541-2-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther --- src/gprs_rlcmac.h | 94 ---------------------------------------------------- src/sysmo_sock.cpp | 1 + src/tbf.h | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+), 94 deletions(-) diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 6fdf600..a40ebd6 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -97,69 +97,6 @@ extern struct gprs_rlcmac_bts *gprs_rlcmac_bts; #ifdef __cplusplus /* - * TBF instance - */ - -#define LLC_MAX_LEN 1543 -#define RLC_MAX_SNS 128 /* GPRS, must be power of 2 */ -#define RLC_MAX_WS 64 /* max window size */ -#define RLC_MAX_LEN 54 /* CS-4 including spare bits */ - -#define Tassign_agch 0,200000 /* waiting after IMM.ASS confirm */ -#define Tassign_pacch 2,0 /* timeout for pacch assigment */ - -enum gprs_rlcmac_tbf_state { - GPRS_RLCMAC_NULL = 0, /* new created TBF */ - GPRS_RLCMAC_ASSIGN, /* wait for downlink assignment */ - GPRS_RLCMAC_FLOW, /* RLC/MAC flow, resource needed */ - GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */ - GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */ - GPRS_RLCMAC_RELEASING, /* releasing, wait to free TBI/USF */ -}; - -enum gprs_rlcmac_tbf_poll_state { - GPRS_RLCMAC_POLL_NONE = 0, - GPRS_RLCMAC_POLL_SCHED, /* a polling was scheduled */ -}; - -enum gprs_rlcmac_tbf_dl_ass_state { - GPRS_RLCMAC_DL_ASS_NONE = 0, - GPRS_RLCMAC_DL_ASS_SEND_ASS, /* send downlink assignment on next RTS */ - GPRS_RLCMAC_DL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */ -}; - -enum gprs_rlcmac_tbf_ul_ass_state { - GPRS_RLCMAC_UL_ASS_NONE = 0, - GPRS_RLCMAC_UL_ASS_SEND_ASS, /* send uplink assignment on next RTS */ - GPRS_RLCMAC_UL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */ -}; - -enum gprs_rlcmac_tbf_ul_ack_state { - GPRS_RLCMAC_UL_ACK_NONE = 0, - GPRS_RLCMAC_UL_ACK_SEND_ACK, /* send acknowledge on next RTS */ - GPRS_RLCMAC_UL_ACK_WAIT_ACK, /* wait for PACKET CONTROL ACK */ -}; - -enum gprs_rlcmac_tbf_direction { - GPRS_RLCMAC_DL_TBF, - GPRS_RLCMAC_UL_TBF -}; - -#define GPRS_RLCMAC_FLAG_CCCH 0 /* assignment on CCCH */ -#define GPRS_RLCMAC_FLAG_PACCH 1 /* assignment on PACCH */ -#define GPRS_RLCMAC_FLAG_UL_DATA 2 /* uplink data received */ -#define GPRS_RLCMAC_FLAG_DL_ACK 3 /* downlink acknowledge received */ -#define GPRS_RLCMAC_FLAG_TO_UL_ACK 4 -#define GPRS_RLCMAC_FLAG_TO_DL_ACK 5 -#define GPRS_RLCMAC_FLAG_TO_UL_ASS 6 -#define GPRS_RLCMAC_FLAG_TO_DL_ASS 7 -#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */ - -extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ -extern struct llist_head gprs_rlcmac_dl_tbfs; /* list of downlink TBFs */ -extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ - -/* * paging entry */ struct gprs_rlcmac_paging { @@ -213,37 +150,6 @@ int sba_alloc(uint8_t *_trx, uint8_t *_ts, uint32_t *_fn, uint8_t ta); struct gprs_rlcmac_sba *sba_find(uint8_t trx, uint8_t ts, uint32_t fn); -int tfi_find_free(struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir, - uint8_t *_trx, int8_t use_trx); - -struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, - struct gprs_rlcmac_tbf *old_tbf, - enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx, - uint8_t ms_class, uint8_t single_slot); - -struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, - uint8_t tfi, uint8_t trx, - enum gprs_rlcmac_tbf_direction dir); - -struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, - enum gprs_rlcmac_tbf_direction dir); - -struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts); - -void tbf_free(struct gprs_rlcmac_tbf *tbf); - -int tbf_update(struct gprs_rlcmac_tbf *tbf); - -int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf); - -void tbf_new_state(struct gprs_rlcmac_tbf *tbf, - enum gprs_rlcmac_tbf_state state); - -void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, - unsigned int seconds, unsigned int microseconds); - -void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf); - /* TS 44.060 Section 10.4.7 Table 10.4.7.1: Payload Type field */ enum gprs_rlcmac_block_type { GPRS_RLCMAC_DATA_BLOCK = 0x0, diff --git a/src/sysmo_sock.cpp b/src/sysmo_sock.cpp index e116e5a..d075df0 100644 --- a/src/sysmo_sock.cpp +++ b/src/sysmo_sock.cpp @@ -36,6 +36,7 @@ extern "C" { #include #include #include +#include extern void *tall_pcu_ctx; diff --git a/src/tbf.h b/src/tbf.h index a6dfced..cf2481d 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -22,6 +22,70 @@ #include +/* + * TBF instance + */ + +#define LLC_MAX_LEN 1543 +#define RLC_MAX_SNS 128 /* GPRS, must be power of 2 */ +#define RLC_MAX_WS 64 /* max window size */ +#define RLC_MAX_LEN 54 /* CS-4 including spare bits */ + +#define Tassign_agch 0,200000 /* waiting after IMM.ASS confirm */ +#define Tassign_pacch 2,0 /* timeout for pacch assigment */ + +enum gprs_rlcmac_tbf_state { + GPRS_RLCMAC_NULL = 0, /* new created TBF */ + GPRS_RLCMAC_ASSIGN, /* wait for downlink assignment */ + GPRS_RLCMAC_FLOW, /* RLC/MAC flow, resource needed */ + GPRS_RLCMAC_FINISHED, /* flow finished, wait for release */ + GPRS_RLCMAC_WAIT_RELEASE,/* wait for release or restart of DL TBF */ + GPRS_RLCMAC_RELEASING, /* releasing, wait to free TBI/USF */ +}; + +enum gprs_rlcmac_tbf_poll_state { + GPRS_RLCMAC_POLL_NONE = 0, + GPRS_RLCMAC_POLL_SCHED, /* a polling was scheduled */ +}; + +enum gprs_rlcmac_tbf_dl_ass_state { + GPRS_RLCMAC_DL_ASS_NONE = 0, + GPRS_RLCMAC_DL_ASS_SEND_ASS, /* send downlink assignment on next RTS */ + GPRS_RLCMAC_DL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */ +}; + +enum gprs_rlcmac_tbf_ul_ass_state { + GPRS_RLCMAC_UL_ASS_NONE = 0, + GPRS_RLCMAC_UL_ASS_SEND_ASS, /* send uplink assignment on next RTS */ + GPRS_RLCMAC_UL_ASS_WAIT_ACK, /* wait for PACKET CONTROL ACK */ +}; + +enum gprs_rlcmac_tbf_ul_ack_state { + GPRS_RLCMAC_UL_ACK_NONE = 0, + GPRS_RLCMAC_UL_ACK_SEND_ACK, /* send acknowledge on next RTS */ + GPRS_RLCMAC_UL_ACK_WAIT_ACK, /* wait for PACKET CONTROL ACK */ +}; + +enum gprs_rlcmac_tbf_direction { + GPRS_RLCMAC_DL_TBF, + GPRS_RLCMAC_UL_TBF +}; + +#define GPRS_RLCMAC_FLAG_CCCH 0 /* assignment on CCCH */ +#define GPRS_RLCMAC_FLAG_PACCH 1 /* assignment on PACCH */ +#define GPRS_RLCMAC_FLAG_UL_DATA 2 /* uplink data received */ +#define GPRS_RLCMAC_FLAG_DL_ACK 3 /* downlink acknowledge received */ +#define GPRS_RLCMAC_FLAG_TO_UL_ACK 4 +#define GPRS_RLCMAC_FLAG_TO_DL_ACK 5 +#define GPRS_RLCMAC_FLAG_TO_UL_ASS 6 +#define GPRS_RLCMAC_FLAG_TO_DL_ASS 7 +#define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */ + +extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ +extern struct llist_head gprs_rlcmac_dl_tbfs; /* list of downlink TBFs */ +extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ + + struct gprs_rlcmac_tbf { struct llist_head list; enum gprs_rlcmac_tbf_state state; @@ -128,3 +192,35 @@ int tbf_handle(struct gprs_rlcmac_bts *bts, struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, int8_t use_trx, uint8_t ms_class, uint32_t tlli, uint8_t ta, struct gprs_rlcmac_tbf *dl_tbf); + +int tfi_find_free(struct gprs_rlcmac_bts *bts, enum gprs_rlcmac_tbf_direction dir, + uint8_t *_trx, int8_t use_trx); + +struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, + struct gprs_rlcmac_tbf *old_tbf, + enum gprs_rlcmac_tbf_direction dir, uint8_t tfi, uint8_t trx, + uint8_t ms_class, uint8_t single_slot); + +struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, + uint8_t tfi, uint8_t trx, + enum gprs_rlcmac_tbf_direction dir); + +struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, + enum gprs_rlcmac_tbf_direction dir); + +struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts); + +void tbf_free(struct gprs_rlcmac_tbf *tbf); + +int tbf_update(struct gprs_rlcmac_tbf *tbf); + +int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf); + +void tbf_new_state(struct gprs_rlcmac_tbf *tbf, + enum gprs_rlcmac_tbf_state state); + +void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, + unsigned int seconds, unsigned int microseconds); + +void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf); + -- 1.8.4.rc3 From hfreyther at sysmocom.de Sat Oct 19 14:26:35 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sat, 19 Oct 2013 16:26:35 +0200 Subject: [PATCH 5/8] tbf: Move many routines related to the tbf from gprs_rlcmac to tbf.c In-Reply-To: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> References: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1382192798-22541-5-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther --- src/gprs_rlcmac.cpp | 153 ---------------------------------------------------- src/tbf.cpp | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 153 insertions(+), 153 deletions(-) diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 3dab44f..d33dc8c 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -888,159 +888,6 @@ int alloc_algorithm_b(struct gprs_rlcmac_bts *bts, return 0; } -static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf) -{ - struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; - struct gprs_rlcmac_pdch *pdch; - int ts; - - if (tbf->direction == GPRS_RLCMAC_UL_TBF) { - bts->trx[tbf->trx].ul_tbf[tbf->tfi] = NULL; - for (ts = 0; ts < 8; ts++) { - pdch = tbf->pdch[ts]; - if (pdch) - pdch->ul_tbf[tbf->tfi] = NULL; - tbf->pdch[ts] = NULL; - } - } else { - bts->trx[tbf->trx].dl_tbf[tbf->tfi] = NULL; - for (ts = 0; ts < 8; ts++) { - pdch = tbf->pdch[ts]; - if (pdch) - pdch->dl_tbf[tbf->tfi] = NULL; - tbf->pdch[ts] = NULL; - } - } -} - -void tbf_free(struct gprs_rlcmac_tbf *tbf) -{ - struct msgb *msg; - - /* Give final measurement report */ - gprs_rlcmac_rssi_rep(tbf); - gprs_rlcmac_lost_rep(tbf); - - debug_diagram(tbf->diag, "+---------------+"); - debug_diagram(tbf->diag, "| THE END |"); - debug_diagram(tbf->diag, "+---------------+"); - LOGP(DRLCMAC, LOGL_INFO, "Free %s TBF=%d with TLLI=0x%08x.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, - tbf->tlli); - if (tbf->ul_ass_state != GPRS_RLCMAC_UL_ASS_NONE) - LOGP(DRLCMAC, LOGL_ERROR, "Software error: Pending uplink " - "assignment. This may not happen, because the " - "assignment message never gets transmitted. Please " - "be shure not to free in this state. PLEASE FIX!\n"); - if (tbf->dl_ass_state != GPRS_RLCMAC_DL_ASS_NONE) - LOGP(DRLCMAC, LOGL_ERROR, "Software error: Pending downlink " - "assignment. This may not happen, because the " - "assignment message never gets transmitted. Please " - "be shure not to free in this state. PLEASE FIX!\n"); - tbf_timer_stop(tbf); - while ((msg = msgb_dequeue(&tbf->llc_queue))) - msgb_free(msg); - tbf_unlink_pdch(tbf); - llist_del(&tbf->list); - LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF ends here **********\n"); - talloc_free(tbf); -} - -int tbf_update(struct gprs_rlcmac_tbf *tbf) -{ - struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; - struct gprs_rlcmac_tbf *ul_tbf = NULL; - int rc; - - LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF update **********\n"); - - if (tbf->direction != GPRS_RLCMAC_DL_TBF) - return -EINVAL; - - if (!tbf->ms_class) { - LOGP(DRLCMAC, LOGL_DEBUG, "- Cannot update, no class\n"); - return -EINVAL; - } - - ul_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); - - tbf_unlink_pdch(tbf); - rc = bts->alloc_algorithm(bts, ul_tbf, tbf, bts->alloc_algorithm_curst, 0); - /* if no ressource */ - if (rc < 0) { - LOGP(DRLCMAC, LOGL_ERROR, "No ressource after update???\n"); - return -rc; - } - - return 0; -} - -int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf) -{ - if (tbf->control_ts == 0xff) - LOGP(DRLCMAC, LOGL_INFO, "- Setting Control TS %d\n", - tbf->first_common_ts); - else if (tbf->control_ts != tbf->first_common_ts) - LOGP(DRLCMAC, LOGL_INFO, "- Changing Control TS %d\n", - tbf->first_common_ts); - tbf->control_ts = tbf->first_common_ts; - - return 0; -} - - -const char *tbf_state_name[] = { - "NULL", - "ASSIGN", - "FLOW", - "FINISHED", - "WAIT RELEASE", - "RELEASING", -}; - -void tbf_new_state(struct gprs_rlcmac_tbf *tbf, - enum gprs_rlcmac_tbf_state state) -{ - debug_diagram(tbf->diag, "->%s", tbf_state_name[state]); - LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d changes state from %s to %s\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, - tbf_state_name[tbf->state], tbf_state_name[state]); - tbf->state = state; -} - -void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, - unsigned int seconds, unsigned int microseconds) -{ - if (!osmo_timer_pending(&tbf->timer)) - LOGP(DRLCMAC, LOGL_DEBUG, "Starting %s TBF=%d timer %u.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tbf->tfi, T); - else - LOGP(DRLCMAC, LOGL_DEBUG, "Restarting %s TBF=%d timer %u " - "while old timer %u pending \n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tbf->tfi, T, tbf->T); - - tbf->T = T; - tbf->num_T_exp = 0; - - /* Tunning timers can be safely re-scheduled. */ - tbf->timer.data = tbf; - tbf->timer.cb = &tbf_timer_cb; - - osmo_timer_schedule(&tbf->timer, seconds, microseconds); -} - -void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf) -{ - if (osmo_timer_pending(&tbf->timer)) { - LOGP(DRLCMAC, LOGL_DEBUG, "Stopping %s TBF=%d timer %u.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tbf->tfi, tbf->T); - osmo_timer_del(&tbf->timer); - } -} - /* starting time for assigning single slot * This offset must be a multiple of 13. */ #define AGCH_START_OFFSET 52 diff --git a/src/tbf.cpp b/src/tbf.cpp index 4bb42a7..b93d0f1 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -25,6 +25,7 @@ extern "C" { #include +#include } #include @@ -238,6 +239,158 @@ struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, return tbf; } +static void tbf_unlink_pdch(struct gprs_rlcmac_tbf *tbf) +{ + struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; + struct gprs_rlcmac_pdch *pdch; + int ts; + + if (tbf->direction == GPRS_RLCMAC_UL_TBF) { + bts->trx[tbf->trx].ul_tbf[tbf->tfi] = NULL; + for (ts = 0; ts < 8; ts++) { + pdch = tbf->pdch[ts]; + if (pdch) + pdch->ul_tbf[tbf->tfi] = NULL; + tbf->pdch[ts] = NULL; + } + } else { + bts->trx[tbf->trx].dl_tbf[tbf->tfi] = NULL; + for (ts = 0; ts < 8; ts++) { + pdch = tbf->pdch[ts]; + if (pdch) + pdch->dl_tbf[tbf->tfi] = NULL; + tbf->pdch[ts] = NULL; + } + } +} + +void tbf_free(struct gprs_rlcmac_tbf *tbf) +{ + struct msgb *msg; + + /* Give final measurement report */ + gprs_rlcmac_rssi_rep(tbf); + gprs_rlcmac_lost_rep(tbf); + + debug_diagram(tbf->diag, "+---------------+"); + debug_diagram(tbf->diag, "| THE END |"); + debug_diagram(tbf->diag, "+---------------+"); + LOGP(DRLCMAC, LOGL_INFO, "Free %s TBF=%d with TLLI=0x%08x.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, + tbf->tlli); + if (tbf->ul_ass_state != GPRS_RLCMAC_UL_ASS_NONE) + LOGP(DRLCMAC, LOGL_ERROR, "Software error: Pending uplink " + "assignment. This may not happen, because the " + "assignment message never gets transmitted. Please " + "be shure not to free in this state. PLEASE FIX!\n"); + if (tbf->dl_ass_state != GPRS_RLCMAC_DL_ASS_NONE) + LOGP(DRLCMAC, LOGL_ERROR, "Software error: Pending downlink " + "assignment. This may not happen, because the " + "assignment message never gets transmitted. Please " + "be shure not to free in this state. PLEASE FIX!\n"); + tbf_timer_stop(tbf); + while ((msg = msgb_dequeue(&tbf->llc_queue))) + msgb_free(msg); + tbf_unlink_pdch(tbf); + llist_del(&tbf->list); + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF ends here **********\n"); + talloc_free(tbf); +} + +int tbf_update(struct gprs_rlcmac_tbf *tbf) +{ + struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; + struct gprs_rlcmac_tbf *ul_tbf = NULL; + int rc; + + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF update **********\n"); + + if (tbf->direction != GPRS_RLCMAC_DL_TBF) + return -EINVAL; + + if (!tbf->ms_class) { + LOGP(DRLCMAC, LOGL_DEBUG, "- Cannot update, no class\n"); + return -EINVAL; + } + + ul_tbf = tbf_by_tlli(tbf->tlli, GPRS_RLCMAC_UL_TBF); + + tbf_unlink_pdch(tbf); + rc = bts->alloc_algorithm(bts, ul_tbf, tbf, bts->alloc_algorithm_curst, 0); + /* if no ressource */ + if (rc < 0) { + LOGP(DRLCMAC, LOGL_ERROR, "No ressource after update???\n"); + return -rc; + } + + return 0; +} + +int tbf_assign_control_ts(struct gprs_rlcmac_tbf *tbf) +{ + if (tbf->control_ts == 0xff) + LOGP(DRLCMAC, LOGL_INFO, "- Setting Control TS %d\n", + tbf->first_common_ts); + else if (tbf->control_ts != tbf->first_common_ts) + LOGP(DRLCMAC, LOGL_INFO, "- Changing Control TS %d\n", + tbf->first_common_ts); + tbf->control_ts = tbf->first_common_ts; + + return 0; +} + +static const char *tbf_state_name[] = { + "NULL", + "ASSIGN", + "FLOW", + "FINISHED", + "WAIT RELEASE", + "RELEASING", +}; + +void tbf_new_state(struct gprs_rlcmac_tbf *tbf, + enum gprs_rlcmac_tbf_state state) +{ + debug_diagram(tbf->diag, "->%s", tbf_state_name[state]); + LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d changes state from %s to %s\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, + tbf_state_name[tbf->state], tbf_state_name[state]); + tbf->state = state; +} + +void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, + unsigned int seconds, unsigned int microseconds) +{ + if (!osmo_timer_pending(&tbf->timer)) + LOGP(DRLCMAC, LOGL_DEBUG, "Starting %s TBF=%d timer %u.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tbf->tfi, T); + else + LOGP(DRLCMAC, LOGL_DEBUG, "Restarting %s TBF=%d timer %u " + "while old timer %u pending \n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tbf->tfi, T, tbf->T); + + tbf->T = T; + tbf->num_T_exp = 0; + + /* Tunning timers can be safely re-scheduled. */ + tbf->timer.data = tbf; + tbf->timer.cb = &tbf_timer_cb; + + osmo_timer_schedule(&tbf->timer, seconds, microseconds); +} + +void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf) +{ + if (osmo_timer_pending(&tbf->timer)) { + LOGP(DRLCMAC, LOGL_DEBUG, "Stopping %s TBF=%d timer %u.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tbf->tfi, tbf->T); + osmo_timer_del(&tbf->timer); + } +} + void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) { for (uint8_t tfi = 0; tfi < 32; tfi++) { -- 1.8.4.rc3 From hfreyther at sysmocom.de Sat Oct 19 14:26:37 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sat, 19 Oct 2013 16:26:37 +0200 Subject: [PATCH 7/8] tbf: Move the tbf_timer_cb into the tbf class In-Reply-To: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> References: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1382192798-22541-7-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther Introduce the first instance method for printing out diagonistic about itself and create a jump function for it. --- src/gprs_rlcmac.cpp | 150 ------------------------------- src/gprs_rlcmac.h | 2 - src/gprs_rlcmac_data.cpp | 72 +-------------- src/tbf.cpp | 227 +++++++++++++++++++++++++++++++++++++++++++++++ src/tbf.h | 3 + 5 files changed, 231 insertions(+), 223 deletions(-) diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 8841445..9b4e643 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -253,156 +253,6 @@ static inline int8_t find_free_usf(struct gprs_rlcmac_pdch *pdch, uint8_t ts) return -1; } -/* lookup TBF Entity (by TFI) */ -struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, - uint8_t tfi, uint8_t trx, enum gprs_rlcmac_tbf_direction dir) -{ - struct gprs_rlcmac_tbf *tbf; - - if (tfi >= 32 || trx >= 8) - return NULL; - - if (dir == GPRS_RLCMAC_UL_TBF) - tbf = bts->trx[trx].ul_tbf[tfi]; - else - tbf = bts->trx[trx].dl_tbf[tfi]; - if (!tbf) - return NULL; - - if (tbf->state != GPRS_RLCMAC_RELEASING) - return tbf; - - return NULL; -} - -/* search for active downlink or uplink tbf */ -struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, - enum gprs_rlcmac_tbf_direction dir) -{ - struct gprs_rlcmac_tbf *tbf; - if (dir == GPRS_RLCMAC_UL_TBF) { - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->tlli == tlli && tbf->tlli_valid) - return tbf; - } - } else { - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->tlli == tlli) - return tbf; - } - } - return NULL; -} - -struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) -{ - struct gprs_rlcmac_tbf *tbf; - - /* only one TBF can poll on specific TS/FN, because scheduler can only - * schedule one downlink control block (with polling) at a FN per TS */ - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED - && tbf->poll_fn == fn && tbf->trx == trx - && tbf->control_ts == ts) - return tbf; - } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING - && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED - && tbf->poll_fn == fn && tbf->trx == trx - && tbf->control_ts == ts) - return tbf; - } - return NULL; -} - -struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, - struct gprs_rlcmac_tbf *old_tbf, enum gprs_rlcmac_tbf_direction dir, - uint8_t tfi, uint8_t trx, - uint8_t ms_class, uint8_t single_slot) -{ - struct gprs_rlcmac_tbf *tbf; - int rc; - -#ifdef DEBUG_DIAGRAM - /* hunt for first free number in diagram */ - int diagram_num; - for (diagram_num = 0; ; diagram_num++) { - llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->diag == diagram_num) - goto next_diagram; - } - llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->diag == diagram_num) - goto next_diagram; - } - break; -next_diagram: - continue; - } -#endif - - LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); - LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d " - "MS_CLASS=%d\n", (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", - tfi, trx, ms_class); - - if (trx >= 8 || tfi >= 32) - return NULL; - - tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_tbf); - if (!tbf) - return NULL; - -#ifdef DEBUG_DIAGRAM - tbf->diag = diagram_num; -#endif - tbf->direction = dir; - tbf->tfi = tfi; - tbf->trx = trx; - tbf->arfcn = bts->trx[trx].arfcn; - tbf->ms_class = ms_class; - tbf->ws = 64; - tbf->sns = 128; - /* select algorithm */ - rc = bts->alloc_algorithm(bts, old_tbf, tbf, bts->alloc_algorithm_curst, - single_slot); - /* if no ressource */ - if (rc < 0) { - talloc_free(tbf); - return NULL; - } - /* assign control ts */ - tbf->control_ts = 0xff; - rc = tbf_assign_control_ts(tbf); - /* if no ressource */ - if (rc < 0) { - talloc_free(tbf); - return NULL; - } - - /* set timestamp */ - gettimeofday(&tbf->meas.dl_bw_tv, NULL); - gettimeofday(&tbf->meas.rssi_tv, NULL); - gettimeofday(&tbf->meas.dl_loss_tv, NULL); - - INIT_LLIST_HEAD(&tbf->llc_queue); - if (dir == GPRS_RLCMAC_UL_TBF) - llist_add(&tbf->list, &gprs_rlcmac_ul_tbfs); - else - llist_add(&tbf->list, &gprs_rlcmac_dl_tbfs); - - debug_diagram(tbf->diag, "+-----------------+"); - debug_diagram(tbf->diag, "|NEW %s TBF TFI=%2d|", - (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi); - debug_diagram(tbf->diag, "+-----------------+"); - - return tbf; -} - /* Slot Allocation: Algorithm A * * Assign single slot for uplink and downlink diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index a40ebd6..8863af4 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -183,8 +183,6 @@ void write_packet_uplink_ack(RlcMacDownlink_t * block, struct gprs_rlcmac_tbf *t int gprs_rlcmac_tx_ul_ud(gprs_rlcmac_tbf *tbf); -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); diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index bc55c57..b5ea7c9 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -79,20 +79,7 @@ static void gprs_rlcmac_downlink_assignment(gprs_rlcmac_tbf *tbf, uint8_t poll, static int gprs_rlcmac_diag(struct gprs_rlcmac_tbf *tbf) { - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n"); - else if (tbf->direction == GPRS_RLCMAC_UL_TBF) - LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n"); - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) - LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n"); - else if (tbf->direction == GPRS_RLCMAC_DL_TBF) - LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n"); - - return 0; + return tbf->rlcmac_diag(); } int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf) @@ -487,63 +474,6 @@ int gprs_rlcmac_rcv_control_block(bitvec *rlc_block, uint8_t trx, uint8_t ts, char debug_imsi[16]; #endif -void tbf_timer_cb(void *_tbf) -{ - struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf; - - LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d timer %u expired.\n", - (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, - tbf->T); - - tbf->num_T_exp++; - - switch (tbf->T) { -#ifdef DEBUG_DL_ASS_IDLE - case 1234: - gprs_rlcmac_trigger_downlink_assignment(tbf, NULL, debug_imsi); - break; -#endif - case 0: /* assignment */ - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { - if (tbf->state == GPRS_RLCMAC_ASSIGN) { - LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to " - "PACCH assignment timeout.\n"); - tbf_free(tbf); - } else - LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not " - "in assign state\n"); - } - if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { - /* change state to FLOW, so scheduler will start transmission */ - tbf->dir.dl.wait_confirm = 0; - if (tbf->state == GPRS_RLCMAC_ASSIGN) { - tbf_new_state(tbf, GPRS_RLCMAC_FLOW); - tbf_assign_control_ts(tbf); - } else - LOGP(DRLCMAC, LOGL_NOTICE, "Continue flow after " - "IMM.ASS confirm\n"); - } - break; - case 3169: - case 3191: - case 3195: - LOGP(DRLCMAC, LOGL_NOTICE, "TBF T%d timeout during " - "transsmission\n", tbf->T); - gprs_rlcmac_diag(tbf); - /* fall through */ - case 3193: - if (tbf->T == 3193) - debug_diagram(tbf->diag, "T3193 timeout"); - LOGP(DRLCMAC, LOGL_DEBUG, "TBF will be freed due to timeout\n"); - /* free TBF */ - tbf_free(tbf); - break; - default: - LOGP(DRLCMAC, LOGL_ERROR, "Timer expired in unknown mode: %u\n", - tbf->T); - } -} - /* * UL data block flow */ diff --git a/src/tbf.cpp b/src/tbf.cpp index b93d0f1..918520c 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -31,6 +31,8 @@ extern "C" { #include #include +extern void *tall_pcu_ctx; + static inline void tbf_update_ms_class(struct gprs_rlcmac_tbf *tbf, const uint8_t ms_class) { @@ -391,6 +393,231 @@ void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf) } } +/* lookup TBF Entity (by TFI) */ +struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, + uint8_t tfi, uint8_t trx, enum gprs_rlcmac_tbf_direction dir) +{ + struct gprs_rlcmac_tbf *tbf; + + if (tfi >= 32 || trx >= 8) + return NULL; + + if (dir == GPRS_RLCMAC_UL_TBF) + tbf = bts->trx[trx].ul_tbf[tfi]; + else + tbf = bts->trx[trx].dl_tbf[tfi]; + if (!tbf) + return NULL; + + if (tbf->state != GPRS_RLCMAC_RELEASING) + return tbf; + + return NULL; +} + +/* search for active downlink or uplink tbf */ +struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, + enum gprs_rlcmac_tbf_direction dir) +{ + struct gprs_rlcmac_tbf *tbf; + if (dir == GPRS_RLCMAC_UL_TBF) { + llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->tlli == tlli && tbf->tlli_valid) + return tbf; + } + } else { + llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->tlli == tlli) + return tbf; + } + } + return NULL; +} + +struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) +{ + struct gprs_rlcmac_tbf *tbf; + + /* only one TBF can poll on specific TS/FN, because scheduler can only + * schedule one downlink control block (with polling) at a FN per TS */ + llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx == trx + && tbf->control_ts == ts) + return tbf; + } + llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + if (tbf->state != GPRS_RLCMAC_RELEASING + && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED + && tbf->poll_fn == fn && tbf->trx == trx + && tbf->control_ts == ts) + return tbf; + } + return NULL; +} + +struct gprs_rlcmac_tbf *tbf_alloc(struct gprs_rlcmac_bts *bts, + struct gprs_rlcmac_tbf *old_tbf, enum gprs_rlcmac_tbf_direction dir, + uint8_t tfi, uint8_t trx, + uint8_t ms_class, uint8_t single_slot) +{ + struct gprs_rlcmac_tbf *tbf; + int rc; + +#ifdef DEBUG_DIAGRAM + /* hunt for first free number in diagram */ + int diagram_num; + for (diagram_num = 0; ; diagram_num++) { + llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { + if (tbf->diag == diagram_num) + goto next_diagram; + } + llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { + if (tbf->diag == diagram_num) + goto next_diagram; + } + break; +next_diagram: + continue; + } +#endif + + LOGP(DRLCMAC, LOGL_DEBUG, "********** TBF starts here **********\n"); + LOGP(DRLCMAC, LOGL_INFO, "Allocating %s TBF: TFI=%d TRX=%d " + "MS_CLASS=%d\n", (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", + tfi, trx, ms_class); + + if (trx >= 8 || tfi >= 32) + return NULL; + + tbf = talloc_zero(tall_pcu_ctx, struct gprs_rlcmac_tbf); + if (!tbf) + return NULL; + +#ifdef DEBUG_DIAGRAM + tbf->diag = diagram_num; +#endif + tbf->direction = dir; + tbf->tfi = tfi; + tbf->trx = trx; + tbf->arfcn = bts->trx[trx].arfcn; + tbf->ms_class = ms_class; + tbf->ws = 64; + tbf->sns = 128; + /* select algorithm */ + rc = bts->alloc_algorithm(bts, old_tbf, tbf, bts->alloc_algorithm_curst, + single_slot); + /* if no ressource */ + if (rc < 0) { + talloc_free(tbf); + return NULL; + } + /* assign control ts */ + tbf->control_ts = 0xff; + rc = tbf_assign_control_ts(tbf); + /* if no ressource */ + if (rc < 0) { + talloc_free(tbf); + return NULL; + } + + /* set timestamp */ + gettimeofday(&tbf->meas.dl_bw_tv, NULL); + gettimeofday(&tbf->meas.rssi_tv, NULL); + gettimeofday(&tbf->meas.dl_loss_tv, NULL); + + INIT_LLIST_HEAD(&tbf->llc_queue); + if (dir == GPRS_RLCMAC_UL_TBF) + llist_add(&tbf->list, &gprs_rlcmac_ul_tbfs); + else + llist_add(&tbf->list, &gprs_rlcmac_dl_tbfs); + + debug_diagram(tbf->diag, "+-----------------+"); + debug_diagram(tbf->diag, "|NEW %s TBF TFI=%2d|", + (dir == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tfi); + debug_diagram(tbf->diag, "+-----------------+"); + + return tbf; +} + +void tbf_timer_cb(void *_tbf) +{ + struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf; + + LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d timer %u expired.\n", + (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, + tbf->T); + + tbf->num_T_exp++; + + switch (tbf->T) { +#ifdef DEBUG_DL_ASS_IDLE + case 1234: + gprs_rlcmac_trigger_downlink_assignment(tbf, NULL, debug_imsi); + break; +#endif + case 0: /* assignment */ + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { + if (tbf->state == GPRS_RLCMAC_ASSIGN) { + LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to " + "PACCH assignment timeout.\n"); + tbf_free(tbf); + } else + LOGP(DRLCMAC, LOGL_ERROR, "Error: TBF is not " + "in assign state\n"); + } + if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { + /* change state to FLOW, so scheduler will start transmission */ + tbf->dir.dl.wait_confirm = 0; + if (tbf->state == GPRS_RLCMAC_ASSIGN) { + tbf_new_state(tbf, GPRS_RLCMAC_FLOW); + tbf_assign_control_ts(tbf); + } else + LOGP(DRLCMAC, LOGL_NOTICE, "Continue flow after " + "IMM.ASS confirm\n"); + } + break; + case 3169: + case 3191: + case 3195: + LOGP(DRLCMAC, LOGL_NOTICE, "TBF T%d timeout during " + "transsmission\n", tbf->T); + tbf->rlcmac_diag(); + /* fall through */ + case 3193: + if (tbf->T == 3193) + debug_diagram(tbf->diag, "T3193 timeout"); + LOGP(DRLCMAC, LOGL_DEBUG, "TBF will be freed due to timeout\n"); + /* free TBF */ + tbf_free(tbf); + break; + default: + LOGP(DRLCMAC, LOGL_ERROR, "Timer expired in unknown mode: %u\n", + tbf->T); + } +} + +int gprs_rlcmac_tbf::rlcmac_diag() +{ + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on CCCH\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Assignment was on PACCH\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_UL_DATA))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Uplink data was received\n"); + else if (direction == GPRS_RLCMAC_UL_TBF) + LOGP(DRLCMAC, LOGL_NOTICE, "- No uplink data received yet\n"); + if ((state_flags & (1 << GPRS_RLCMAC_FLAG_DL_ACK))) + LOGP(DRLCMAC, LOGL_NOTICE, "- Downlink ACK was received\n"); + else if (direction == GPRS_RLCMAC_DL_TBF) + LOGP(DRLCMAC, LOGL_NOTICE, "- No downlink ACK received yet\n"); + + return 0; +} + void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) { for (uint8_t tfi = 0; tfi < 32; tfi++) { diff --git a/src/tbf.h b/src/tbf.h index 74df237..d2aead2 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -91,6 +91,7 @@ struct gprs_rlcmac_tbf { static void free_all(struct gprs_rlcmac_trx *trx); static void free_all(struct gprs_rlcmac_pdch *pdch); + int rlcmac_diag(); struct llist_head list; enum gprs_rlcmac_tbf_state state; @@ -229,3 +230,5 @@ void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf); +void tbf_timer_cb(void *_tbf); + -- 1.8.4.rc3 From hfreyther at sysmocom.de Sat Oct 19 14:26:36 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sat, 19 Oct 2013 16:26:36 +0200 Subject: [PATCH 6/8] tbf: Remove dead code that called tbf_free In-Reply-To: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> References: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1382192798-22541-6-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther --- src/gprs_rlcmac.cpp | 48 ------------------------------------------------ 1 file changed, 48 deletions(-) diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index d33dc8c..8841445 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -950,54 +950,6 @@ struct gprs_rlcmac_sba *sba_find(uint8_t trx, uint8_t ts, uint32_t fn) return NULL; } -#if 0 -static void tbf_gsm_timer_cb(void *_tbf) -{ - struct gprs_rlcmac_tbf *tbf = (struct gprs_rlcmac_tbf *)_tbf; - - tbf->num_fT_exp++; - - switch (tbf->fT) { - case 0: -hier alles berdenken - // This is timer for delay RLC/MAC data sending after Downlink Immediate Assignment on CCCH. - gprs_rlcmac_segment_llc_pdu(tbf); - LOGP(DRLCMAC, LOGL_NOTICE, "TBF: [DOWNLINK] END TFI: %u TLLI: 0x%08x \n", tbf->tfi, tbf->tlli); - tbf_free(tbf); - break; - default: - LOGP(DRLCMAC, LOGL_NOTICE, "Timer expired in unknown mode: %u \n", tbf->fT); - } -} - -static void tbf_gsm_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int fT, - int frames) -{ - if (osmo_gsm_timer_pending(&tbf->gsm_timer)) - LOGP(DRLCMAC, LOGL_NOTICE, "Starting TBF timer %u while old timer %u pending \n", fT, tbf->fT); - tbf->fT = fT; - tbf->num_fT_exp = 0; - - /* FIXME: we should do this only once ? */ - tbf->gsm_timer.data = tbf; - tbf->gsm_timer.cb = &tbf_gsm_timer_cb; - - osmo_gsm_timer_schedule(&tbf->gsm_timer, frames); -} - -eine stop-funktion, auch im tbf_free aufrufen - -#endif - -#if 0 -void gprs_rlcmac_enqueue_block(bitvec *block, int len) -{ - struct msgb *msg = msgb_alloc(len, "rlcmac_dl"); - bitvec_pack(block, msgb_put(msg, len)); - msgb_enqueue(&block_queue, msg); -} -#endif - /* received RLC/MAC block from L1 */ int gprs_rlcmac_rcv_block(uint8_t trx, uint8_t ts, uint8_t *data, uint8_t len, uint32_t fn, int8_t rssi) -- 1.8.4.rc3 From hfreyther at sysmocom.de Sat Oct 19 14:26:33 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sat, 19 Oct 2013 16:26:33 +0200 Subject: [PATCH 3/8] tbf: Move the code to close all timeslots into the tbf class In-Reply-To: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> References: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1382192798-22541-3-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther Move the code out of the sysmocom_socket (as this is only required to talk to our hardware) and into the TBF class that actually knows what a TBF is. --- src/sysmo_sock.cpp | 12 ++---------- src/tbf.cpp | 14 ++++++++++++++ src/tbf.h | 4 ++++ 3 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/sysmo_sock.cpp b/src/sysmo_sock.cpp index d075df0..591c105 100644 --- a/src/sysmo_sock.cpp +++ b/src/sysmo_sock.cpp @@ -82,8 +82,7 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost) { struct osmo_fd *bfd = &state->conn_bfd; struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; - struct gprs_rlcmac_tbf *tbf; - uint8_t trx, ts, tfi; + uint8_t trx, ts; LOGP(DL1IF, LOGL_NOTICE, "PCU socket has %s connection\n", (lost) ? "LOST" : "closed"); @@ -108,14 +107,7 @@ static void pcu_sock_close(struct pcu_sock_state *state, int lost) #endif for (ts = 0; ts < 8; ts++) bts->trx[trx].pdch[ts].enable = 0; - for (tfi = 0; tfi < 32; tfi++) { - tbf = bts->trx[trx].ul_tbf[tfi]; - if (tbf) - tbf_free(tbf); - tbf = bts->trx[trx].dl_tbf[tfi]; - if (tbf) - tbf_free(tbf); - } + gprs_rlcmac_tbf::free_all(&bts->trx[trx]); } gprs_bssgp_destroy_or_exit(); diff --git a/src/tbf.cpp b/src/tbf.cpp index 79f1ea8..8aff463 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -237,3 +237,17 @@ struct gprs_rlcmac_tbf *tbf_alloc_ul(struct gprs_rlcmac_bts *bts, return tbf; } + +void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) +{ + for (uint8_t tfi = 0; tfi < 32; tfi++) { + struct gprs_rlcmac_tbf *tbf; + + tbf = trx->ul_tbf[tfi]; + if (tbf) + tbf_free(tbf); + tbf = trx->dl_tbf[tfi]; + if (tbf) + tbf_free(tbf); + } +} diff --git a/src/tbf.h b/src/tbf.h index cf2481d..b73d0b8 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -87,6 +87,10 @@ extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ struct gprs_rlcmac_tbf { + + static void free_all(struct gprs_rlcmac_trx *trx); + + struct llist_head list; enum gprs_rlcmac_tbf_state state; uint32_t state_flags; -- 1.8.4.rc3 From hfreyther at sysmocom.de Sat Oct 19 14:26:31 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sat, 19 Oct 2013 16:26:31 +0200 Subject: [PATCH 1/8] tbf: Move the struct to the tbf.h header file Message-ID: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther This is the begin of a long march of turning tbf into a C++ class and properly hiding the secrets inside this implementation instead of having it spread across various different files. --- src/gprs_rlcmac.cpp | 1 + src/gprs_rlcmac.h | 97 -------------------------------------------- src/gprs_rlcmac_meas.cpp | 1 + src/gprs_rlcmac_sched.cpp | 1 + src/pcu_l1_if.cpp | 1 + src/tbf.h | 100 +++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 103 insertions(+), 98 deletions(-) diff --git a/src/gprs_rlcmac.cpp b/src/gprs_rlcmac.cpp index 6546f8a..3dab44f 100644 --- a/src/gprs_rlcmac.cpp +++ b/src/gprs_rlcmac.cpp @@ -22,6 +22,7 @@ #include #include #include +#include /* 3GPP TS 05.02 Annex B.1 */ diff --git a/src/gprs_rlcmac.h b/src/gprs_rlcmac.h index 8de7417..6fdf600 100644 --- a/src/gprs_rlcmac.h +++ b/src/gprs_rlcmac.h @@ -155,103 +155,6 @@ enum gprs_rlcmac_tbf_direction { #define GPRS_RLCMAC_FLAG_TO_DL_ASS 7 #define GPRS_RLCMAC_FLAG_TO_MASK 0xf0 /* timeout bits */ -struct gprs_rlcmac_tbf { - struct llist_head list; - enum gprs_rlcmac_tbf_state state; - uint32_t state_flags; - enum gprs_rlcmac_tbf_direction direction; - uint8_t tfi; - uint32_t tlli; - uint8_t tlli_valid; - uint8_t trx; - uint16_t arfcn; - uint8_t tsc; - uint8_t first_ts; /* first TS used by TBF */ - uint8_t first_common_ts; /* first TS that the phone can send and - reveive simultaniously */ - uint8_t control_ts; /* timeslot control messages and polling */ - uint8_t ms_class; - struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */ - uint16_t ta; - uint8_t llc_frame[LLC_MAX_LEN]; /* current DL or UL frame */ - uint16_t llc_index; /* current write/read position of frame */ - uint16_t llc_length; /* len of current DL LLC_frame, 0 == no frame */ - struct llist_head llc_queue; /* queued LLC DL data */ - - enum gprs_rlcmac_tbf_dl_ass_state dl_ass_state; - enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state; - enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state; - - enum gprs_rlcmac_tbf_poll_state poll_state; - uint32_t poll_fn; /* frame number to poll */ - - uint16_t ws; /* window size */ - uint16_t sns; /* sequence number space */ - - /* Please note that all variables here will be reset when changing - * from WAIT RELEASE back to FLOW state (re-use of TBF). - * All states that need reset must be in this struct, so this is why - * variables are in both (dl and ul) structs and not outside union. - */ - union { - struct { - uint16_t bsn; /* block sequence number */ - uint16_t v_s; /* send state */ - uint16_t v_a; /* ack state */ - char v_b[RLC_MAX_SNS/2]; /* acknowledge state array */ - int32_t tx_counter; /* count all transmitted blocks */ - char imsi[16]; /* store IMSI for PCH retransmission */ - uint8_t wait_confirm; /* wait for CCCH IMM.ASS cnf */ - } dl; - struct { - uint16_t bsn; /* block sequence number */ - uint16_t v_r; /* receive state */ - uint16_t v_q; /* receive window state */ - char v_n[RLC_MAX_SNS/2]; /* receive state array */ - int32_t rx_counter; /* count all received blocks */ - uint8_t n3103; /* N3103 counter */ - uint8_t usf[8]; /* list USFs per PDCH (timeslot) */ - uint8_t contention_resolution_done; /* set after done */ - uint8_t final_ack_sent; /* set if we sent final ack */ - } ul; - } dir; - uint8_t rlc_block[RLC_MAX_SNS/2][RLC_MAX_LEN]; /* block history */ - uint8_t rlc_block_len[RLC_MAX_SNS/2]; /* block len of history */ - - uint8_t n3105; /* N3105 counter */ - - struct osmo_timer_list timer; - unsigned int T; /* Txxxx number */ - unsigned int num_T_exp; /* number of consecutive T expirations */ - - struct osmo_gsm_timer_list gsm_timer; - unsigned int fT; /* fTxxxx number */ - unsigned int num_fT_exp; /* number of consecutive fT expirations */ - - struct { - char imsi[16]; - - struct timeval dl_bw_tv; /* timestamp for dl bw calculation */ - uint32_t dl_bw_octets; /* number of octets since bw_tv */ - - struct timeval rssi_tv; /* timestamp for rssi calculation */ - int32_t rssi_sum; /* sum of rssi values */ - int rssi_num; /* number of rssi values added since rssi_tv */ - - struct timeval dl_loss_tv; /* timestamp for loss calculation */ - uint16_t dl_loss_lost; /* sum of lost packets */ - uint16_t dl_loss_received; /* sum of received packets */ - - } meas; - - uint8_t cs; /* current coding scheme */ - -#ifdef DEBUG_DIAGRAM - int diag; /* number where TBF is presented in diagram */ - int diag_new; /* used to format output of new TBF */ -#endif -}; - extern struct llist_head gprs_rlcmac_ul_tbfs; /* list of uplink TBFs */ extern struct llist_head gprs_rlcmac_dl_tbfs; /* list of downlink TBFs */ extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ diff --git a/src/gprs_rlcmac_meas.cpp b/src/gprs_rlcmac_meas.cpp index 75da835..3229795 100644 --- a/src/gprs_rlcmac_meas.cpp +++ b/src/gprs_rlcmac_meas.cpp @@ -20,6 +20,7 @@ #include #include #include +#include #include #include diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index 6290c5d..f3edaac 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -20,6 +20,7 @@ #include #include #include +#include uint32_t sched_poll(uint8_t trx, uint8_t ts, uint32_t fn, uint8_t block_nr, struct gprs_rlcmac_tbf **poll_tbf, diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 218dc23..47bf740 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -37,6 +37,7 @@ extern "C" { #include #include #include +#include // FIXME: move this, when changed from c++ to c. extern "C" { diff --git a/src/tbf.h b/src/tbf.h index 330eac1..a6dfced 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -18,9 +18,107 @@ #pragma once +#include "gprs_rlcmac.h" + #include -struct gprs_rlcmac_bts; +struct gprs_rlcmac_tbf { + struct llist_head list; + enum gprs_rlcmac_tbf_state state; + uint32_t state_flags; + enum gprs_rlcmac_tbf_direction direction; + uint8_t tfi; + uint32_t tlli; + uint8_t tlli_valid; + uint8_t trx; + uint16_t arfcn; + uint8_t tsc; + uint8_t first_ts; /* first TS used by TBF */ + uint8_t first_common_ts; /* first TS that the phone can send and + reveive simultaniously */ + uint8_t control_ts; /* timeslot control messages and polling */ + uint8_t ms_class; + struct gprs_rlcmac_pdch *pdch[8]; /* list of PDCHs allocated to TBF */ + uint16_t ta; + uint8_t llc_frame[LLC_MAX_LEN]; /* current DL or UL frame */ + uint16_t llc_index; /* current write/read position of frame */ + uint16_t llc_length; /* len of current DL LLC_frame, 0 == no frame */ + struct llist_head llc_queue; /* queued LLC DL data */ + + enum gprs_rlcmac_tbf_dl_ass_state dl_ass_state; + enum gprs_rlcmac_tbf_ul_ass_state ul_ass_state; + enum gprs_rlcmac_tbf_ul_ack_state ul_ack_state; + + enum gprs_rlcmac_tbf_poll_state poll_state; + uint32_t poll_fn; /* frame number to poll */ + + uint16_t ws; /* window size */ + uint16_t sns; /* sequence number space */ + + /* Please note that all variables here will be reset when changing + * from WAIT RELEASE back to FLOW state (re-use of TBF). + * All states that need reset must be in this struct, so this is why + * variables are in both (dl and ul) structs and not outside union. + */ + union { + struct { + uint16_t bsn; /* block sequence number */ + uint16_t v_s; /* send state */ + uint16_t v_a; /* ack state */ + char v_b[RLC_MAX_SNS/2]; /* acknowledge state array */ + int32_t tx_counter; /* count all transmitted blocks */ + char imsi[16]; /* store IMSI for PCH retransmission */ + uint8_t wait_confirm; /* wait for CCCH IMM.ASS cnf */ + } dl; + struct { + uint16_t bsn; /* block sequence number */ + uint16_t v_r; /* receive state */ + uint16_t v_q; /* receive window state */ + char v_n[RLC_MAX_SNS/2]; /* receive state array */ + int32_t rx_counter; /* count all received blocks */ + uint8_t n3103; /* N3103 counter */ + uint8_t usf[8]; /* list USFs per PDCH (timeslot) */ + uint8_t contention_resolution_done; /* set after done */ + uint8_t final_ack_sent; /* set if we sent final ack */ + } ul; + } dir; + uint8_t rlc_block[RLC_MAX_SNS/2][RLC_MAX_LEN]; /* block history */ + uint8_t rlc_block_len[RLC_MAX_SNS/2]; /* block len of history */ + + uint8_t n3105; /* N3105 counter */ + + struct osmo_timer_list timer; + unsigned int T; /* Txxxx number */ + unsigned int num_T_exp; /* number of consecutive T expirations */ + + struct osmo_gsm_timer_list gsm_timer; + unsigned int fT; /* fTxxxx number */ + unsigned int num_fT_exp; /* number of consecutive fT expirations */ + + struct { + char imsi[16]; + + struct timeval dl_bw_tv; /* timestamp for dl bw calculation */ + uint32_t dl_bw_octets; /* number of octets since bw_tv */ + + struct timeval rssi_tv; /* timestamp for rssi calculation */ + int32_t rssi_sum; /* sum of rssi values */ + int rssi_num; /* number of rssi values added since rssi_tv */ + + struct timeval dl_loss_tv; /* timestamp for loss calculation */ + uint16_t dl_loss_lost; /* sum of lost packets */ + uint16_t dl_loss_received; /* sum of received packets */ + + } meas; + + uint8_t cs; /* current coding scheme */ + +#ifdef DEBUG_DIAGRAM + int diag; /* number where TBF is presented in diagram */ + int diag_new; /* used to format output of new TBF */ +#endif +}; + /* dispatch Unitdata.DL messages */ int tbf_handle(struct gprs_rlcmac_bts *bts, -- 1.8.4.rc3 From hfreyther at sysmocom.de Sat Oct 19 14:26:34 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sat, 19 Oct 2013 16:26:34 +0200 Subject: [PATCH 4/8] tbf: Add another variant of the free_all now by pdch In-Reply-To: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> References: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1382192798-22541-4-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther --- src/pcu_l1_if.cpp | 12 ++---------- src/tbf.cpp | 14 ++++++++++++++ src/tbf.h | 1 + 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/pcu_l1_if.cpp b/src/pcu_l1_if.cpp index 47bf740..a31974f 100644 --- a/src/pcu_l1_if.cpp +++ b/src/pcu_l1_if.cpp @@ -306,20 +306,12 @@ static int pcu_rx_rach_ind(struct gsm_pcu_if_rach_ind *rach_ind) int flush_pdch(struct gprs_rlcmac_pdch *pdch, uint8_t trx, uint8_t ts) { - uint8_t tfi; - struct gprs_rlcmac_tbf *tbf; struct gprs_rlcmac_paging *pag; struct gprs_rlcmac_sba *sba, *sba2; /* kick all TBF on slot */ - for (tfi = 0; tfi < 32; tfi++) { - tbf = pdch->ul_tbf[tfi]; - if (tbf) - tbf_free(tbf); - tbf = pdch->dl_tbf[tfi]; - if (tbf) - tbf_free(tbf); - } + gprs_rlcmac_tbf::free_all(pdch); + /* flush all pending paging messages */ while ((pag = gprs_rlcmac_dequeue_paging(pdch))) talloc_free(pag); diff --git a/src/tbf.cpp b/src/tbf.cpp index 8aff463..4bb42a7 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -251,3 +251,17 @@ void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_trx *trx) tbf_free(tbf); } } + +void gprs_rlcmac_tbf::free_all(struct gprs_rlcmac_pdch *pdch) +{ + for (uint8_t tfi = 0; tfi < 32; tfi++) { + struct gprs_rlcmac_tbf *tbf; + + tbf = pdch->ul_tbf[tfi]; + if (tbf) + tbf_free(tbf); + tbf = pdch->dl_tbf[tfi]; + if (tbf) + tbf_free(tbf); + } +} diff --git a/src/tbf.h b/src/tbf.h index b73d0b8..74df237 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -89,6 +89,7 @@ extern struct llist_head gprs_rlcmac_sbas; /* list of single block allocs */ struct gprs_rlcmac_tbf { static void free_all(struct gprs_rlcmac_trx *trx); + static void free_all(struct gprs_rlcmac_pdch *pdch); struct llist_head list; -- 1.8.4.rc3 From hfreyther at sysmocom.de Sat Oct 19 14:26:38 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sat, 19 Oct 2013 16:26:38 +0200 Subject: [PATCH 8/8] tbf: Prepare to make thing things private in the tbf, start with the state In-Reply-To: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> References: <1382192798-22541-1-git-send-email-hfreyther@sysmocom.de> Message-ID: <1382192798-22541-8-git-send-email-hfreyther@sysmocom.de> From: Holger Hans Peter Freyther There really shouldn't be too many callers of state. Instead the tbf should dispatch depending on the internal state. For now introduce state_is and state_is_not accessor functions so we can start to see who is using the internal state. --- src/gprs_rlcmac_data.cpp | 18 +++++++++--------- src/gprs_rlcmac_sched.cpp | 6 +++--- src/tbf.cpp | 18 +++++++++--------- src/tbf.h | 24 +++++++++++++++++++++++- 4 files changed, 44 insertions(+), 22 deletions(-) diff --git a/src/gprs_rlcmac_data.cpp b/src/gprs_rlcmac_data.cpp index b5ea7c9..17c4b1b 100644 --- a/src/gprs_rlcmac_data.cpp +++ b/src/gprs_rlcmac_data.cpp @@ -98,7 +98,7 @@ int gprs_rlcmac_poll_timeout(struct gprs_rlcmac_tbf *tbf) } tbf->ul_ack_state = GPRS_RLCMAC_UL_ACK_NONE; debug_diagram(tbf->diag, "timeout UL-ACK"); - if (tbf->state == GPRS_RLCMAC_FINISHED) { + if (tbf->state_is(GPRS_RLCMAC_FINISHED)) { struct gprs_rlcmac_bts *bts = gprs_rlcmac_bts; tbf->dir.ul.n3103++; @@ -687,7 +687,7 @@ static int gprs_rlcmac_assemble_llc(struct gprs_rlcmac_tbf *tbf, uint8_t *data, struct msgb *gprs_rlcmac_send_uplink_ack(struct gprs_rlcmac_tbf *tbf, uint32_t fn) { - int final = (tbf->state == GPRS_RLCMAC_FINISHED); + int final = (tbf->state_is(GPRS_RLCMAC_FINISHED)); struct msgb *msg; if (final) { @@ -899,7 +899,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts, } /* Check CV of last frame in buffer */ - if (tbf->state == GPRS_RLCMAC_FLOW /* still in flow state */ + if (tbf->state_is(GPRS_RLCMAC_FLOW) /* still in flow state */ && tbf->dir.ul.v_q == tbf->dir.ul.v_r) { /* if complete */ struct rlc_ul_header *last_rh = (struct rlc_ul_header *) tbf->rlc_block[(tbf->dir.ul.v_r - 1) & mod_sns_half]; @@ -917,7 +917,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts, /* If TLLI is included or if we received half of the window, we send * an ack/nack */ - if (rh->si || rh->ti || tbf->state == GPRS_RLCMAC_FINISHED + if (rh->si || rh->ti || tbf->state_is(GPRS_RLCMAC_FINISHED) || (tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) { if (rh->si) { LOGP(DRLCMACUL, LOGL_NOTICE, "- Scheduling Ack/Nack, " @@ -927,7 +927,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts, LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, " "because TLLI is included.\n"); } - if (tbf->state == GPRS_RLCMAC_FINISHED) { + if (tbf->state_is(GPRS_RLCMAC_FINISHED)) { LOGP(DRLCMACUL, LOGL_DEBUG, "- Scheduling Ack/Nack, " "because last block has CV==0.\n"); } @@ -942,7 +942,7 @@ int gprs_rlcmac_rcv_data_block_acknowledged(uint8_t trx, uint8_t ts, debug_diagram(tbf->diag, "sched UL-ACK stall"); if (rh->ti) debug_diagram(tbf->diag, "sched UL-ACK TLLI"); - if (tbf->state == GPRS_RLCMAC_FINISHED) + if (tbf->state_is(GPRS_RLCMAC_FINISHED)) debug_diagram(tbf->diag, "sched UL-ACK CV==0"); if ((tbf->dir.ul.rx_counter % SEND_ACK_AFTER_FRAMES) == 0) debug_diagram(tbf->diag, "sched UL-ACK n=%d", @@ -1200,11 +1200,11 @@ do_resend: /* if the window has stalled, or transfer is complete, * send an unacknowledged block */ - if (tbf->state == GPRS_RLCMAC_FINISHED + if (tbf->state_is(GPRS_RLCMAC_FINISHED) || ((tbf->dir.dl.v_s - tbf->dir.dl.v_a) & mod_sns) == tbf->ws) { int resend = 0; - if (tbf->state == GPRS_RLCMAC_FINISHED) + if (tbf->state_is(GPRS_RLCMAC_FINISHED)) LOGP(DRLCMACDL, LOGL_DEBUG, "- Restarting at BSN %d, " "because all blocks have been transmitted.\n", tbf->dir.dl.v_a); @@ -1568,7 +1568,7 @@ int gprs_rlcmac_downlink_ack(struct gprs_rlcmac_tbf *tbf, uint8_t final, "X=Resend-Unacked\n", tbf->dir.dl.v_a, show_v_b, (tbf->dir.dl.v_s - 1) & mod_sns); - if (tbf->state == GPRS_RLCMAC_FINISHED + if (tbf->state_is(GPRS_RLCMAC_FINISHED) && tbf->dir.dl.v_s == tbf->dir.dl.v_a) { LOGP(DRLCMACDL, LOGL_NOTICE, "Received acknowledge of " "all blocks, but without final ack " diff --git a/src/gprs_rlcmac_sched.cpp b/src/gprs_rlcmac_sched.cpp index f3edaac..476d781 100644 --- a/src/gprs_rlcmac_sched.cpp +++ b/src/gprs_rlcmac_sched.cpp @@ -103,7 +103,7 @@ uint8_t sched_select_uplink(uint8_t trx, uint8_t ts, uint32_t fn, /* we don't need to give resources in FINISHED state, * because we have received all blocks and only poll * for packet control ack. */ - if (tbf->state != GPRS_RLCMAC_FLOW) + if (tbf->state_is_not(GPRS_RLCMAC_FLOW)) continue; /* use this USF */ @@ -182,8 +182,8 @@ struct msgb *sched_select_downlink(uint8_t trx, uint8_t ts, uint32_t fn, if (tbf->direction != GPRS_RLCMAC_DL_TBF) continue; /* no DL resources needed, go next */ - if (tbf->state != GPRS_RLCMAC_FLOW - && tbf->state != GPRS_RLCMAC_FINISHED) + if (tbf->state_is_not(GPRS_RLCMAC_FLOW) + && tbf->state_is_not(GPRS_RLCMAC_FINISHED)) continue; /* waiting for CCCH IMM.ASS confirm */ diff --git a/src/tbf.cpp b/src/tbf.cpp index 918520c..547612f 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -59,7 +59,7 @@ static int tbf_append_data(struct gprs_rlcmac_tbf *tbf, const uint8_t *data, const uint16_t len) { LOGP(DRLCMAC, LOGL_INFO, "TBF: APPEND TFI: %u TLLI: 0x%08x\n", tbf->tfi, tbf->tlli); - if (tbf->state == GPRS_RLCMAC_WAIT_RELEASE) { + if (tbf->state_is(GPRS_RLCMAC_WAIT_RELEASE)) { LOGP(DRLCMAC, LOGL_DEBUG, "TBF in WAIT RELEASE state " "(T3193), so reuse TBF\n"); memcpy(tbf->llc_frame, data, len); @@ -357,7 +357,7 @@ void tbf_new_state(struct gprs_rlcmac_tbf *tbf, LOGP(DRLCMAC, LOGL_DEBUG, "%s TBF=%d changes state from %s to %s\n", (tbf->direction == GPRS_RLCMAC_UL_TBF) ? "UL" : "DL", tbf->tfi, tbf_state_name[tbf->state], tbf_state_name[state]); - tbf->state = state; + tbf->set_state(state); } void tbf_timer_start(struct gprs_rlcmac_tbf *tbf, unsigned int T, @@ -409,7 +409,7 @@ struct gprs_rlcmac_tbf *tbf_by_tfi(struct gprs_rlcmac_bts *bts, if (!tbf) return NULL; - if (tbf->state != GPRS_RLCMAC_RELEASING) + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING)) return tbf; return NULL; @@ -422,13 +422,13 @@ struct gprs_rlcmac_tbf *tbf_by_tlli(uint32_t tlli, struct gprs_rlcmac_tbf *tbf; if (dir == GPRS_RLCMAC_UL_TBF) { llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->tlli == tlli && tbf->tlli_valid) return tbf; } } else { llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->tlli == tlli) return tbf; } @@ -443,14 +443,14 @@ struct gprs_rlcmac_tbf *tbf_by_poll_fn(uint32_t fn, uint8_t trx, uint8_t ts) /* only one TBF can poll on specific TS/FN, because scheduler can only * schedule one downlink control block (with polling) at a FN per TS */ llist_for_each_entry(tbf, &gprs_rlcmac_ul_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx == trx && tbf->control_ts == ts) return tbf; } llist_for_each_entry(tbf, &gprs_rlcmac_dl_tbfs, list) { - if (tbf->state != GPRS_RLCMAC_RELEASING + if (tbf->state_is_not(GPRS_RLCMAC_RELEASING) && tbf->poll_state == GPRS_RLCMAC_POLL_SCHED && tbf->poll_fn == fn && tbf->trx == trx && tbf->control_ts == ts) @@ -561,7 +561,7 @@ void tbf_timer_cb(void *_tbf) #endif case 0: /* assignment */ if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_PACCH))) { - if (tbf->state == GPRS_RLCMAC_ASSIGN) { + if (tbf->state_is(GPRS_RLCMAC_ASSIGN)) { LOGP(DRLCMAC, LOGL_NOTICE, "Releasing due to " "PACCH assignment timeout.\n"); tbf_free(tbf); @@ -572,7 +572,7 @@ void tbf_timer_cb(void *_tbf) if ((tbf->state_flags & (1 << GPRS_RLCMAC_FLAG_CCCH))) { /* change state to FLOW, so scheduler will start transmission */ tbf->dir.dl.wait_confirm = 0; - if (tbf->state == GPRS_RLCMAC_ASSIGN) { + if (tbf->state_is(GPRS_RLCMAC_ASSIGN)) { tbf_new_state(tbf, GPRS_RLCMAC_FLOW); tbf_assign_control_ts(tbf); } else diff --git a/src/tbf.h b/src/tbf.h index d2aead2..84d558e 100644 --- a/src/tbf.h +++ b/src/tbf.h @@ -91,10 +91,13 @@ struct gprs_rlcmac_tbf { static void free_all(struct gprs_rlcmac_trx *trx); static void free_all(struct gprs_rlcmac_pdch *pdch); + bool state_is(enum gprs_rlcmac_tbf_state rhs) const; + bool state_is_not(enum gprs_rlcmac_tbf_state rhs) const; + void set_state(enum gprs_rlcmac_tbf_state new_state); + int rlcmac_diag(); struct llist_head list; - enum gprs_rlcmac_tbf_state state; uint32_t state_flags; enum gprs_rlcmac_tbf_direction direction; uint8_t tfi; @@ -187,6 +190,10 @@ struct gprs_rlcmac_tbf { int diag; /* number where TBF is presented in diagram */ int diag_new; /* used to format output of new TBF */ #endif + + /* these should become protected but only after gprs_rlcmac_data.c + * stops to iterate over all tbf in its current form */ + enum gprs_rlcmac_tbf_state state; }; @@ -232,3 +239,18 @@ void tbf_timer_stop(struct gprs_rlcmac_tbf *tbf); void tbf_timer_cb(void *_tbf); + +inline bool gprs_rlcmac_tbf::state_is(enum gprs_rlcmac_tbf_state rhs) const +{ + return state == rhs; +} + +inline bool gprs_rlcmac_tbf::state_is_not(enum gprs_rlcmac_tbf_state rhs) const +{ + return state != rhs; +} + +inline void gprs_rlcmac_tbf::set_state(enum gprs_rlcmac_tbf_state new_state) +{ + state = new_state; +} -- 1.8.4.rc3 From hfreyther at sysmocom.de Sun Oct 20 14:35:42 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sun, 20 Oct 2013 16:35:42 +0200 Subject: Status on re-factorings Message-ID: <20131020143542.GA26968@xiaoyu.lan> Hi all, I have continued with my refactorings and mostly done: * Remove global state (e.g. the global lists for ta, sba, tbf, bts * Add back-pointers to tbf, trx, pdch which will allow to kill methods that take trx, ts as parameters. * Started to use C++ classes and functions. * Stop poking of internals from other classes areas (gprs_rlcmac_data is still in front of me and the most hairy part). I will probably need to spend another 40h on this code to finally have structure in it. Once this is done I will add counters and rate counters, improve the VTY inspection... and then I can search for the actual defects we are experiencing. While doing the refactorings I noticed that both pcu_l1_if.cpp and sysmo_sock.cpp have different ways to reset the BTS/PCU state. Both of them have different issues and are both incomplete. It is the perfect example where structure would have saved timed and made the code more reliable at the same time. I am going to work on gprs_rlcmac_data.cpp and while my refactorings so far where low risk.. the risk will increase when touching and structuring the above, e.g. it is hard to judge if the difference in the code-clones is on purpose or actually a bug. There will be only one way to find it out though. I am afraid that I have 52 commits compares to master and I am only half way done. Review and changing directions will be quite difficult at this point in time. holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From andreas at eversberg.eu Mon Oct 21 07:00:57 2013 From: andreas at eversberg.eu (Andreas Eversberg) Date: Mon, 21 Oct 2013 09:00:57 +0200 Subject: Status on re-factorings In-Reply-To: <20131020143542.GA26968@xiaoyu.lan> References: <20131020143542.GA26968@xiaoyu.lan> Message-ID: <5264D129.2060603@eversberg.eu> Holger Hans Peter Freyther wrote: > I am going to work on gprs_rlcmac_data.cpp and while my refactorings > so far where low risk.. the risk will increase when touching and > structuring the above, e.g. it is hard to judge if the difference in > the code-clones is on purpose or actually a bug. There will be only > one way to find it out though. dear holger, the TBF assignment process, the time slot allocation algorithm and the RLC/MAC data transfer were the most complicated parts of the PCU for me. the data transfer seems to be critical, but breaking things there might be easy to find out. in most cases it just doesn't work anymore. once you have cleaned up the data transfer part, i will test all your changes (at good coverage and at border of coverage) and review the debug output. regards, andreas From hfreyther at sysmocom.de Sun Oct 27 11:12:42 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sun, 27 Oct 2013 12:12:42 +0100 Subject: Dropping LLC frames due the TBF destruction Message-ID: <20131027111242.GN6295@xiaoyu.lan> Hi, my clean-ups are not done but there is a basic structure now that can be refined. I started to add statistics to the BTS (and then will add statistics per tbf but they are short lived so one would need to be quick to see them). E.g. in tbf_free we are freeing still pending llc_frames and I assume that these are related to the "Killing pending DL TBF" and others. I am wondering why: * there is no indication to the SGSN for dropped frames/octets? * can't the DL-TBF be re-associated/updated after the assignment is done again? holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From hfreyther at sysmocom.de Sun Oct 27 12:33:13 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Sun, 27 Oct 2013 13:33:13 +0100 Subject: Losing ACKs due TLLI changes? Message-ID: <20131027123313.GO6295@xiaoyu.lan> Hi, I got this log from the pcu while using my E71 (the only sub in this network). <0007> gprs_rlcmac_meas.cpp:103 UL RSSI of TLLI=0x88661bc6: -67 dBm <0002> bts.cpp:945 Got ACK, but UL TBF is gone TLLI=0xe512eba3 <0007> gprs_rlcmac_meas.cpp:158 DL packet loss of IMSI=274080000004765 / TLLI=0xe512eba3: 0% <0002> tbf.cpp:668 TBF TFI=0 TLLI=0x88661bc6 T3169 timeout during transsmission <0002> tbf.cpp:690 - Assignment was on PACCH <0002> tbf.cpp:694 - No uplink data received yet So there is an ACK for TLLI=0xe512eba3 but at the same time the tlli 0x88661bc6 is timing out. PCU->SGSN TLLI=0x88661bc6 Attach Request SGSN->PCU TLLI=0x88661bc6 Attach Accept (new P-TMSI) PCU->SGSN TLLI=0xe512eba3 Attach Complete (new TLLI) (6s later) Now the question is how the PCU should behave. I think the MS is allowed to change the TLLI (after a P-TMSI assignment) after the contention resolution is completed. From my reading there is no content resolution on the UL. My E71 appears to run into a timeout and then issue a RACH request to send the Attach Complete. I think I have seen other equipment failing to transmit the Attach Complete at all. I think for the SGSN -> PCU side we should generally look things up by IMSI (there is already a warning in the code), for the MS->PCU side. I think we should store the old and new TLLI (and then put new_tlli into tlli once the new one is being used). comments? holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From Ivan.Kluchnikov at fairwaves.ru Mon Oct 28 11:16:34 2013 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Mon, 28 Oct 2013 15:16:34 +0400 Subject: Status on re-factorings In-Reply-To: <20131020143542.GA26968@xiaoyu.lan> References: <20131020143542.GA26968@xiaoyu.lan> Message-ID: Hi Holger, I have merged all patches, which you sent to mailing list previously and also looked through the code of zecke/features/clean-up branch. You have done really great work and as I think all structure changes have the right direction. As you mentioned, refactoring of some parts of the code is risky, but when we use right code structure, it is more easy to find problems. Also I think that after the end of refactoring, we should implement set of tests, which will help us to find bugs and problems. I have one question about C/C++ using in osmo-pcu project. What I see, that now the code migrates to C++, but previously we mainly used C. As the result now osmo-pcu code is C and C++ mix, but I think that we should use only one as basic. I personally prefer to use C++ in osmo-pcu. What do you think about it? Do you plan to migrate the most parts of the code to C++? 2013/10/20 Holger Hans Peter Freyther : > Hi all, > > I have continued with my refactorings and mostly done: > > * Remove global state (e.g. the global lists for ta, sba, tbf, bts > * Add back-pointers to tbf, trx, pdch which will allow to kill methods > that take trx, ts as parameters. > * Started to use C++ classes and functions. > * Stop poking of internals from other classes areas (gprs_rlcmac_data > is still in front of me and the most hairy part). > > I will probably need to spend another 40h on this code to finally > have structure in it. Once this is done I will add counters and > rate counters, improve the VTY inspection... and then I can search > for the actual defects we are experiencing. > > While doing the refactorings I noticed that both pcu_l1_if.cpp and > sysmo_sock.cpp have different ways to reset the BTS/PCU state. Both > of them have different issues and are both incomplete. It is the > perfect example where structure would have saved timed and made > the code more reliable at the same time. > > I am going to work on gprs_rlcmac_data.cpp and while my refactorings > so far where low risk.. the risk will increase when touching and > structuring the above, e.g. it is hard to judge if the difference in > the code-clones is on purpose or actually a bug. There will be only > one way to find it out though. > > I am afraid that I have 52 commits compares to master and I am only > half way done. Review and changing directions will be quite difficult > at this point in time. > > holger > > > -- > - Holger Freyther http://www.sysmocom.de/ > ======================================================================= > * sysmocom - systems for mobile communications GmbH > * Schivelbeiner Str. 5 > * 10439 Berlin, Germany > * Sitz / Registered office: Berlin, HRB 134158 B > * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte > > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From Ivan.Kluchnikov at fairwaves.ru Mon Oct 28 14:17:50 2013 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Mon, 28 Oct 2013 18:17:50 +0400 Subject: Losing ACKs due TLLI changes? In-Reply-To: <20131027123313.GO6295@xiaoyu.lan> References: <20131027123313.GO6295@xiaoyu.lan> Message-ID: Hi Holger, Can you send full pcu tbf debug log for this attach procedure? I want to understand, in which place of TBF MS starts use new TLLI. What do you mean by "no content resolution on the UL"? As I know, there are content resolution on network side and on MS side. The contention resolution at one phase access is successfully completed on the MS side when the mobile station receives a PACKET UPLINK ACK/NACK. The contention resolution at two phase access is completed at MS when it receives the second uplink assignment message with its TLLI included. Also I can't understand why we should use IMSI in pcu? Why it is not enough to use TLLI? 2013/10/27 Holger Hans Peter Freyther : > Hi, > > I got this log from the pcu while using my E71 (the only sub in this > network). > > <0007> gprs_rlcmac_meas.cpp:103 UL RSSI of TLLI=0x88661bc6: -67 dBm > <0002> bts.cpp:945 Got ACK, but UL TBF is gone TLLI=0xe512eba3 > <0007> gprs_rlcmac_meas.cpp:158 DL packet loss of IMSI=274080000004765 / TLLI=0xe512eba3: 0% > <0002> tbf.cpp:668 TBF TFI=0 TLLI=0x88661bc6 T3169 timeout during transsmission > <0002> tbf.cpp:690 - Assignment was on PACCH > <0002> tbf.cpp:694 - No uplink data received yet > > So there is an ACK for TLLI=0xe512eba3 but at the same time the tlli > 0x88661bc6 is timing out. > > PCU->SGSN TLLI=0x88661bc6 Attach Request > SGSN->PCU TLLI=0x88661bc6 Attach Accept (new P-TMSI) > PCU->SGSN TLLI=0xe512eba3 Attach Complete (new TLLI) (6s later) > > Now the question is how the PCU should behave. I think the MS is > allowed to change the TLLI (after a P-TMSI assignment) after the > contention resolution is completed. From my reading there is no content > resolution on the UL. My E71 appears to run into a timeout and then > issue a RACH request to send the Attach Complete. I think I have > seen other equipment failing to transmit the Attach Complete at > all. > > > I think for the SGSN -> PCU side we should generally look things up > by IMSI (there is already a warning in the code), for the MS->PCU > side. I think we should store the old and new TLLI (and then put > new_tlli into tlli once the new one is being used). > > comments? > holger > > > -- > - Holger Freyther http://www.sysmocom.de/ > ======================================================================= > * sysmocom - systems for mobile communications GmbH > * Schivelbeiner Str. 5 > * 10439 Berlin, Germany > * Sitz / Registered office: Berlin, HRB 134158 B > * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte > > -- Regards, Ivan Kluchnikov. http://fairwaves.ru From hfreyther at sysmocom.de Mon Oct 28 15:23:24 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Mon, 28 Oct 2013 16:23:24 +0100 Subject: Losing ACKs due TLLI changes? In-Reply-To: References: <20131027123313.GO6295@xiaoyu.lan> Message-ID: <20131028152324.GI15067@xiaoyu.lan> On Mon, Oct 28, 2013 at 06:17:50PM +0400, Ivan Kluchnikov wrote: > Hi Holger, Hi, > > Can you send full pcu tbf debug log for this attach procedure? > I want to understand, in which place of TBF MS starts use new TLLI. > What do you mean by "no content resolution on the UL"? s/content resolution/contention resolution/. Sorry. I don't have a log file but with the routing area update, the SGSN may assign a new P-TMSI and if a new P-TMSI was assigned with the "Accept" message, a "Complete" message needs to be generated by the MS. This message can/should already contain the new TLLI (which is derived from the P-TMSI). > Also I can't understand why we should use IMSI in pcu? > Why it is not enough to use TLLI? The TLLI is either random (I have not seen this), foreign or local. In the last two cases it is derived from the P-TMSI. The P-TMSI can change (e.g. at routing area update). -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From hfreyther at sysmocom.de Mon Oct 28 15:39:52 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Mon, 28 Oct 2013 16:39:52 +0100 Subject: Status on re-factorings In-Reply-To: References: <20131020143542.GA26968@xiaoyu.lan> Message-ID: <20131028153952.GK15067@xiaoyu.lan> On Mon, Oct 28, 2013 at 03:16:34PM +0400, Ivan Kluchnikov wrote: > As you mentioned, refactoring of some parts of the code is risky, but > when we use right code structure, it is more easy to find problems. > Also I think that after the end of refactoring, we should implement > set of tests, which will help us to find bugs and problems. with the manual toying around my E71 can open webpages. By cheer luck I spotted a "bts->bts = bts->bts" (which should have been a (tbf->bts = bts). But so far it is okay. The main issue is that I have now around 90 commits. It will be not nice to review and changing direction will be difficult as well. But e.g. my renaming of tfi/tlli in the code has lead me to create a tbf_name() function that I use for logging. And I found places that could have silently changed the tlli. My selfish proposal would be to merge my branch to master and continue the clean-up there once some people having done smoke "testing" on it. > I have one question about C/C++ using in osmo-pcu project. What I see, > that now the code migrates to C++, but previously we mainly used C. As > the result now osmo-pcu code is C and C++ mix, but I think that we > should use only one as basic. > I personally prefer to use C++ in osmo-pcu. > What do you think about it? > Do you plan to migrate the most parts of the code to C++? yes, to a very tiny subject of C++. E.g. I don't want to use stl and maybe only virtual functions when creating a GPRS TBF and a EGPRS TBF. -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From Ivan.Kluchnikov at fairwaves.ru Mon Oct 28 18:02:45 2013 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Mon, 28 Oct 2013 22:02:45 +0400 Subject: Losing ACKs due TLLI changes? In-Reply-To: <20131028152324.GI15067@xiaoyu.lan> References: <20131027123313.GO6295@xiaoyu.lan> <20131028152324.GI15067@xiaoyu.lan> Message-ID: 2013/10/28 Holger Hans Peter Freyther : > I don't have a log file but with the routing area update, the > SGSN may assign a new P-TMSI and if a new P-TMSI was assigned > with the "Accept" message, a "Complete" message needs to be > generated by the MS. This message can/should already contain > the new TLLI (which is derived from the P-TMSI). Ok, I will try to reproduce it. -- Regards, Ivan Kluchnikov. http://fairwaves.ru From Ivan.Kluchnikov at fairwaves.ru Mon Oct 28 18:21:47 2013 From: Ivan.Kluchnikov at fairwaves.ru (Ivan Kluchnikov) Date: Mon, 28 Oct 2013 22:21:47 +0400 Subject: Status on re-factorings In-Reply-To: <20131028153952.GK15067@xiaoyu.lan> References: <20131020143542.GA26968@xiaoyu.lan> <20131028153952.GK15067@xiaoyu.lan> Message-ID: 2013/10/28 Holger Hans Peter Freyther : > The main issue is that I have now around 90 commits. It will be > not nice to review and changing direction will be difficult as well. > > But e.g. my renaming of tfi/tlli in the code has lead me to create > a tbf_name() function that I use for logging. And I found places > that could have silently changed the tlli. > > My selfish proposal would be to merge my branch to master and > continue the clean-up there once some people having done smoke > "testing" on it. Ok, let me try to test new code, after that I think we can merge it to master to speed up code debugging and testing. -- Regards, Ivan Kluchnikov. http://fairwaves.ru From hfreyther at sysmocom.de Mon Oct 28 18:28:17 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Mon, 28 Oct 2013 19:28:17 +0100 Subject: Losing ACKs due TLLI changes? In-Reply-To: References: <20131027123313.GO6295@xiaoyu.lan> <20131028152324.GI15067@xiaoyu.lan> Message-ID: <20131028182817.GM15067@xiaoyu.lan> On Mon, Oct 28, 2013 at 10:02:45PM +0400, Ivan Kluchnikov wrote: > 2013/10/28 Holger Hans Peter Freyther : > Ok, I will try to reproduce it. It should happen on every attach and routing area update. E.g. if you have periodic updating enabled in the NITB you should see this behavior (bug) every time. I intend to look at it during wednesday. My current trial will be to change code in here[1]. When the TLLI is changing try to find other TBFs (e.g. if we ever support multiple tbf assignment) and update the TLLI as well. I would also say that if the tlli is changed, it is valid. So the separate "mark valid" function is probably not needed. But I need to modify the code in bts.cpp for that. holger [1] http://git.osmocom.org/osmo-pcu/tree/src/tbf.cpp?h=zecke/features/clean-up#n1620 -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From vrolbin at gmail.com Tue Oct 29 10:35:19 2013 From: vrolbin at gmail.com (Vladimir Rolbin) Date: Tue, 29 Oct 2013 12:35:19 +0200 Subject: Losing ACKs due TLLI changes? In-Reply-To: <20131028152324.GI15067@xiaoyu.lan> References: <20131027123313.GO6295@xiaoyu.lan> <20131028152324.GI15067@xiaoyu.lan> Message-ID: Hi, Let me participate in the discussion to improve my understanding. If I see well the new TLLI (after changing by Attach Accept for example) may be obtained from the first RLC data block belonging to the UL TBF allocated for Attach Complete transfer (in the case of resource request on RACH) or from still existing DL TBF context (in the case the channel request is included in PACCH downlink packet ack/nack) where it has to be updated on P-TMSI change. For paging group choosing in the later stage (after attaching procedure) it's enough that IMSI is known in SGSN and delivered to pcu with the downlink packets. Regards, Vladimir. On Mon, Oct 28, 2013 at 5:23 PM, Holger Hans Peter Freyther < hfreyther at sysmocom.de> wrote: > On Mon, Oct 28, 2013 at 06:17:50PM +0400, Ivan Kluchnikov wrote: > > Hi Holger, > > Hi, > > > > > Can you send full pcu tbf debug log for this attach procedure? > > I want to understand, in which place of TBF MS starts use new TLLI. > > What do you mean by "no content resolution on the UL"? > > s/content resolution/contention resolution/. Sorry. > > I don't have a log file but with the routing area update, the > SGSN may assign a new P-TMSI and if a new P-TMSI was assigned > with the "Accept" message, a "Complete" message needs to be > generated by the MS. This message can/should already contain > the new TLLI (which is derived from the P-TMSI). > > > > > Also I can't understand why we should use IMSI in pcu? > > Why it is not enough to use TLLI? > > The TLLI is either random (I have not seen this), foreign > or local. In the last two cases it is derived from the P-TMSI. > The P-TMSI can change (e.g. at routing area update). > > -- > - Holger Freyther http://www.sysmocom.de/ > ======================================================================= > * sysmocom - systems for mobile communications GmbH > * Schivelbeiner Str. 5 > * 10439 Berlin, Germany > * Sitz / Registered office: Berlin, HRB 134158 B > * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hfreyther at sysmocom.de Wed Oct 30 11:17:31 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Wed, 30 Oct 2013 12:17:31 +0100 Subject: Losing ACKs due TLLI changes? In-Reply-To: <20131027123313.GO6295@xiaoyu.lan> References: <20131027123313.GO6295@xiaoyu.lan> Message-ID: <20131030111731.GA23718@xiaoyu.lan> On Sun, Oct 27, 2013 at 01:33:13PM +0100, Holger Hans Peter Freyther wrote: Hi, > <0007> gprs_rlcmac_meas.cpp:103 UL RSSI of TLLI=0x88661bc6: -67 dBm > <0002> bts.cpp:945 Got ACK, but UL TBF is gone TLLI=0xe512eba3 > <0007> gprs_rlcmac_meas.cpp:158 DL packet loss of IMSI=274080000004765 / TLLI=0xe512eba3: 0% > <0002> tbf.cpp:668 TBF TFI=0 TLLI=0x88661bc6 T3169 timeout during transsmission > <0002> tbf.cpp:690 - Assignment was on PACCH > <0002> tbf.cpp:694 - No uplink data received yet this is from a routing area update (with some printf debugging): TBF(TFI=0 TLLI=0xb68154e6 DIR=DL) TLLLI changed...... 0xb68154e6->0xc782d1de <0002> tbf.cpp:1626 TBF(TFI=0 TLLI=0xb68154e6 DIR=DL) changing tlli to TLLI=0xc782d1de <0002> bts.cpp:941 Got ACK, but UL TBF is gone TLLI=0xc782d1de <0007> gprs_rlcmac_meas.cpp:158 DL packet loss of IMSI=274080000004765 / TLLI=0xc782d1de: 0% <0002> tbf.cpp:664 TBF(TFI=0 TLLI=0xb68154e6 DIR=UL) T3169 timeout during transsmission <0002> tbf.cpp:686 - Assignment was on PACCH <0002> tbf.cpp:690 - No uplink data received yet So the DL TLLI has been changed and then we get an ACK for a UL tbf with the new TLLI and can't find it. And run into a timeout. I have applied this change: diff --git a/src/tbf.cpp b/src/tbf.cpp index fac5aaf..19bb83c 100644 --- a/src/tbf.cpp +++ b/src/tbf.cpp @@ -1618,6 +1618,17 @@ void gprs_rlcmac_tbf::update_tlli(uint32_t tlli) if (tlli == m_tlli) return; + printf("%s TLLLI changed...... 0x%08x->0x%08x\n", + tbf_name(this), m_tlli, tlli); + + if (direction == GPRS_RLCMAC_DL_TBF) { + gprs_rlcmac_tbf *ul_tbf; + ul_tbf = bts->tbf_by_tlli(m_tlli, GPRS_RLCMAC_UL_TBF); + + if (ul_tbf) + ul_tbf->m_tlli = tlli; + } + #warning "TODO.. find the DL/UL opposite and update the TLLI too" LOGP(DRLCMAC, LOGL_NOTICE, "%s changing tlli to TLLI=0x%08x\n", tbf_name(this), tlli); and now the "Attach Complete" comes immediately after the Attach Accept. I will push something like this but we really need a better way to link the DL/UL TBFs together. holger -- - Holger Freyther http://www.sysmocom.de/ ======================================================================= * sysmocom - systems for mobile communications GmbH * Schivelbeiner Str. 5 * 10439 Berlin, Germany * Sitz / Registered office: Berlin, HRB 134158 B * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte From vrolbin at gmail.com Wed Oct 30 16:26:57 2013 From: vrolbin at gmail.com (Vladimir Rolbin) Date: Wed, 30 Oct 2013 18:26:57 +0200 Subject: Fwd: Losing ACKs due TLLI changes? In-Reply-To: References: <20131027123313.GO6295@xiaoyu.lan> <20131030111731.GA23718@xiaoyu.lan> Message-ID: Hi, I don't see any print connected to the Uplink TBF request for "Attach accept" (by MS). At this moment the TLLI has been already updated but UL TBF still does not exist (what bts->tbf_by_tlli(m_tlli, GPRS_RLCMAC_UL_TBF) returns?). Corresponding to TS 04.60, 11.2.29 Packet Uplink Assignment possibly may use DL TFI to address the MS in place of TLLI (we still don't know if it's accepted or not by MS). Also the uplink FN may be used to find corresponding UL TBF context (according to Packet Uplink Assignment RRBP field) for UL Packet Control Ack which contains relevant TLLI. So is it really necessary to link UL and DL TBFs in the case? ... Regards, Vladimir Rolbin On Wed, Oct 30, 2013 at 1:17 PM, Holger Hans Peter Freyther < hfreyther at sysmocom.de> wrote: > On Sun, Oct 27, 2013 at 01:33:13PM +0100, Holger Hans Peter Freyther wrote: > > Hi, > > > > <0007> gprs_rlcmac_meas.cpp:103 UL RSSI of TLLI=0x88661bc6: -67 dBm > > <0002> bts.cpp:945 Got ACK, but UL TBF is gone TLLI=0xe512eba3 > > <0007> gprs_rlcmac_meas.cpp:158 DL packet loss of IMSI=274080000004765 / > TLLI=0xe512eba3: 0% > > <0002> tbf.cpp:668 TBF TFI=0 TLLI=0x88661bc6 T3169 timeout during > transsmission > > <0002> tbf.cpp:690 - Assignment was on PACCH > > <0002> tbf.cpp:694 - No uplink data received yet > > this is from a routing area update (with some printf debugging): > > > TBF(TFI=0 TLLI=0xb68154e6 DIR=DL) TLLLI changed...... > 0xb68154e6->0xc782d1de > <0002> tbf.cpp:1626 TBF(TFI=0 TLLI=0xb68154e6 DIR=DL) changing tlli to > TLLI=0xc782d1de > <0002> bts.cpp:941 Got ACK, but UL TBF is gone TLLI=0xc782d1de > <0007> gprs_rlcmac_meas.cpp:158 DL packet loss of IMSI=274080000004765 / > TLLI=0xc782d1de: 0% > <0002> tbf.cpp:664 TBF(TFI=0 TLLI=0xb68154e6 DIR=UL) T3169 timeout during > transsmission > <0002> tbf.cpp:686 - Assignment was on PACCH > <0002> tbf.cpp:690 - No uplink data received yet > > So the DL TLLI has been changed and then we get an ACK for a UL tbf > with the new TLLI and can't find it. And run into a timeout. > > > I have applied this change: > > diff --git a/src/tbf.cpp b/src/tbf.cpp > index fac5aaf..19bb83c 100644 > --- a/src/tbf.cpp > +++ b/src/tbf.cpp > @@ -1618,6 +1618,17 @@ void gprs_rlcmac_tbf::update_tlli(uint32_t tlli) > if (tlli == m_tlli) > return; > > + printf("%s TLLLI changed...... 0x%08x->0x%08x\n", > + tbf_name(this), m_tlli, tlli); > + > + if (direction == GPRS_RLCMAC_DL_TBF) { > + gprs_rlcmac_tbf *ul_tbf; > + ul_tbf = bts->tbf_by_tlli(m_tlli, GPRS_RLCMAC_UL_TBF); > + > + if (ul_tbf) > + ul_tbf->m_tlli = tlli; > + } > + > #warning "TODO.. find the DL/UL opposite and update the TLLI too" > LOGP(DRLCMAC, LOGL_NOTICE, "%s changing tlli to TLLI=0x%08x\n", > tbf_name(this), tlli); > > > and now the "Attach Complete" comes immediately after the Attach Accept. > I will push something like this but we really need a better way to link > the DL/UL TBFs together. > > > holger > > > -- > - Holger Freyther http://www.sysmocom.de/ > ======================================================================= > * sysmocom - systems for mobile communications GmbH > * Schivelbeiner Str. 5 > * 10439 Berlin, Germany > * Sitz / Registered office: Berlin, HRB 134158 B > * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte > > > -------------- next part -------------- An HTML attachment was scrubbed... URL: From hfreyther at sysmocom.de Wed Oct 30 17:18:00 2013 From: hfreyther at sysmocom.de (Holger Hans Peter Freyther) Date: Wed, 30 Oct 2013 18:18:00 +0100 Subject: Fwd: Losing ACKs due TLLI changes? In-Reply-To: References: <20131027123313.GO6295@xiaoyu.lan> <20131030111731.GA23718@xiaoyu.lan> Message-ID: <20131030171800.GG8675@xiaoyu.lan> On Wed, Oct 30, 2013 at 06:26:57PM +0200, Vladimir Rolbin wrote: > I don't see any print connected to the Uplink TBF request for "Attach > accept" (by MS). At this moment the TLLI has been already updated but UL > TBF still does not exist I don't understand that part? What happens here is that we poll for a PACKET CONTROL ACK. So we know the TBF based on the FN. And in this TBF we notice that the TLLI has changed (ACK is using the new TLLI that is derived from the P-TMSI). > (what bts->tbf_by_tlli(m_tlli, GPRS_RLCMAC_UL_TBF) returns?). Corresponding > to TS 04.60, 11.2.29 Packet Uplink Assignment possibly may use DL TFI to > address the MS in place of TLLI (we still don't know if it's accepted or > not by MS). Also the uplink FN may be used to find corresponding UL TBF > context (according to Packet Uplink Assignment RRBP field) for UL Packet > Control Ack which contains relevant TLLI. So is it really necessary to > link UL and DL TBFs in the case? ... From vrolbin at gmail.com Thu Oct 31 09:08:34 2013 From: vrolbin at gmail.com (Vladimir Rolbin) Date: Thu, 31 Oct 2013 11:08:34 +0200 Subject: Fwd: Losing ACKs due TLLI changes? In-Reply-To: <20131030171800.GG8675@xiaoyu.lan> References: <20131027123313.GO6295@xiaoyu.lan> <20131030111731.GA23718@xiaoyu.lan> <20131030171800.GG8675@xiaoyu.lan> Message-ID: >I don't understand that part? What happens here is that we poll for >a PACKET CONTROL ACK. So we know the TBF based on the FN. Here is an example (You may open the messages in 3GPP message decoder), RRBP = 0, so UL FN = DL FN + 13. DL FN is known in gprs_rlcmac_rcv_rts_block: 1379410063.708403 3031788400: [ PCU -> BTS ] PACCH: TS 6 FN 1885970 FN52 34 CNTRL1 raw=(4f2856d9f9fce301a004880801052b2b2b2b2b2b2b2b2b) DL_PACKET_UPLINK_ASSIGNMENT 1379410063.828722 3064122224: [ BTS -> PCU ] PhDataInd TS:6 FN:1885983 FN52:47 CNTRL1 raw=(4006db3f3f9f2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b2b) UL_PACKET_CONTROL_ACKNOWLEDGEMENT >And in this >TBF we notice that the TLLI has changed (ACK is using the new TLLI >that is derived from the P-TMSI). Yep.. I guess so. >From an engineering point of view I think linking makes sense because: >* With multiple TBF assignment the tbf_by_tlli will return a list anyway. >* For the multiple RACH cases we could it probably handle it more >nicely. The simpler things the better they work. TBFs are the instances with short life. And with all respect to tlli the id that uniquely identifies the TBF is TFI. I think that independent TBF treatment is less complex. In the cases when the new TBF is created while older TBSs still exist for the MS the new TBF context simply inherit the critical data like TA.. Anyway it's only my opinion. >E.g. avoid this: ><0005> bts.cpp:1035 Got RACH from TLLI=0xcf7611f6 while TBF(TFI=0 TLLI=0xcf7611f6 DIR=DL) still exists. Killing pending DL TBF ><0002> bts.cpp:359 Got IMM.ASS confirm, but TLLI=cf7611f6 does not exit To my mind it's strange situation. If the DL flow still exists why the MS requests resources on RACH? On Wed, Oct 30, 2013 at 7:18 PM, Holger Hans Peter Freyther < hfreyther at sysmocom.de> wrote: > On Wed, Oct 30, 2013 at 06:26:57PM +0200, Vladimir Rolbin wrote: > > > I don't see any print connected to the Uplink TBF request for "Attach > > accept" (by MS). At this moment the TLLI has been already updated but UL > > TBF still does not exist > > I don't understand that part? What happens here is that we poll for > a PACKET CONTROL ACK. So we know the TBF based on the FN. And in this > TBF we notice that the TLLI has changed (ACK is using the new TLLI > that is derived from the P-TMSI). > > > > (what bts->tbf_by_tlli(m_tlli, GPRS_RLCMAC_UL_TBF) returns?). > Corresponding > > to TS 04.60, 11.2.29 Packet Uplink Assignment possibly may use DL TFI to > > address the MS in place of TLLI (we still don't know if it's accepted or > > not by MS). Also the uplink FN may be used to find corresponding UL TBF > > context (according to Packet Uplink Assignment RRBP field) for UL Packet > > Control Ack which contains relevant TLLI. So is it really necessary to > > link UL and DL TBFs in the case? ... > > From an engineering point of view I think linking makes sense because: > > * With multiple TBF assignment the tbf_by_tlli will return a list > anyway. > * For the multiple RACH cases we could it probably handle it more > nicely. > > > E.g. avoid this: > <0005> bts.cpp:1035 Got RACH from TLLI=0xcf7611f6 while TBF(TFI=0 > TLLI=0xcf7611f6 DIR=DL) still exists. Killing pending DL TBF > <0002> bts.cpp:359 Got IMM.ASS confirm, but TLLI=cf7611f6 does not exit > > > > -- > - Holger Freyther http://www.sysmocom.de/ > ======================================================================= > * sysmocom - systems for mobile communications GmbH > * Schivelbeiner Str. 5 > * 10439 Berlin, Germany > * Sitz / Registered office: Berlin, HRB 134158 B > * Geschaeftsfuehrer / Managing Directors: Holger Freyther, Harald Welte > > -------------- next part -------------- An HTML attachment was scrubbed... URL: