ms: Rewrite MS release lifecycle

This commit changes lots of stuff in the MS release lifecycle, but
there's no really good way to split this into patches which make sense,
since all the chaos is intensively entangled.

Get rid of the ms_callback complex mess, it is not needed at all.

Previous MS release was strange due to the existance of previous
ms_callback.idle concept and MS storage: the MS signalled when it went
idle (no TBFs attached) and waited for somebody outside to free it,
while then arming itself the release timer to release itself if it was
not released by whoever.

The new lifecycle follows an easier (expected) approach: Whenever all
TBFs become detached from the MS and it becomes idle (use_count becomes
0), then it frees its reserved resources (TFI, etc.) and either:
* frees itself immediatelly under certain conditions (release timeout
  configured = 0 or MS garbage with TLLI=GSM_RESERVED_TMSI)
* Arms release_timer and frees itself when it triggers.

If during release_timer the MS is required again (for instance because a
new TBF with TLLI/IMSI of the MS is observed), then a TBF is attached to
the MS and it is considered to become active again, hence the release_timer
is stopped.

OS#6002
Change-Id: Ibe5115bc15bb4d76026918adc1be79469c2f4839
This commit is contained in:
Pau Espin 2023-04-18 19:02:55 +02:00
parent df6684fe50
commit ac4d4a6d41
11 changed files with 354 additions and 551 deletions

View File

@ -242,7 +242,6 @@ static int bts_talloc_destructor(struct gprs_rlcmac_bts* bts)
{
struct GprsMs *ms;
while ((ms = llist_first_entry_or_null(&bts->ms_list, struct GprsMs, list))) {
ms_set_callback(ms, NULL);
ms_set_timeout(ms, 0);
bts_stat_item_dec(bts, STAT_MS_PRESENT);
talloc_free(ms);

View File

@ -61,7 +61,7 @@ static int64_t now_msec()
return (int64_t)(ts.tv_sec) * 1000 + ts.tv_nsec / 1000000;
}
static void ms_update_status(struct GprsMs *ms);
static void ms_becomes_idle(struct GprsMs *ms);
static int ms_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, const char *file, int line)
{
@ -90,36 +90,20 @@ static int ms_use_cb(struct osmo_use_count_entry *e, int32_t old_use_count, cons
if (e->count < 0)
return -ERANGE;
if (total == 0)
ms_update_status(ms);
if (total == 0) {
OSMO_ASSERT(ms_is_idle(ms));
ms_becomes_idle(ms);
}
return 0;
}
void gprs_default_cb_ms_idle(struct GprsMs *ms)
{
if (ms_is_idle(ms))
talloc_free(ms);
}
void gprs_default_cb_ms_active(struct GprsMs *ms)
{
/* do nothing */
}
static struct gpr_ms_callback gprs_default_cb = {
.ms_idle = gprs_default_cb_ms_idle,
.ms_active = gprs_default_cb_ms_active,
};
static void ms_release_timer_cb(void *data)
{
struct GprsMs *ms = (struct GprsMs *) data;
LOGPMS(ms, DRLCMAC, LOGL_INFO, "Release timer expired\n");
if (ms->timer.data) {
ms->timer.data = NULL;
ms_unref(ms, MS_USE_RELEASE_TIMER);
}
/* Finally free the MS after being idle for a while according to config */
talloc_free(ms);
}
static void ms_llc_timer_cb(void *_ms)
@ -149,14 +133,12 @@ struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts)
bts_stat_item_inc(bts, STAT_MS_PRESENT);
ms->bts = bts;
ms->cb = gprs_default_cb;
ms->tlli = GSM_RESERVED_TMSI;
ms->new_ul_tlli = GSM_RESERVED_TMSI;
ms->new_dl_tlli = GSM_RESERVED_TMSI;
ms->ta = GSM48_TA_INVALID;
ms->current_cs_ul = UNKNOWN;
ms->current_cs_dl = UNKNOWN;
ms->is_idle = true;
INIT_LLIST_HEAD(&ms->old_tbfs);
ms->use_count = (struct osmo_use_count){
@ -169,7 +151,7 @@ struct GprsMs *ms_alloc(struct gprs_rlcmac_bts *bts)
LOGP(DRLCMAC, LOGL_INFO, "Creating MS object\n");
ms->imsi[0] = '\0';
osmo_timer_setup(&ms->timer, ms_release_timer_cb, NULL);
osmo_timer_setup(&ms->timer, ms_release_timer_cb, ms);
llc_queue_init(&ms->llc_queue, ms);
memset(&ms->llc_timer, 0, sizeof(ms->llc_timer));
osmo_timer_setup(&ms->llc_timer, ms_llc_timer_cb, ms);
@ -232,69 +214,42 @@ static int ms_talloc_destructor(struct GprsMs *ms)
return 0;
}
void ms_set_callback(struct GprsMs *ms, struct gpr_ms_callback *cb)
/* MS has no attached TBFs anymore. */
static void ms_becomes_idle(struct GprsMs *ms)
{
if (cb)
ms->cb = *cb;
else
ms->cb = gprs_default_cb;
}
ms_set_reserved_slots(ms, NULL, 0, 0);
ms->first_common_ts = NULL;
static void ms_update_status(struct GprsMs *ms)
{
if (osmo_use_count_total(&ms->use_count) > 0)
return;
if (ms_is_idle(ms) && !ms->is_idle) {
ms->is_idle = true;
ms->cb.ms_idle(ms);
/* this can be deleted by now, do not access it */
return;
}
if (!ms_is_idle(ms) && ms->is_idle) {
ms->is_idle = false;
ms->cb.ms_active(ms);
}
}
static void ms_release_timer_start(struct GprsMs *ms)
{
/* Immediate free():
* Skip delaying free() through release timer if delay is configured to be 0.
* This is useful for synced freed during unit tests.
*/
if (ms->delay == 0)
if (ms->delay == 0) {
talloc_free(ms);
return;
}
/* Immediate free():
* Skip delaying free() through release timer if TMSI is not
* known, since those cannot really be reused.
*/
if (ms_tlli(ms) == GSM_RESERVED_TMSI)
if (ms_tlli(ms) == GSM_RESERVED_TMSI) {
talloc_free(ms);
return;
LOGPMS(ms, DRLCMAC, LOGL_DEBUG, "Schedule MS release in %u secs\n", ms->delay);
if (!ms->timer.data) {
ms_ref(ms, MS_USE_RELEASE_TIMER);
ms->timer.data = ms;
}
LOGPMS(ms, DRLCMAC, LOGL_DEBUG, "Schedule MS release in %u secs\n", ms->delay);
osmo_timer_schedule(&ms->timer, ms->delay, 0);
}
static void ms_release_timer_stop(struct GprsMs *ms)
static void ms_becomes_active(struct GprsMs *ms)
{
if (!ms->timer.data)
if (!osmo_timer_pending(&ms->timer))
return;
LOGPMS(ms, DRLCMAC, LOGL_DEBUG, "Cancel scheduled MS release\n");
osmo_timer_del(&ms->timer);
ms->timer.data = NULL;
ms_unref(ms, MS_USE_RELEASE_TIMER);
}
void ms_set_mode(struct GprsMs *ms, enum mcs_kind mode)
@ -374,32 +329,24 @@ static void ms_attach_ul_tbf(struct GprsMs *ms, struct gprs_rlcmac_ul_tbf *tbf)
{
LOGPMS(ms, DRLCMAC, LOGL_INFO, "Attaching UL TBF: %s\n", tbf_name((struct gprs_rlcmac_tbf *)tbf));
ms_ref(ms, __func__);
if (ms->ul_tbf)
llist_add_tail(tbf_ms_list(ul_tbf_as_tbf(ms->ul_tbf)), &ms->old_tbfs);
ms->ul_tbf = tbf;
ms_release_timer_stop(ms);
ms_unref(ms, __func__);
ms_ref(ms, MS_USE_TBF);
}
static void ms_attach_dl_tbf(struct GprsMs *ms, struct gprs_rlcmac_dl_tbf *tbf)
{
LOGPMS(ms, DRLCMAC, LOGL_INFO, "Attaching DL TBF: %s\n", tbf_name((struct gprs_rlcmac_tbf *)tbf));
ms_ref(ms, __func__);
if (ms->dl_tbf)
llist_add_tail(tbf_ms_list(dl_tbf_as_tbf(ms->dl_tbf)), &ms->old_tbfs);
ms->dl_tbf = tbf;
ms_release_timer_stop(ms);
ms_unref(ms, __func__);
ms_ref(ms, MS_USE_TBF);
}
void ms_attach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
@ -412,6 +359,8 @@ void ms_attach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
ms_attach_dl_tbf(ms, tbf_as_dl_tbf(tbf));
else
ms_attach_ul_tbf(ms, tbf_as_ul_tbf(tbf));
ms_becomes_active(ms);
}
void ms_detach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
@ -436,21 +385,35 @@ void ms_detach_tbf(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf)
llist_del(tbf_ms_list(tbf));
}
if (!ms->dl_tbf && !ms->ul_tbf) {
ms_set_reserved_slots(ms, NULL, 0, 0);
ms->first_common_ts = NULL;
ms_release_timer_start(ms);
}
ms_update_status(ms);
ms_unref(ms, MS_USE_TBF);
}
/* Cleans up old MS being merged into a new one. Should be called with a
ms_ref() taken to avoid use-after-free. */
void ms_reset(struct GprsMs *ms)
{
LOGPMS(ms, DRLCMAC, LOGL_INFO, "Clearing MS object\n");
struct llist_item *pos;
struct gprs_rlcmac_tbf *tbf;
ms_release_timer_stop(ms);
/* free immediately when it becomes idle: */
ms->delay = 0;
tbf = ul_tbf_as_tbf(ms_ul_tbf(ms));
if (tbf && !tbf_timers_pending(tbf, T_MAX))
tbf_free(tbf);
tbf = dl_tbf_as_tbf(ms_dl_tbf(ms));
if (tbf && !tbf_timers_pending(tbf, T_MAX))
tbf_free(tbf);
llist_for_each_entry(pos, &ms->old_tbfs, list) {
tbf = (struct gprs_rlcmac_tbf *)pos->entry;
if (!tbf_timers_pending(tbf, T_MAX))
tbf_free(tbf);
}
/* Flag it with invalid data so that it cannot be looked up anymore and
* shows up specially if listed in VTY: */
ms->tlli = GSM_RESERVED_TMSI;
ms->new_dl_tlli = ms->tlli;
ms->new_ul_tlli = ms->tlli;
@ -507,12 +470,6 @@ void ms_merge_and_clear_ms(struct GprsMs *ms, struct GprsMs *old_ms)
llc_queue_move_and_merge(&ms->llc_queue, &old_ms->llc_queue);
/* Clean up the old MS object */
/* TODO: Use timer? */
if (ms_ul_tbf(old_ms) && !tbf_timers_pending((struct gprs_rlcmac_tbf *)ms_ul_tbf(old_ms), T_MAX))
tbf_free((struct gprs_rlcmac_tbf *)ms_ul_tbf(old_ms));
if (ms_dl_tbf(old_ms) && !tbf_timers_pending((struct gprs_rlcmac_tbf *)ms_dl_tbf(old_ms), T_MAX))
tbf_free((struct gprs_rlcmac_tbf *)ms_dl_tbf(old_ms));
ms_reset(old_ms);
ms_unref(old_ms, __func__);

View File

@ -51,14 +51,8 @@ struct gprs_rlcmac_bts;
struct gprs_rlcmac_trx;
struct GprsMs;
struct gpr_ms_callback {
void (*ms_idle)(struct GprsMs *);
void (*ms_active)(struct GprsMs *);
};
struct GprsMs {
struct llist_head list; /* list of all GprsMs */
struct gpr_ms_callback cb;
bool app_info_pending;
struct gprs_rlcmac_bts *bts;
@ -84,7 +78,6 @@ struct GprsMs {
struct gprs_llc_queue llc_queue;
struct osmo_timer_list llc_timer;
bool is_idle;
struct osmo_use_count use_count;
struct osmo_timer_list timer;
unsigned delay;
@ -140,8 +133,6 @@ static inline struct gprs_rlcmac_dl_tbf *ms_dl_tbf(const struct GprsMs *ms) {ret
const char *ms_name(const struct GprsMs *ms);
char *ms_name_buf(const struct GprsMs *ms, char *buf, unsigned int buf_size);
void ms_set_callback(struct GprsMs *ms, struct gpr_ms_callback *cb);
int ms_nacc_start(struct GprsMs *ms, Packet_Cell_Change_Notification_t *notif);
bool ms_nacc_rts(const struct GprsMs *ms);
struct msgb *ms_nacc_create_rlcmac_msg(struct GprsMs *ms, struct gprs_rlcmac_tbf *tbf,
@ -157,8 +148,7 @@ int ms_append_llc_dl_data(struct GprsMs *ms, uint16_t pdu_delay_csec, const uint
static inline bool ms_is_idle(const struct GprsMs *ms)
{
return !ms->ul_tbf && !ms->dl_tbf &&
llist_empty(&ms->old_tbfs) &&
osmo_use_count_total(&ms->use_count) == 0;
llist_empty(&ms->old_tbfs);
}
static inline struct gprs_llc_queue *ms_llc_queue(struct GprsMs *ms)
@ -251,7 +241,7 @@ static inline struct gprs_rlcmac_trx *ms_current_trx(const struct GprsMs *ms)
return ms->current_trx;
}
#define MS_USE_RELEASE_TIMER "release_timer"
#define MS_USE_TBF "tbf"
#define ms_ref(ms, use) \
OSMO_ASSERT(osmo_use_count_get_put(&(ms)->use_count, use, 1) == 0)
#define ms_unref(ms, use) \

View File

@ -419482,8 +419482,8 @@ DL_ASS_TBF(DL:TFI-0-0-1:STATE-NEW:GPRS:TLLI-0xc0000001){NONE}: Deallocated
MS(TLLI-0xc0000001:TA-220:MSCLS-2-0) Allocating DL TBF
UL_ASS_TBF{NONE}: Allocated
DL_ASS_TBF{NONE}: Allocated
TBF(DL:TFI-0-0-1:STATE-NEW:GPRS:TLLI-0xc0000001) Setting Control TS PDCH(bts=0,trx=0,ts=4)
TBF(DL:TFI-0-0-1:STATE-NEW:GPRS:TLLI-0xc0000001) Allocated: trx = 0, ul_slots = 10, dl_slots = 18
TBF(DL:TFI-0-0-1:STATE-NEW:GPRS:TLLI-0xc0000001) Setting Control TS PDCH(bts=0,trx=0,ts=5)
TBF(DL:TFI-0-0-1:STATE-NEW:GPRS:TLLI-0xc0000001) Allocated: trx = 0, ul_slots = 20, dl_slots = 30
No TFI available (suggested TRX: 0).
TBF(DL:TFI-0-0-2:STATE-NEW:GPRS:TLLI-0xc0000002) free
UL_ASS_TBF(DL:TFI-0-0-2:STATE-NEW:GPRS:TLLI-0xc0000002){NONE}: Deallocated
@ -419509,8 +419509,8 @@ DL_ASS_TBF(DL:TFI-0-0-4:STATE-NEW:GPRS:TLLI-0xc0000004){NONE}: Deallocated
MS(TLLI-0xc0000004:TA-220:MSCLS-5-0) Allocating DL TBF
UL_ASS_TBF{NONE}: Allocated
DL_ASS_TBF{NONE}: Allocated
TBF(DL:TFI-0-0-4:STATE-NEW:GPRS:TLLI-0xc0000004) Setting Control TS PDCH(bts=0,trx=0,ts=3)
TBF(DL:TFI-0-0-4:STATE-NEW:GPRS:TLLI-0xc0000004) Allocated: trx = 0, ul_slots = 08, dl_slots = 18
TBF(DL:TFI-0-0-4:STATE-NEW:GPRS:TLLI-0xc0000004) Setting Control TS PDCH(bts=0,trx=0,ts=6)
TBF(DL:TFI-0-0-4:STATE-NEW:GPRS:TLLI-0xc0000004) Allocated: trx = 0, ul_slots = 40, dl_slots = c0
No TFI available (suggested TRX: 0).
TBF(DL:TFI-0-0-5:STATE-NEW:GPRS:TLLI-0xc0000005) free
UL_ASS_TBF(DL:TFI-0-0-5:STATE-NEW:GPRS:TLLI-0xc0000005){NONE}: Deallocated
@ -419527,8 +419527,8 @@ DL_ASS_TBF(DL:TFI-0-0-6:STATE-NEW:GPRS:TLLI-0xc0000006){NONE}: Deallocated
MS(TLLI-0xc0000006:TA-220:MSCLS-7-0) Allocating DL TBF
UL_ASS_TBF{NONE}: Allocated
DL_ASS_TBF{NONE}: Allocated
TBF(DL:TFI-0-0-6:STATE-NEW:GPRS:TLLI-0xc0000006) Setting Control TS PDCH(bts=0,trx=0,ts=6)
TBF(DL:TFI-0-0-6:STATE-NEW:GPRS:TLLI-0xc0000006) Allocated: trx = 0, ul_slots = 40, dl_slots = c0
TBF(DL:TFI-0-0-6:STATE-NEW:GPRS:TLLI-0xc0000006) Setting Control TS PDCH(bts=0,trx=0,ts=5)
TBF(DL:TFI-0-0-6:STATE-NEW:GPRS:TLLI-0xc0000006) Allocated: trx = 0, ul_slots = 20, dl_slots = 60
No TFI available (suggested TRX: 0).
TBF(DL:TFI-0-0-7:STATE-NEW:GPRS:TLLI-0xc0000007) free
UL_ASS_TBF(DL:TFI-0-0-7:STATE-NEW:GPRS:TLLI-0xc0000007){NONE}: Deallocated

View File

@ -14805,12 +14805,12 @@ Going to test assignment with many connections, algorithm B
TBF[30] class 31 reserves ....DDCD
TBF[31] class 32 reserves ...DDCD.
TBF[0] class 1 reserves ...C....
TBF[1] class 2 reserves ...DC...
TBF[1] class 2 reserves ....DC..
TBF[2] class 3 reserves ......DC
TBF[3] class 4 reserves ...DCD..
TBF[4] class 5 reserves ...CD...
TBF[4] class 5 reserves ......CD
TBF[5] class 6 reserves ...CD...
TBF[6] class 7 reserves ......CD
TBF[6] class 7 reserves .....CD.
TBF[7] class 8 reserves ....DDCD
TBF[8] class 9 reserves ...DCD..
TBF[9] class 10 reserves .....DCD

View File

@ -24,8 +24,7 @@ PDCH(bts=0,trx=0,ts=5) Attaching TBF(DL:TFI-0-0-0:STATE-NEW:EGPRS), 1 TBFs, USFs
PDCH(bts=0,trx=0,ts=6) Attaching TBF(DL:TFI-0-0-0:STATE-NEW:EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001.
PDCH(bts=0,trx=0,ts=7) Attaching TBF(DL:TFI-0-0-0:STATE-NEW:EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001.
MS(TA-220:MSCLS-10-11) Attaching DL TBF: TBF(DL:TFI-0-0-0:STATE-NEW:EGPRS)
MS(TA-220:MSCLS-10-11): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TA-220:MSCLS-10-11:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TA-220:MSCLS-10-11:DL): + tbf: now used by 1 (tbf)
ws(64)
Creating MS object
Modifying MS object, TLLI = 0xffffffff, MS class 0 -> 12
@ -36,8 +35,7 @@ PDCH(bts=0,trx=0,ts=4) Attaching TBF(DL:TFI-0-0-1:STATE-NEW:EGPRS), 2 TBFs, USFs
PDCH(bts=0,trx=0,ts=5) Attaching TBF(DL:TFI-0-0-1:STATE-NEW:EGPRS), 2 TBFs, USFs = 00, TFIs = 00000003.
PDCH(bts=0,trx=0,ts=6) Attaching TBF(DL:TFI-0-0-1:STATE-NEW:EGPRS), 2 TBFs, USFs = 00, TFIs = 00000003.
MS(TA-220:MSCLS-12-13) Attaching DL TBF: TBF(DL:TFI-0-0-1:STATE-NEW:EGPRS)
MS(TA-220:MSCLS-12-13): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TA-220:MSCLS-12-13:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TA-220:MSCLS-12-13:DL): + tbf: now used by 1 (tbf)
ws(64)
--- test_sched_app_info_ok ---
@ -65,9 +63,11 @@ PDCH(bts=0,trx=0,ts=5) Detaching TBF(DL:TFI-0-0-0:STATE-NEW:EGPRS), 2 TBFs, USFs
PDCH(bts=0,trx=0,ts=6) Detaching TBF(DL:TFI-0-0-0:STATE-NEW:EGPRS), 2 TBFs, USFs = 00, TFIs = 00000003.
PDCH(bts=0,trx=0,ts=7) Detaching TBF(DL:TFI-0-0-0:STATE-NEW:EGPRS), 1 TBFs, USFs = 00, TFIs = 00000001.
MS(TA-220:MSCLS-10-11:DL) Detaching TBF: TBF(DL:TFI-0-0-0:STATE-NEW:EGPRS)
MS(TA-220:MSCLS-10-11): - tbf: now used by 0 (-)
MS(TA-220:MSCLS-10-11) Destroying MS object
PDCH(bts=0,trx=0,ts=4) Detaching TBF(DL:TFI-0-0-1:STATE-NEW:EGPRS), 1 TBFs, USFs = 00, TFIs = 00000002.
PDCH(bts=0,trx=0,ts=5) Detaching TBF(DL:TFI-0-0-1:STATE-NEW:EGPRS), 1 TBFs, USFs = 00, TFIs = 00000002.
PDCH(bts=0,trx=0,ts=6) Detaching TBF(DL:TFI-0-0-1:STATE-NEW:EGPRS), 1 TBFs, USFs = 00, TFIs = 00000002.
MS(TA-220:MSCLS-12-13:DL) Detaching TBF: TBF(DL:TFI-0-0-1:STATE-NEW:EGPRS)
MS(TA-220:MSCLS-12-13): - tbf: now used by 0 (-)
MS(TA-220:MSCLS-12-13) Destroying MS object

View File

@ -120,96 +120,6 @@ static void test_ms_state()
printf("=== end %s ===\n", __func__);
}
static enum {CB_UNKNOWN, CB_IS_IDLE, CB_IS_ACTIVE} last_cb = CB_UNKNOWN;
static void ms_idle_cb(struct GprsMs *ms)
{
OSMO_ASSERT(ms_is_idle(ms));
printf(" ms_idle() was called\n");
last_cb = CB_IS_IDLE;
}
static void ms_active_cb(struct GprsMs *ms)
{
OSMO_ASSERT(!ms_is_idle(ms));
printf(" ms_active() was called\n");
last_cb = CB_IS_ACTIVE;
}
static struct gpr_ms_callback ms_cb = {
.ms_idle = ms_idle_cb,
.ms_active = ms_active_cb
};
static void test_ms_callback()
{
uint32_t tlli = 0xffeeddbb;
gprs_rlcmac_dl_tbf *dl_tbf;
gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
GprsMs *ms;
last_cb = CB_UNKNOWN;
printf("=== start %s ===\n", __func__);
ms = ms_alloc(bts);
ms_set_tlli(ms, tlli);
ms_set_callback(ms, &ms_cb);
OSMO_ASSERT(ms_is_idle(ms));
dl_tbf = alloc_dl_tbf(bts, ms);
ul_tbf = alloc_ul_tbf(bts, ms);
OSMO_ASSERT(last_cb == CB_UNKNOWN);
ms_attach_tbf(ms, ul_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
OSMO_ASSERT(last_cb == CB_IS_ACTIVE);
last_cb = CB_UNKNOWN;
ms_attach_tbf(ms, dl_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
OSMO_ASSERT(last_cb == CB_UNKNOWN);
ms_detach_tbf(ms, ul_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf);
OSMO_ASSERT(last_cb == CB_UNKNOWN);
ms_detach_tbf(ms, dl_tbf);
OSMO_ASSERT(ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
OSMO_ASSERT(last_cb == CB_IS_IDLE);
last_cb = CB_UNKNOWN;
talloc_free(ms);
talloc_free(dl_tbf);
talloc_free(ul_tbf);
talloc_free(bts);
printf("=== end %s ===\n", __func__);
}
static bool was_idle;
static void ms_replace_tbf_idle_cb(struct GprsMs *ms)
{
OSMO_ASSERT(ms_is_idle(ms));
printf(" ms_idle() was called\n");
was_idle = true;
}
static void ms_replace_tbf_active_cb(struct GprsMs *ms)
{
OSMO_ASSERT(!ms_is_idle(ms));
printf(" ms_active() was called\n");
}
static struct gpr_ms_callback ms_replace_tbf_cb = {
.ms_idle = ms_replace_tbf_idle_cb,
.ms_active = ms_replace_tbf_active_cb
};
static void test_ms_replace_tbf()
{
uint32_t tlli = 0xffeeddbb;
@ -222,10 +132,8 @@ static void test_ms_replace_tbf()
ms = ms_alloc(bts);
ms_confirm_tlli(ms, tlli);
ms_set_callback(ms, &ms_replace_tbf_cb);
OSMO_ASSERT(ms_is_idle(ms));
was_idle = false;
dl_tbf[0] = alloc_dl_tbf(bts, ms);
dl_tbf[1] = alloc_dl_tbf(bts, ms);
@ -236,44 +144,34 @@ static void test_ms_replace_tbf()
OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[0]);
OSMO_ASSERT(llist_empty(&ms->old_tbfs));
OSMO_ASSERT(!was_idle);
ms_attach_tbf(ms, dl_tbf[1]);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[1]);
OSMO_ASSERT(!llist_empty(&ms->old_tbfs));
OSMO_ASSERT(!was_idle);
ms_attach_tbf(ms, ul_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == ul_tbf);
OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[1]);
OSMO_ASSERT(!llist_empty(&ms->old_tbfs));
OSMO_ASSERT(!was_idle);
ms_detach_tbf(ms, ul_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[1]);
OSMO_ASSERT(!llist_empty(&ms->old_tbfs));
OSMO_ASSERT(!was_idle);
ms_detach_tbf(ms, dl_tbf[0]);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
OSMO_ASSERT(ms_dl_tbf(ms) == dl_tbf[1]);
OSMO_ASSERT(llist_empty(&ms->old_tbfs));
OSMO_ASSERT(!was_idle);
ms_detach_tbf(ms, dl_tbf[1]);
OSMO_ASSERT(ms_is_idle(ms));
OSMO_ASSERT(ms_ul_tbf(ms) == NULL);
OSMO_ASSERT(ms_dl_tbf(ms) == NULL);
OSMO_ASSERT(llist_empty(&ms->old_tbfs));
OSMO_ASSERT(was_idle);
talloc_free(ms);
/* MS is gone now: */
OSMO_ASSERT(bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI) == NULL);
talloc_free(dl_tbf[0]);
talloc_free(dl_tbf[1]);
@ -470,13 +368,11 @@ static void test_ms_timeout()
gprs_rlcmac_ul_tbf *ul_tbf;
struct gprs_rlcmac_bts *bts = bts_alloc(the_pcu, 0);
GprsMs *ms;
last_cb = CB_UNKNOWN;
printf("=== start %s ===\n", __func__);
ms = ms_alloc(bts);
ms_set_tlli(ms, tlli);
ms_set_callback(ms, &ms_cb);
ms_set_timeout(ms, 1);
OSMO_ASSERT(ms_is_idle(ms));
@ -484,34 +380,27 @@ static void test_ms_timeout()
dl_tbf = alloc_dl_tbf(bts, ms);
ul_tbf = alloc_ul_tbf(bts, ms);
OSMO_ASSERT(last_cb == CB_UNKNOWN);
ms_attach_tbf(ms, ul_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(last_cb == CB_IS_ACTIVE);
last_cb = CB_UNKNOWN;
ms_attach_tbf(ms, dl_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(last_cb == CB_UNKNOWN);
ms_detach_tbf(ms, ul_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(last_cb == CB_UNKNOWN);
ms_detach_tbf(ms, dl_tbf);
OSMO_ASSERT(!ms_is_idle(ms));
OSMO_ASSERT(last_cb == CB_UNKNOWN);
/* test MS still exists and it's idle: */
OSMO_ASSERT(bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI) != NULL);
OSMO_ASSERT(ms_is_idle(ms));
OSMO_ASSERT(osmo_timer_pending(&ms->timer));
usleep(1100000);
osmo_timers_update();
OSMO_ASSERT(ms_is_idle(ms));
OSMO_ASSERT(last_cb == CB_IS_IDLE);
/* MS is gone now: */
OSMO_ASSERT(bts_get_ms_by_tlli(bts, tlli, GSM_RESERVED_TMSI) == NULL);
last_cb = CB_UNKNOWN;
talloc_free(ms);
talloc_free(dl_tbf);
talloc_free(ul_tbf);
talloc_free(bts);
@ -651,7 +540,6 @@ int main(int argc, char **argv)
osmo_tdef_set(the_pcu->T_defs, -2030, 0, OSMO_TDEF_S);
test_ms_state();
test_ms_callback();
test_ms_replace_tbf();
test_ms_change_tlli();
test_ms_storage();

View File

@ -1,39 +1,22 @@
Creating MS object
Modifying MS object, UL TLLI: 0xffffffff -> 0xffeeddbb, not yet confirmed
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Attaching UL TBF: TBF(UL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): + ms_attach_ul_tbf: now used by 1 (ms_attach_ul_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): - ms_attach_ul_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): + tbf: now used by 1 (tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL) Attaching DL TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL:DL) Detaching TBF: TBF(UL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Detaching TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Destroying MS object
Creating MS object
Modifying MS object, UL TLLI: 0xffffffff -> 0xffeeddbb, not yet confirmed
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Attaching UL TBF: TBF(UL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): + ms_attach_ul_tbf: now used by 1 (ms_attach_ul_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): - ms_attach_ul_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL) Attaching DL TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL:DL) Detaching TBF: TBF(UL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Detaching TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): - tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Destroying MS object
Creating MS object
The MS object cannot fully confirm an unexpected TLLI: 0xffeeddbb, partly confirmed
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Attaching DL TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL): + tbf: now used by 1 (tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Attaching DL TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Attaching UL TBF: TBF(UL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL): + ms_attach_ul_tbf: now used by 1 (ms_attach_ul_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL:DL): - ms_attach_ul_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL:DL) Detaching TBF: TBF(UL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Detaching TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Detaching TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): - tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Destroying MS object
Creating MS object
Modifying MS object, UL TLLI: 0xffffffff -> 0xff001111, not yet confirmed
@ -59,43 +42,39 @@ Creating MS object
Modifying MS object, UL TLLI: 0xffffffff -> 0xffeeddbc, not yet confirmed
Modifying MS object, TLLI = 0xffeeddbc, IMSI '' -> '001001987654322'
MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Attaching UL TBF: TBF(UL:STATE-NEW:GPRS:IMSI-001001987654321:TLLI-0xffeeddbb)
MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0): + ms_attach_ul_tbf: now used by 1 (ms_attach_ul_tbf)
MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): - ms_attach_ul_tbf: now used by 0 (-)
MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): + tbf: now used by 1 (tbf)
MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL) Detaching TBF: TBF(UL:STATE-NEW:GPRS:IMSI-001001987654321:TLLI-0xffeeddbb)
MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0): - tbf: now used by 0 (-)
MS(IMSI-001001987654321:TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Destroying MS object
MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0) Attaching UL TBF: TBF(UL:STATE-NEW:GPRS:IMSI-001001987654322:TLLI-0xffeeddbc)
MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0): + ms_attach_ul_tbf: now used by 1 (ms_attach_ul_tbf)
MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0:UL): - ms_attach_ul_tbf: now used by 0 (-)
MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0:UL): + tbf: now used by 1 (tbf)
MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0:UL) Detaching TBF: TBF(UL:STATE-NEW:GPRS:IMSI-001001987654322:TLLI-0xffeeddbc)
MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0): - tbf: now used by 0 (-)
MS(IMSI-001001987654322:TLLI-0xffeeddbc:TA-220:MSCLS-0-0) Destroying MS object
Creating MS object
Modifying MS object, UL TLLI: 0xffffffff -> 0xffeeddbb, not yet confirmed
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Attaching UL TBF: TBF(UL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): + ms_attach_ul_tbf: now used by 1 (ms_attach_ul_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): - ms_attach_ul_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): + tbf: now used by 1 (tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL) Attaching DL TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:UL:DL) Detaching TBF: TBF(UL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Detaching TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): + release_timer: now used by 1 (release_timer)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): - tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Release timer expired
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): - release_timer: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Destroying MS object
Creating MS object
The MS object cannot fully confirm an unexpected TLLI: 0xffeeddbb, partly confirmed
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0) Attaching DL TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL): + tbf: now used by 1 (tbf)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Destroying MS object
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0:DL) Detaching TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xffeeddbb)
MS(TLLI-0xffeeddbb:TA-220:MSCLS-0-0): - tbf: now used by 0 (-)
Creating MS object
The MS object cannot fully confirm an unexpected TLLI: 0xdeadbeef, partly confirmed
Creating MS object
The MS object cannot fully confirm an unexpected TLLI: 0xdeadbef0, partly confirmed
MS(TLLI-0xdeadbef0:TA-220:MSCLS-0-0) Attaching DL TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xdeadbef0)
MS(TLLI-0xdeadbef0:TA-220:MSCLS-0-0): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TLLI-0xdeadbef0:TA-220:MSCLS-0-0:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TLLI-0xdeadbef0:TA-220:MSCLS-0-0:DL): + tbf: now used by 1 (tbf)
MS(TLLI-0xdeadbeef:TA-220:MSCLS-0-0) Destroying MS object
MS(TLLI-0xdeadbef0:TA-220:MSCLS-0-0:DL) Destroying MS object
MS(TLLI-0xdeadbef0:TA-220:MSCLS-0-0:DL) Detaching TBF: TBF(DL:STATE-NEW:GPRS:TLLI-0xdeadbef0)
MS(TLLI-0xdeadbef0:TA-220:MSCLS-0-0): - tbf: now used by 0 (-)

View File

@ -1,20 +1,12 @@
=== start test_ms_state ===
=== end test_ms_state ===
=== start test_ms_callback ===
ms_active() was called
ms_idle() was called
=== end test_ms_callback ===
=== start test_ms_replace_tbf ===
ms_active() was called
ms_idle() was called
=== end test_ms_replace_tbf ===
=== start test_ms_change_tlli ===
=== end test_ms_change_tlli ===
=== start test_ms_storage ===
=== end test_ms_storage ===
=== start test_ms_timeout ===
ms_active() was called
ms_idle() was called
=== end test_ms_timeout ===
=== start test_ms_cs_selection ===
=== end test_ms_cs_selection ===

File diff suppressed because it is too large Load Diff

View File

@ -18,8 +18,7 @@ PDCH(bts=0,trx=0,ts=0) PDCH state: disabled => enabled
Creating MS object
The MS object cannot fully confirm an unexpected TLLI: 0x12345678, partly confirmed
MS(TLLI-0x12345678:TA-220:MSCLS-0-0) Attaching DL TBF: TBF(DL:TFI-0-0--1:STATE-NEW:GPRS:TLLI-0x12345678)
MS(TLLI-0x12345678:TA-220:MSCLS-0-0): + ms_attach_dl_tbf: now used by 1 (ms_attach_dl_tbf)
MS(TLLI-0x12345678:TA-220:MSCLS-0-0:DL): - ms_attach_dl_tbf: now used by 0 (-)
MS(TLLI-0x12345678:TA-220:MSCLS-0-0:DL): + tbf: now used by 1 (tbf)
PDCH(bts=0,trx=0,ts=0) Reserving FN 2715608 for type POLL
PDCH(bts=0,trx=0,ts=0) Reserving FN 2715613 for type POLL
PDCH(bts=0,trx=0,ts=0) Reserving FN 2715617 for type POLL
@ -76,6 +75,7 @@ PDCH(bts=0,trx=0,ts=0) Expiring FN=43 but previous FN=39 is still reserved!
PDCH(bts=0,trx=0,ts=0) Timeout for registered POLL (FN=39, reason=UL_ASS): TBF(DL:TFI-0-0--1:STATE-NEW:GPRS:TLLI-0x12345678)
MS(TLLI-0x12345678:TA-220:MSCLS-0-0:DL) Destroying MS object
MS(TLLI-0x12345678:TA-220:MSCLS-0-0:DL) Detaching TBF: TBF(DL:TFI-0-0--1:STATE-NEW:GPRS:TLLI-0x12345678)
MS(TLLI-0x12345678:TA-220:MSCLS-0-0): - tbf: now used by 0 (-)
PDCH(bts=0,trx=0,ts=0) PDCH state: disabled => enabled
PDCH(bts=0,trx=0,ts=0) Reserving FN 104 for type SBA
PDCH(bts=0,trx=0,ts=0) Reserving FN 117 for type SBA