Files
nextepc-oss/lib/core/ogs-timer.c
Sukchan Lee b08b2adc6c [AMF/MME] Remove code that doesn't work (#2013)
Based on the standard document below, when the UE is in the IDLE state,
we checked the implicit timer and tried to send a message to the UE,
but it doesn't work properly.

So, first of all, I deleted the related code.

- TS 24.301 Ch 5.3.7
If ISR is not activated, the network behaviour upon expiry of
the mobile reachable timer is network dependent, but typically
the network stops sending paging messages to the UE on the
first expiry, and may take other appropriate actions

- TS 24.501 Ch 5.3.7
The network behaviour upon expiry of the mobile reachable timer is network dependent,
but typically the network stops sending paging messages to the UE on the first expiry,
and may take other appropriate actions.
2023-07-23 14:54:06 +09:00

210 lines
5.1 KiB
C

/*
* Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
*
* This file is part of Open5GS.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "ogs-core.h"
#undef OGS_LOG_DOMAIN
#define OGS_LOG_DOMAIN __ogs_event_domain
typedef struct ogs_timer_mgr_s {
OGS_POOL(pool, ogs_timer_t);
ogs_rbtree_t tree;
} ogs_timer_mgr_t;
static void add_timer_node(
ogs_rbtree_t *tree, ogs_timer_t *timer, ogs_time_t duration)
{
ogs_rbnode_t **new = NULL;
ogs_rbnode_t *parent = NULL;
ogs_assert(tree);
ogs_assert(timer);
timer->timeout = ogs_get_monotonic_time() + duration;
new = &tree->root;
while (*new) {
ogs_timer_t *this = ogs_rb_entry(*new, ogs_timer_t, rbnode);
parent = *new;
if (timer->timeout < this->timeout)
new = &(*new)->left;
else
new = &(*new)->right;
}
ogs_rbtree_link_node(timer, parent, new);
ogs_rbtree_insert_color(tree, timer);
}
ogs_timer_mgr_t *ogs_timer_mgr_create(unsigned int capacity)
{
ogs_timer_mgr_t *manager = ogs_calloc(1, sizeof *manager);
if (!manager) {
ogs_error("ogs_calloc() failed");
return NULL;
}
ogs_pool_init(&manager->pool, capacity);
return manager;
}
void ogs_timer_mgr_destroy(ogs_timer_mgr_t *manager)
{
ogs_assert(manager);
ogs_pool_final(&manager->pool);
ogs_free(manager);
}
static ogs_timer_t *ogs_timer_cycle(ogs_timer_mgr_t *manager, ogs_timer_t *timer)
{
ogs_assert(manager);
return ogs_pool_cycle(&manager->pool, timer);
}
ogs_timer_t *ogs_timer_add(
ogs_timer_mgr_t *manager, void (*cb)(void *data), void *data)
{
ogs_timer_t *timer = NULL;
ogs_assert(manager);
ogs_pool_alloc(&manager->pool, &timer);
if (!timer) {
ogs_fatal("ogs_pool_alloc() failed");
return NULL;
}
memset(timer, 0, sizeof *timer);
timer->cb = cb;
timer->data = data;
timer->manager = manager;
return timer;
}
void ogs_timer_delete_debug(ogs_timer_t *timer, const char *file_line)
{
ogs_timer_mgr_t *manager;
ogs_assert(timer);
manager = timer->manager;
ogs_assert(manager);
timer = ogs_timer_cycle(manager, timer);
if (!timer) {
ogs_fatal("ogs_timer_delete() failed in %s", file_line);
ogs_assert_if_reached();
}
ogs_timer_stop(timer);
ogs_pool_free(&manager->pool, timer);
}
void ogs_timer_start_debug(
ogs_timer_t *timer, ogs_time_t duration, const char *file_line)
{
ogs_timer_mgr_t *manager = NULL;
ogs_assert(timer);
ogs_assert(duration);
manager = timer->manager;
ogs_assert(manager);
timer = ogs_timer_cycle(manager, timer);
if (!timer) {
ogs_fatal("ogs_timer_start() failed in %s", file_line);
ogs_assert_if_reached();
}
if (timer->running == true)
ogs_rbtree_delete(&manager->tree, timer);
timer->running = true;
add_timer_node(&manager->tree, timer, duration);
}
void ogs_timer_stop_debug(ogs_timer_t *timer, const char *file_line)
{
ogs_timer_mgr_t *manager = NULL;
ogs_assert(timer);
manager = timer->manager;
ogs_assert(manager);
timer = ogs_timer_cycle(manager, timer);
ogs_assert(timer);
if (!timer) {
ogs_fatal("ogs_timer_stop() failed in %s", file_line);
ogs_assert_if_reached();
}
if (timer->running == false)
return;
timer->running = false;
ogs_rbtree_delete(&manager->tree, timer);
}
ogs_time_t ogs_timer_mgr_next(ogs_timer_mgr_t *manager)
{
ogs_time_t current;
ogs_rbnode_t *rbnode = NULL;
ogs_assert(manager);
current = ogs_get_monotonic_time();
rbnode = ogs_rbtree_first(&manager->tree);
if (rbnode) {
ogs_timer_t *this = ogs_rb_entry(rbnode, ogs_timer_t, rbnode);
if (this->timeout > current) {
return (this->timeout - current);
} else {
return OGS_NO_WAIT_TIME;
}
}
return OGS_INFINITE_TIME;
}
void ogs_timer_mgr_expire(ogs_timer_mgr_t *manager)
{
OGS_LIST(list);
ogs_lnode_t *lnode;
ogs_time_t current;
ogs_rbnode_t *rbnode;
ogs_timer_t *this;
ogs_assert(manager);
current = ogs_get_monotonic_time();
ogs_rbtree_for_each(&manager->tree, rbnode) {
this = ogs_rb_entry(rbnode, ogs_timer_t, rbnode);
if (this->timeout > current)
break;
ogs_list_add(&list, &this->lnode);
}
ogs_list_for_each(&list, lnode) {
this = ogs_rb_entry(lnode, ogs_timer_t, lnode);
ogs_timer_stop(this);
if (this->cb)
this->cb(this->data);
}
}