Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
常顺宇
OpenXG-RAN
Commits
7aa9a7bd
Commit
7aa9a7bd
authored
May 03, 2020
by
laurent
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
work in progress, re-merge before continuing
parent
07c8d000
Changes
18
Hide whitespace changes
Inline
Side-by-side
Showing
18 changed files
with
17 additions
and
3145 deletions
+17
-3145
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+1
-0
cmake_targets/nas_sim_tools/CMakeLists.txt
cmake_targets/nas_sim_tools/CMakeLists.txt
+1
-0
common/utils/itti_analyzer/common/queue.h
common/utils/itti_analyzer/common/queue.h
+0
-592
openair1/PHY/LTE_UE_TRANSPORT/sldch.c
openair1/PHY/LTE_UE_TRANSPORT/sldch.c
+0
-5
openair1/PHY/LTE_UE_TRANSPORT/slsch.c
openair1/PHY/LTE_UE_TRANSPORT/slsch.c
+0
-4
openair1/PHY/LTE_UE_TRANSPORT/slss.c
openair1/PHY/LTE_UE_TRANSPORT/slss.c
+0
-4
openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h
openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h
+3
-63
openair1/PHY/phy_vars_nr_ue.h
openair1/PHY/phy_vars_nr_ue.h
+1
-1
openair1/PHY/phy_vars_ue.h
openair1/PHY/phy_vars_ue.h
+3
-3
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
+0
-11
openair1/SIMULATION/TOOLS/rangen_double.c
openair1/SIMULATION/TOOLS/rangen_double.c
+0
-2
openair3/M3AP/m3ap_MCE_handler.h
openair3/M3AP/m3ap_MCE_handler.h
+4
-4
openair3/M3AP/m3ap_MME_generate_messages.h
openair3/M3AP/m3ap_MME_generate_messages.h
+4
-4
openair3/NAS/COMMON/API/NETWORK/as_message.h
openair3/NAS/COMMON/API/NETWORK/as_message.h
+0
-578
openair3/NAS/COMMON/commonDef.h
openair3/NAS/COMMON/commonDef.h
+0
-333
openair3/NAS/COMMON/networkDef.h
openair3/NAS/COMMON/networkDef.h
+0
-271
openair3/UTILS/queue.h
openair3/UTILS/queue.h
+0
-592
openair3/UTILS/tree.h
openair3/UTILS/tree.h
+0
-678
No files found.
cmake_targets/CMakeLists.txt
View file @
7aa9a7bd
...
...
@@ -884,6 +884,7 @@ include_directories("${OPENAIR2_DIR}/LAYER2/PDCP_v10.1.0")
include_directories
(
"
${
OPENAIR2_DIR
}
/RRC/LTE/MESSAGES"
)
include_directories
(
"
${
OPENAIR2_DIR
}
/RRC/LTE"
)
include_directories
(
"
${
OPENAIR_DIR
}
/common/utils"
)
include_directories
(
"
${
OPENAIR_DIR
}
/common/utils/collection"
)
include_directories
(
"
${
OPENAIR_DIR
}
/common/utils/ocp_itti"
)
include_directories
(
"
${
OPENAIR3_DIR
}
/NAS/COMMON"
)
include_directories
(
"
${
OPENAIR3_DIR
}
/NAS/COMMON/API/NETWORK"
)
...
...
cmake_targets/nas_sim_tools/CMakeLists.txt
View file @
7aa9a7bd
...
...
@@ -14,6 +14,7 @@ set(CMAKE_C_FLAGS
set
(
OPENAIR_DIR $ENV{OPENAIR_DIR}
)
set
(
OPENAIR3_DIR $ENV{OPENAIR_DIR}/openair3
)
include_directories
(
${
OPENAIR_DIR
}
/openair2/COMMON
)
set
(
CONF2UEDATA_LIB_SRC
${
OPENAIR_DIR
}
/openair3/NAS/TOOLS/conf_emm.c
...
...
common/utils/itti_analyzer/common/queue.h
deleted
100644 → 0
View file @
07c8d000
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
* A singly-linked list is headed by a single forward pointer. The
* elements are singly linked for minimum space and pointer manipulation
* overhead at the expense of O(n) removal for arbitrary elements. New
* elements can be added to the list after an existing element or at the
* head of the list. Elements being removed from the head of the list
* should use the explicit macro for this purpose for optimum
* efficiency. A singly-linked list may only be traversed in the forward
* direction. Singly-linked lists are ideal for applications with large
* datasets and few or no removals or for implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
* SLIST LIST STAILQ TAILQ CIRCLEQ
* _HEAD + + + + +
* _HEAD_INITIALIZER + + + + +
* _ENTRY + + + + +
* _INIT + + + + +
* _EMPTY + + + + +
* _FIRST + + + + +
* _NEXT + + + + +
* _PREV - - - + +
* _LAST - - + + +
* _FOREACH + + + + +
* _FOREACH_REVERSE - - - + +
* _INSERT_HEAD + + + + +
* _INSERT_BEFORE - + - + +
* _INSERT_AFTER + + + + +
* _INSERT_TAIL - - + + +
* _REMOVE_HEAD + - + - -
* _REMOVE + + + + +
*/
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first;
/* first element */
\
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next;
/* next element */
\
struct type **le_prev;
/* address of previous next element */
\
}
/*
* List functions.
*/
#define LIST_INIT(head) do { \
(head)->lh_first = NULL; \
} while (
/*CONSTCOND*/
0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (
/*CONSTCOND*/
0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (
/*CONSTCOND*/
0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (
/*CONSTCOND*/
0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
} while (
/*CONSTCOND*/
0)
#define LIST_FOREACH(var, head, field) \
for ((var) = ((head)->lh_first); \
(var); \
(var) = ((var)->field.le_next))
/*
* List access methods.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first;
/* first element */
\
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next;
/* next element */
\
}
/*
* Singly-linked List functions.
*/
#define SLIST_INIT(head) do { \
(head)->slh_first = NULL; \
} while (
/*CONSTCOND*/
0)
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (
/*CONSTCOND*/
0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (
/*CONSTCOND*/
0)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (
/*CONSTCOND*/
0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = (head)->slh_first; \
while(curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
} \
} while (
/*CONSTCOND*/
0)
#define SLIST_FOREACH(var, head, field) \
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
/*
* Singly-linked List access methods.
*/
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first;
/* first element */
\
struct type **stqh_last;
/* addr of last next element */
\
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next;
/* next element */
\
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_INIT(head) do { \
(head)->stqh_first = NULL; \
(head)->stqh_last = &(head)->stqh_first; \
} while (
/*CONSTCOND*/
0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
(head)->stqh_last = &(elm)->field.stqe_next; \
(head)->stqh_first = (elm); \
} while (
/*CONSTCOND*/
0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.stqe_next = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &(elm)->field.stqe_next; \
} while (
/*CONSTCOND*/
0)
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
(head)->stqh_last = &(elm)->field.stqe_next; \
(listelm)->field.stqe_next = (elm); \
} while (
/*CONSTCOND*/
0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
(head)->stqh_last = &(head)->stqh_first; \
} while (
/*CONSTCOND*/
0)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if ((head)->stqh_first == (elm)) { \
STAILQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->stqh_first; \
while (curelm->field.stqe_next != (elm)) \
curelm = curelm->field.stqe_next; \
if ((curelm->field.stqe_next = \
curelm->field.stqe_next->field.stqe_next) == NULL) \
(head)->stqh_last = &(curelm)->field.stqe_next; \
} \
} while (
/*CONSTCOND*/
0)
#define STAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->stqh_first); \
(var); \
(var) = ((var)->field.stqe_next))
#define STAILQ_CONCAT(head1, head2) do { \
if (!STAILQ_EMPTY((head2))) { \
*(head1)->stqh_last = (head2)->stqh_first; \
(head1)->stqh_last = (head2)->stqh_last; \
STAILQ_INIT((head2)); \
} \
} while (
/*CONSTCOND*/
0)
/*
* Singly-linked Tail queue access methods.
*/
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first;
/* first element */
\
struct type **sqh_last;
/* addr of last next element */
\
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next;
/* next element */
\
}
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
if ((head)->sqh_first == (elm)) { \
SIMPLEQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->sqh_first; \
while (curelm->field.sqe_next != (elm)) \
curelm = curelm->field.sqe_next; \
if ((curelm->field.sqe_next = \
curelm->field.sqe_next->field.sqe_next) == NULL) \
(head)->sqh_last = &(curelm)->field.sqe_next; \
} \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->sqh_first); \
(var); \
(var) = ((var)->field.sqe_next))
/*
* Simple queue access methods.
*/
#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
/*
* Tail queue definitions.
*/
#define _TAILQ_HEAD(name, type, qual) \
struct name { \
qual type *tqh_first;
/* first element */
\
qual type *qual *tqh_last;
/* addr of last next element */
\
}
#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define _TAILQ_ENTRY(type, qual) \
struct { \
qual type *tqe_next;
/* next element */
\
qual type *qual *tqe_prev;
/* address of previous next element */
\
}
#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
/*
* Tail queue functions.
*/
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->tqh_first); \
(var); \
(var) = ((var)->field.tqe_next))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
(var); \
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
#define TAILQ_CONCAT(head1, head2, field) do { \
if (!TAILQ_EMPTY(head2)) { \
*(head1)->tqh_last = (head2)->tqh_first; \
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
(head1)->tqh_last = (head2)->tqh_last; \
TAILQ_INIT((head2)); \
} \
} while (
/*CONSTCOND*/
0)
/*
* Tail queue access methods.
*/
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
/*
* Circular queue definitions.
*/
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first;
/* first element */
\
struct type *cqh_last;
/* last element */
\
}
#define CIRCLEQ_HEAD_INITIALIZER(head) \
{ (void *)&head, (void *)&head }
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next;
/* next element */
\
struct type *cqe_prev;
/* previous element */
\
}
/*
* Circular queue functions.
*/
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = (void *)(head); \
(head)->cqh_last = (void *)(head); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = (void *)(head); \
if ((head)->cqh_last == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = (void *)(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->cqh_first); \
(var) != (const void *)(head); \
(var) = ((var)->field.cqe_next))
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for ((var) = ((head)->cqh_last); \
(var) != (const void *)(head); \
(var) = ((var)->field.cqe_prev))
/*
* Circular queue access methods.
*/
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
(((elm)->field.cqe_next == (void *)(head)) \
? ((head)->cqh_first) \
: (elm->field.cqe_next))
#define CIRCLEQ_LOOP_PREV(head, elm, field) \
(((elm)->field.cqe_prev == (void *)(head)) \
? ((head)->cqh_last) \
: (elm->field.cqe_prev))
#endif
/* sys/queue.h */
openair1/PHY/LTE_UE_TRANSPORT/sldch.c
View file @
7aa9a7bd
...
...
@@ -29,8 +29,6 @@
* \note
* \warning
*/
#ifndef __LTE_TRANSPORT_SLSS__C__
#define __LTE_TRANSPORT_SLSS__C__
#include "PHY/defs_UE.h"
extern
int
multicast_link_write_sock
(
int
groupP
,
char
*
dataP
,
uint32_t
sizeP
);
...
...
@@ -61,6 +59,3 @@ void generate_sldch(PHY_VARS_UE *ue,SLDCH_t *sldch,int frame_tx,int subframe_tx)
sldch_header_len
+
sizeof
(
SLDCH_t
));
}
#endif
openair1/PHY/LTE_UE_TRANSPORT/slsch.c
View file @
7aa9a7bd
...
...
@@ -29,8 +29,6 @@
* \note
* \warning
*/
#ifndef __LTE_TRANSPORT_SLSS__C__
#define __LTE_TRANSPORT_SLSS__C__
#include "PHY/defs_UE.h"
extern
int
...
...
@@ -66,5 +64,3 @@ void generate_slsch(PHY_VARS_UE *ue,SLSCH_t *slsch,int frame_tx,int subframe_tx)
}
}
#endif
openair1/PHY/LTE_UE_TRANSPORT/slss.c
View file @
7aa9a7bd
...
...
@@ -29,8 +29,6 @@
* \note
* \warning
*/
#ifndef __LTE_TRANSPORT_SLSS__C__
#define __LTE_TRANSPORT_SLSS__C__
#include "PHY/defs_UE.h"
...
...
@@ -39,5 +37,3 @@ void generate_slss(PHY_VARS_UE *ue,SLSS_t *slss,int frame_tx,int subframe_tx) {
AssertFatal
(
1
==
0
,
"Should get here yet for UE %d
\n
"
,
ue
->
Mod_id
);
}
#endif
openair1/PHY/NR_TRANSPORT/nr_transport_proto_common.h
View file @
7aa9a7bd
...
...
@@ -29,8 +29,8 @@
* \note
* \warning
*/
#ifndef __NR_TRANSPORT_PROTO_
UE
__H__
#define __NR_TRANSPORT_PROTO_
UE
__H__
#ifndef __NR_TRANSPORT_PROTO_
COMMON
__H__
#define __NR_TRANSPORT_PROTO_
COMMON
__H__
#include "PHY/defs_nr_UE.h"
#include "SCHED_NR_UE/defs.h"
//#include "PHY/LTE_TRANSPORT/transport_common_proto.h"
...
...
@@ -43,29 +43,6 @@
* @{
*/
/** \fn free_ue_dlsch(NR_UE_DLSCH_t *dlsch)
\brief This function frees memory allocated for a particular DLSCH at UE
@param dlsch Pointer to DLSCH to be removed
*/
void
free_nr_ue_dlsch
(
NR_UE_DLSCH_t
*
dlsch
);
/** \fn new_ue_dlsch(uint8_t Kmimo,uint8_t Mdlharq,uint32_t Nsoft,uint8_t abstraction_flag)
\brief This function allocates structures for a particular DLSCH at UE
@returns Pointer to DLSCH to be removed
@param Kmimo Kmimo factor from 36-212/36-213
@param Mdlharq Maximum number of HARQ rounds (36-212/36-213)
@param Nsoft Soft-LLR buffer size from UE-Category
@params N_RB_DL total number of resource blocks (determine the operating BW)
@param abstraction_flag Flag to indicate abstracted interface
*/
NR_UE_DLSCH_t
*
new_nr_ue_dlsch
(
uint8_t
Kmimo
,
uint8_t
Mdlharq
,
uint32_t
Nsoft
,
uint8_t
max_turbo_iterations
,
uint8_t
N_RB_DL
,
uint8_t
abstraction_flag
);
void
free_nr_ue_ulsch
(
NR_UE_ULSCH_t
*
ulsch
);
NR_UE_ULSCH_t
*
new_nr_ue_ulsch
(
unsigned
char
N_RB_UL
,
int
number_of_harq_pids
,
uint8_t
abstraction_flag
);
void
fill_UE_dlsch_MCH
(
PHY_VARS_NR_UE
*
ue
,
int
mcs
,
int
ndi
,
int
rvidx
,
int
eNB_id
);
int
rx_pmch
(
PHY_VARS_NR_UE
*
phy_vars_ue
,
...
...
@@ -1055,21 +1032,6 @@ int nr_ulsch_encoding(NR_UE_ULSCH_t *ulsch,
NR_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
harq_pid
);
/*! \brief Perform PUSCH scrambling. TS 38.211 V15.4.0 subclause 6.3.1.1
@param[in] in Pointer to input bits
@param[in] size of input bits
@param[in] Nid cell id
@param[in] n_RNTI CRNTI
@param[out] out the scrambled bits
*/
void
nr_pusch_codeword_scrambling
(
uint8_t
*
in
,
uint16_t
size
,
uint32_t
Nid
,
uint32_t
n_RNTI
,
uint32_t
*
out
);
uint32_t
nr_dlsch_decoding_mthread
(
PHY_VARS_NR_UE
*
phy_vars_ue
,
UE_nr_rxtx_proc_t
*
proc
,
int
eNB_id
,
...
...
@@ -1130,14 +1092,7 @@ int32_t nr_rx_pdsch(PHY_VARS_NR_UE *phy_vars_ue,
int32_t
nr_rx_pdcch
(
PHY_VARS_NR_UE
*
ue
,
uint32_t
frame
,
uint8_t
nr_tti_rx
,
uint8_t
eNB_id
,
MIMO_mode_t
mimo_mode
,
uint32_t
high_speed_flag
,
uint8_t
is_secondary_ue
,
int
nb_coreset_active
,
uint16_t
symbol_mon
,
NR_SEARCHSPACE_TYPE_t
searchSpaceType
);
uint32_t
slot
);
/*! \brief Extract PSS and SSS resource elements
@param phy_vars_ue Pointer to UE variables
...
...
@@ -1471,17 +1426,6 @@ void init_transport_channels(uint8_t);
void
generate_RIV_tables
(
void
);
/*!
\brief This function performs the initial cell search procedure - PSS detection, SSS detection and PBCH detection. At the
end, the basic frame parameters are known (Frame configuration - TDD/FDD and cyclic prefix length,
N_RB_DL, PHICH_CONFIG and Nid_cell) and the UE can begin decoding PDCCH and DLSCH SI to retrieve the rest. Once these
parameters are know, the routine calls some basic initialization routines (cell-specific reference signals, etc.)
@param phy_vars_ue Pointer to UE variables
@param mode current running mode
*/
int
nr_initial_sync
(
UE_nr_rxtx_proc_t
*
proc
,
PHY_VARS_NR_UE
*
phy_vars_ue
,
runmode_t
mode
);
/*!
\brief Encoding of PUSCH/ACK/RI/ACK from 36-212.
...
...
@@ -1724,10 +1668,6 @@ uint8_t get_prach_prb_offset(NR_DL_FRAME_PARMS *frame_parms,
uint8_t
n_ra_prboffset
,
uint8_t
tdd_mapindex
,
uint16_t
Nf
);
void
nr_pdcch_unscrambling
(
uint16_t
crnti
,
NR_DL_FRAME_PARMS
*
frame_parms
,
uint8_t
nr_tti_rx
,
int16_t
*
z
,
uint32_t
length
,
uint16_t
pdcch_DMRS_scrambling_id
,
int
do_common
);
uint32_t
lte_gold_generic
(
uint32_t
*
x1
,
uint32_t
*
x2
,
uint8_t
reset
);
int
nr_rx_pdsch
(
PHY_VARS_NR_UE
*
ue
,
...
...
openair1/PHY/phy_vars_nr_ue.h
View file @
7aa9a7bd
...
...
@@ -142,4 +142,4 @@ uint8_t scrambling_lut[65536*16] __attribute__((aligned(32)));
uint8_t
max_ldpc_iterations
=
4
;
uint8_t
max_turbo_iterations
=
4
;
#endif
/*__PHY_VARS_H__ */
#endif
openair1/PHY/phy_vars_ue.h
View file @
7aa9a7bd
...
...
@@ -19,8 +19,8 @@
* contact@openairinterface.org
*/
#ifndef __PHY_VARS_H__
#define __PHY_VARS_H__
#ifndef __PHY_VARS_
UE_
H__
#define __PHY_VARS_
UE_
H__
#include "PHY/types.h"
#include "PHY/defs_UE.h"
...
...
@@ -133,4 +133,4 @@ int16_t unscrambling_lut[65536*16] __attribute__((aligned(32)));
uint8_t
scrambling_lut
[
65536
*
16
]
__attribute__
((
aligned
(
32
)));
uint8_t
max_turbo_iterations
=
4
;
#endif
/*__PHY_VARS_H__ */
#endif
openair1/SCHED_NR_UE/phy_procedures_nr_ue.c
View file @
7aa9a7bd
...
...
@@ -86,17 +86,6 @@ char nr_mode_string[4][20] = {"NOT SYNCHED","PRACH","RAR","PUSCH"};
extern
double
cpuf
;
int32_t
nr_rx_pdcch
(
PHY_VARS_NR_UE
*
ue
,
uint32_t
frame
,
uint32_t
slot
);
uint8_t
nr_dci_decoding_procedure
(
PHY_VARS_NR_UE
*
ue
,
int
frame
,
int
nr_tti_rx
,
fapi_nr_dci_indication_t
*
dci_ind
);
/*
int nr_generate_ue_ul_dlsch_params_from_dci(PHY_VARS_NR_UE *ue,
uint8_t eNB_id,
...
...
openair1/SIMULATION/TOOLS/rangen_double.c
View file @
7aa9a7bd
...
...
@@ -67,8 +67,6 @@ void randominit(unsigned seed_init)
double
uniformrandom
(
void
)
{
#define a 1664525lu
#define mod 4294967296.0
/* is 2**32 */
int
j
;
...
...
openair3/M3AP/m3ap_MCE_handler.h
View file @
7aa9a7bd
...
...
@@ -19,15 +19,15 @@
* contact@openairinterface.org
*/
/*! \file m
2
ap_handler.h
* \brief m
2
ap handler procedures for eNB
/*! \file m
3
ap_handler.h
* \brief m
3
ap handler procedures for eNB
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M
2
AP_MCE_HANDLERS_H_
#define M
2
AP_MCE_HANDLERS_H_
#ifndef M
3
AP_MCE_HANDLERS_H_
#define M
3
AP_MCE_HANDLERS_H_
#include "m2ap_MCE_defs.h"
...
...
openair3/M3AP/m3ap_MME_generate_messages.h
View file @
7aa9a7bd
...
...
@@ -19,15 +19,15 @@
* contact@openairinterface.org
*/
/*! \file m
2
ap_MCE_generate_messages.h
* \brief m
2
ap procedures for MCE
/*! \file m
3
ap_MCE_generate_messages.h
* \brief m
3
ap procedures for MCE
* \author Javier Morgade <javier.morgade@ieee.org>
* \date 2019
* \version 0.1
*/
#ifndef M
2
AP_MCE_GENERATE_MESSAGES_H_
#define M
2
AP_MCE_GENERATE_MESSAGES_H_
#ifndef M
3
AP_MCE_GENERATE_MESSAGES_H_
#define M
3
AP_MCE_GENERATE_MESSAGES_H_
#include "m2ap_MCE_defs.h"
#include "m2ap_common.h"
...
...
openair3/NAS/COMMON/API/NETWORK/as_message.h
deleted
100644 → 0
View file @
07c8d000
/*
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the FreeBSD Project.
*/
/*****************************************************************************
Source as_message.h
Version 0.1
Date 2012/10/18
Product NAS stack
Subsystem Application Programming Interface
Author Frederic Maurel
Description Defines the messages supported by the Access Stratum sublayer
protocol (usually RRC and S1AP for E-UTRAN) and functions used
to encode and decode
*****************************************************************************/
#ifndef __AS_MESSAGE_H__
#define __AS_MESSAGE_H__
#include "commonDef.h"
#include "networkDef.h"
/****************************************************************************/
/********************* G L O B A L C O N S T A N T S *******************/
/****************************************************************************/
/*
* --------------------------------------------------------------------------
* Access Stratum message types
* --------------------------------------------------------------------------
*/
#define AS_REQUEST 0x0100
#define AS_RESPONSE 0x0200
#define AS_INDICATION 0x0400
#define AS_CONFIRM 0x0800
/*
* --------------------------------------------------------------------------
* Access Stratum message identifiers
* --------------------------------------------------------------------------
*/
/* Broadcast information */
#define AS_BROADCAST_INFO 0x01
#define AS_BROADCAST_INFO_IND (AS_BROADCAST_INFO | AS_INDICATION)
/* Cell information relevant for cell selection processing */
#define AS_CELL_INFO 0x02
#define AS_CELL_INFO_REQ (AS_CELL_INFO | AS_REQUEST)
#define AS_CELL_INFO_CNF (AS_CELL_INFO | AS_CONFIRM)
#define AS_CELL_INFO_IND (AS_CELL_INFO | AS_INDICATION)
/* Paging information */
#define AS_PAGING 0x03
#define AS_PAGING_REQ (AS_PAGING | AS_REQUEST)
#define AS_PAGING_IND (AS_PAGING | AS_INDICATION)
/* NAS signalling connection establishment */
#define AS_NAS_ESTABLISH 0x04
#define AS_NAS_ESTABLISH_REQ (AS_NAS_ESTABLISH | AS_REQUEST)
#define AS_NAS_ESTABLISH_IND (AS_NAS_ESTABLISH | AS_INDICATION)
#define AS_NAS_ESTABLISH_RSP (AS_NAS_ESTABLISH | AS_RESPONSE)
#define AS_NAS_ESTABLISH_CNF (AS_NAS_ESTABLISH | AS_CONFIRM)
/* NAS signalling connection release */
#define AS_NAS_RELEASE 0x05
#define AS_NAS_RELEASE_REQ (AS_NAS_RELEASE | AS_REQUEST)
#define AS_NAS_RELEASE_IND (AS_NAS_RELEASE | AS_INDICATION)
/* Uplink information transfer */
#define AS_UL_INFO_TRANSFER 0x06
#define AS_UL_INFO_TRANSFER_REQ (AS_UL_INFO_TRANSFER | AS_REQUEST)
#define AS_UL_INFO_TRANSFER_CNF (AS_UL_INFO_TRANSFER | AS_CONFIRM)
#define AS_UL_INFO_TRANSFER_IND (AS_UL_INFO_TRANSFER | AS_INDICATION)
/* Downlink information transfer */
#define AS_DL_INFO_TRANSFER 0x07
#define AS_DL_INFO_TRANSFER_REQ (AS_DL_INFO_TRANSFER | AS_REQUEST)
#define AS_DL_INFO_TRANSFER_CNF (AS_DL_INFO_TRANSFER | AS_CONFIRM)
#define AS_DL_INFO_TRANSFER_IND (AS_DL_INFO_TRANSFER | AS_INDICATION)
/* Radio Access Bearer establishment */
#define AS_RAB_ESTABLISH 0x08
#define AS_RAB_ESTABLISH_REQ (AS_RAB_ESTABLISH | AS_REQUEST)
#define AS_RAB_ESTABLISH_IND (AS_RAB_ESTABLISH | AS_INDICATION)
#define AS_RAB_ESTABLISH_RSP (AS_RAB_ESTABLISH | AS_RESPONSE)
#define AS_RAB_ESTABLISH_CNF (AS_RAB_ESTABLISH | AS_CONFIRM)
/* Radio Access Bearer release */
#define AS_RAB_RELEASE 0x09
#define AS_RAB_RELEASE_REQ (AS_RAB_RELEASE | AS_REQUEST)
#define AS_RAB_RELEASE_IND (AS_RAB_RELEASE | AS_INDICATION)
/* NAS Cause */
#define EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED (8)
#define EPS_SERVICES_NOT_ALLOWED (7)
#define PLMN_NOT_ALLOWED (11)
#define TRACKING_AREA_NOT_ALLOWED (12)
#define ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA (13)
#define EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN (14)
#define NO_SUITABLE_CELLS_IN_TRACKING_AREA (15)
#define NETWORK_FAILURE (17)
#define ESM_FAILURE (19)
typedef
enum
nas_cause_s
{
NAS_CAUSE_EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED
=
EPS_SERVICES_AND_NON_EPS_SERVICES_NOT_ALLOWED
,
NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED
=
EPS_SERVICES_NOT_ALLOWED
,
NAS_CAUSE_PLMN_NOT_ALLOWED
=
PLMN_NOT_ALLOWED
,
NAS_CAUSE_TRACKING_AREA_NOT_ALLOWED
=
TRACKING_AREA_NOT_ALLOWED
,
NAS_CAUSE_ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA
=
ROAMING_NOT_ALLOWED_IN_THIS_TRACKING_AREA
,
NAS_CAUSE_EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN
=
EPS_SERVICES_NOT_ALLOWED_IN_THIS_PLMN
,
NAS_CAUSE_NO_SUITABLE_CELLS_IN_TRACKING_AREA
=
NO_SUITABLE_CELLS_IN_TRACKING_AREA
,
NAS_CAUSE_NETWORK_FAILURE
=
NETWORK_FAILURE
,
NAS_CAUSE_ESM_FAILURE
=
ESM_FAILURE
}
nas_cause_t
;
/*
* --------------------------------------------------------------------------
* Access Stratum message global parameters
* --------------------------------------------------------------------------
*/
/* Error code */
typedef
enum
nas_error_code_s
{
AS_SUCCESS
=
1
,
/* Success code, transaction is going on */
AS_TERMINATED_NAS
,
/* Transaction terminated by NAS */
AS_TERMINATED_AS
,
/* Transaction terminated by AS */
AS_FAILURE
/* Failure code */
}
nas_error_code_t
;
/* Core network domain */
typedef
enum
core_network_s
{
AS_PS
=
1
,
/* Packet-Switched */
AS_CS
/* Circuit-Switched */
}
core_network_t
;
/* SAE Temporary Mobile Subscriber Identity */
typedef
struct
as_stmsi_s
{
uint8_t
MMEcode
;
/* MME code that allocated the GUTI */
uint32_t
m_tmsi
;
/* M-Temporary Mobile Subscriber Identity */
}
as_stmsi_t
;
/* Dedicated NAS information */
typedef
struct
as_nas_info_s
{
uint32_t
length
;
/* Length of the NAS information data */
Byte_t
*
data
;
/* Dedicated NAS information data container */
}
as_nas_info_t
;
/* Radio Access Bearer identity */
typedef
uint8_t
as_rab_id_t
;
/****************************************************************************/
/************************ G L O B A L T Y P E S ************************/
/****************************************************************************/
/*
* --------------------------------------------------------------------------
* Broadcast information
* --------------------------------------------------------------------------
*/
/*
* AS->NAS - Broadcast information indication
* AS may asynchronously report to NAS available PLMNs within specific
* location area
*/
typedef
struct
broadcast_info_ind_s
{
#define PLMN_LIST_MAX_SIZE 6
PLMN_LIST_T
(
PLMN_LIST_MAX_SIZE
)
plmnIDs
;
/* List of PLMN identifiers */
ci_t
cellID
;
/* Identity of the cell serving the listed PLMNs */
tac_t
tac
;
/* Code of the tracking area the cell belongs to */
}
broadcast_info_ind_t
;
/*
* --------------------------------------------------------------------------
* Cell information relevant for cell selection processing
* --------------------------------------------------------------------------
*/
/* Radio access technologies supported by the network */
#define AS_GSM (1 << NET_ACCESS_GSM)
#define AS_COMPACT (1 << NET_ACCESS_COMPACT)
#define AS_UTRAN (1 << NET_ACCESS_UTRAN)
#define AS_EGPRS (1 << NET_ACCESS_EGPRS)
#define AS_HSDPA (1 << NET_ACCESS_HSDPA)
#define AS_HSUPA (1 << NET_ACCESS_HSUPA)
#define AS_HSDUPA (1 << NET_ACCESS_HSDUPA)
#define AS_EUTRAN (1 << NET_ACCESS_EUTRAN)
/*
* NAS->AS - Cell Information request
* NAS request AS to search for a suitable cell belonging to the selected
* PLMN to camp on.
*/
typedef
struct
cell_info_req_s
{
plmn_t
plmnID
;
/* Selected PLMN identity */
Byte_t
rat
;
/* Bitmap - set of radio access technologies */
}
cell_info_req_t
;
/*
* AS->NAS - Cell Information confirm
* AS search for a suitable cell and respond to NAS. If found, the cell
* is selected to camp on.
*/
typedef
struct
cell_info_cnf_s
{
uint8_t
errCode
;
/* Error code */
ci_t
cellID
;
/* Identity of the cell serving the selected PLMN */
tac_t
tac
;
/* Code of the tracking area the cell belongs to */
AcT_t
rat
;
/* Radio access technology supported by the cell */
uint8_t
rsrq
;
/* Reference signal received quality */
uint8_t
rsrp
;
/* Reference signal received power */
}
cell_info_cnf_t
;
/*
* AS->NAS - Cell Information indication
* AS may change cell selection if a more suitable cell is found.
*/
typedef
struct
cell_info_ind_s
{
ci_t
cellID
;
/* Identity of the new serving cell */
tac_t
tac
;
/* Code of the tracking area the cell belongs to */
}
cell_info_ind_t
;
/*
* --------------------------------------------------------------------------
* Paging information
* --------------------------------------------------------------------------
*/
/* Paging cause */
typedef
enum
paging_cause_s
{
AS_CONNECTION_ESTABLISH
,
/* Establish NAS signalling connection */
AS_EPS_ATTACH
,
/* Perform local detach and initiate EPS
* attach procedure */
AS_CS_FALLBACK
/* Inititate CS fallback procedure */
}
paging_cause_t
;
/*
* NAS->AS - Paging Information request
* NAS requests the AS that NAS signalling messages or user data is pending
* to be sent.
*/
typedef
struct
paging_req_s
{
as_stmsi_t
s_tmsi
;
/* UE identity */
uint8_t
CN_domain
;
/* Core network domain */
}
paging_req_t
;
/*
* AS->NAS - Paging Information indication
* AS reports to the NAS that appropriate procedure has to be initiated.
*/
typedef
struct
paging_ind_s
{
paging_cause_t
cause
;
/* Paging cause */
}
paging_ind_t
;
/*
* --------------------------------------------------------------------------
* NAS signalling connection establishment
* --------------------------------------------------------------------------
*/
/* Cause of RRC connection establishment */
typedef
enum
as_cause_s
{
AS_CAUSE_UNKNOWN
=
0
,
AS_CAUSE_EMERGENCY
=
NET_ESTABLISH_CAUSE_EMERGENCY
,
AS_CAUSE_HIGH_PRIO
=
NET_ESTABLISH_CAUSE_HIGH_PRIO
,
AS_CAUSE_MT_ACCESS
=
NET_ESTABLISH_CAUSE_MT_ACCESS
,
AS_CAUSE_MO_SIGNAL
=
NET_ESTABLISH_CAUSE_MO_SIGNAL
,
AS_CAUSE_MO_DATA
=
NET_ESTABLISH_CAUSE_MO_DATA
,
AS_CAUSE_V1020
=
NET_ESTABLISH_CAUSE_V1020
}
as_cause_t
;
/* Type of the call associated to the RRC connection establishment */
typedef
enum
as_call_type_s
{
AS_TYPE_ORIGINATING_SIGNAL
=
NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL
,
AS_TYPE_EMERGENCY_CALLS
=
NET_ESTABLISH_TYPE_EMERGENCY_CALLS
,
AS_TYPE_ORIGINATING_CALLS
=
NET_ESTABLISH_TYPE_ORIGINATING_CALLS
,
AS_TYPE_TERMINATING_CALLS
=
NET_ESTABLISH_TYPE_TERMINATING_CALLS
,
AS_TYPE_MO_CS_FALLBACK
=
NET_ESTABLISH_TYPE_MO_CS_FALLBACK
}
as_call_type_t
;
/*
* NAS->AS - NAS signalling connection establishment request
* NAS requests the AS to perform the RRC connection establishment procedure
* to transfer initial NAS message to the network while UE is in IDLE mode.
*/
typedef
struct
nas_establish_req_s
{
as_cause_t
cause
;
/* RRC connection establishment cause */
as_call_type_t
type
;
/* RRC associated call type */
as_stmsi_t
s_tmsi
;
/* UE identity */
plmn_t
plmnID
;
/* Selected PLMN identity */
as_nas_info_t
initialNasMsg
;
/* Initial NAS message to transfer */
}
nas_establish_req_t
;
/*
* AS->NAS - NAS signalling connection establishment indication
* AS transfers the initial NAS message to the NAS.
*/
typedef
struct
nas_establish_ind_s
{
uint32_t
UEid
;
/* UE lower layer identifier */
tac_t
tac
;
/* Code of the tracking area the initiating
* UE belongs to */
as_cause_t
asCause
;
/* Establishment cause */
as_nas_info_t
initialNasMsg
;
/* Initial NAS message to transfer */
}
nas_establish_ind_t
;
/*
* NAS->AS - NAS signalling connection establishment response
* NAS responds to the AS that initial answer message has to be provided to
* the UE.
*/
typedef
struct
nas_establish_rsp_s
{
uint32_t
UEid
;
/* UE lower layer identifier */
as_stmsi_t
s_tmsi
;
/* UE identity */
nas_error_code_t
errCode
;
/* Transaction status */
as_nas_info_t
nasMsg
;
/* NAS message to transfer */
uint32_t
nas_ul_count
;
/* UL NAS COUNT */
uint16_t
selected_encryption_algorithm
;
uint16_t
selected_integrity_algorithm
;
}
nas_establish_rsp_t
;
/*
* AS->NAS - NAS signalling connection establishment confirm
* AS transfers the initial answer message to the NAS.
*/
typedef
struct
nas_establish_cnf_s
{
uint32_t
UEid
;
/* UE lower layer identifier */
nas_error_code_t
errCode
;
/* Transaction status */
as_nas_info_t
nasMsg
;
/* NAS message to transfer */
uint32_t
ul_nas_count
;
uint16_t
selected_encryption_algorithm
;
uint16_t
selected_integrity_algorithm
;
}
nas_establish_cnf_t
;
/*
* --------------------------------------------------------------------------
* NAS signalling connection release
* --------------------------------------------------------------------------
*/
/* Release cause */
typedef
enum
release_cause_s
{
AS_AUTHENTICATION_FAILURE
=
1
,
/* Authentication procedure failed */
AS_DETACH
/* Detach requested */
}
release_cause_t
;
/*
* NAS->AS - NAS signalling connection release request
* NAS requests the termination of the connection with the UE.
*/
typedef
struct
nas_release_req_s
{
uint32_t
UEid
;
/* UE lower layer identifier */
as_stmsi_t
s_tmsi
;
/* UE identity */
release_cause_t
cause
;
/* Release cause */
}
nas_release_req_t
;
/*
* AS->NAS - NAS signalling connection release indication
* AS reports that connection has been terminated by the network.
*/
typedef
struct
nas_release_ind_s
{
release_cause_t
cause
;
/* Release cause */
}
nas_release_ind_t
;
/*
* --------------------------------------------------------------------------
* NAS information transfer
* --------------------------------------------------------------------------
*/
/*
* NAS->AS - Uplink data transfer request
* NAS requests the AS to transfer uplink information to the NAS that
* operates at the network side.
*/
typedef
struct
ul_info_transfer_req_s
{
uint32_t
UEid
;
/* UE lower layer identifier */
as_stmsi_t
s_tmsi
;
/* UE identity */
as_nas_info_t
nasMsg
;
/* Uplink NAS message */
}
ul_info_transfer_req_t
;
/*
* AS->NAS - Uplink data transfer confirm
* AS immediately notifies the NAS whether uplink information has been
* successfully sent to the network or not.
*/
typedef
struct
ul_info_transfer_cnf_s
{
uint32_t
UEid
;
/* UE lower layer identifier */
nas_error_code_t
errCode
;
/* Transaction status */
}
ul_info_transfer_cnf_t
;
/*
* AS->NAS - Uplink data transfer indication
* AS delivers the uplink information message to the NAS that operates
* at the network side.
*/
typedef
struct
ul_info_transfer_ind_s
{
uint32_t
UEid
;
/* UE lower layer identifier */
as_nas_info_t
nasMsg
;
/* Uplink NAS message */
}
ul_info_transfer_ind_t
;
/*
* NAS->AS - Downlink data transfer request
* NAS requests the AS to transfer downlink information to the NAS that
* operates at the UE side.
*/
typedef
ul_info_transfer_req_t
dl_info_transfer_req_t
;
/*
* AS->NAS - Downlink data transfer confirm
* AS immediately notifies the NAS whether downlink information has been
* successfully sent to the network or not.
*/
typedef
ul_info_transfer_cnf_t
dl_info_transfer_cnf_t
;
/*
* AS->NAS - Downlink data transfer indication
* AS delivers the downlink information message to the NAS that operates
* at the UE side.
*/
typedef
ul_info_transfer_ind_t
dl_info_transfer_ind_t
;
/*
* --------------------------------------------------------------------------
* Radio Access Bearer establishment
* --------------------------------------------------------------------------
*/
/* TODO: Quality of Service parameters */
typedef
struct
{}
as_qos_t
;
/*
* NAS->AS - Radio access bearer establishment request
* NAS requests the AS to allocate transmission resources to radio access
* bearer initialized at the network side.
*/
typedef
struct
rab_establish_req_s
{
as_stmsi_t
s_tmsi
;
/* UE identity */
as_rab_id_t
rabID
;
/* Radio access bearer identity */
as_qos_t
QoS
;
/* Requested Quality of Service */
}
rab_establish_req_t
;
/*
* AS->NAS - Radio access bearer establishment indication
* AS notifies the NAS that specific radio access bearer has to be setup.
*/
typedef
struct
rab_establish_ind_s
{
as_rab_id_t
rabID
;
/* Radio access bearer identity */
}
rab_establish_ind_t
;
/*
* NAS->AS - Radio access bearer establishment response
* NAS responds to AS whether the specified radio access bearer has been
* successfully setup or not.
*/
typedef
struct
rab_establish_rsp_s
{
as_stmsi_t
s_tmsi
;
/* UE identity */
as_rab_id_t
rabID
;
/* Radio access bearer identity */
nas_error_code_t
errCode
;
/* Transaction status */
}
rab_establish_rsp_t
;
/*
* AS->NAS - Radio access bearer establishment confirm
* AS notifies NAS whether the specified radio access bearer has been
* successfully setup at the UE side or not.
*/
typedef
struct
rab_establish_cnf_s
{
as_rab_id_t
rabID
;
/* Radio access bearer identity */
nas_error_code_t
errCode
;
/* Transaction status */
}
rab_establish_cnf_t
;
/*
* --------------------------------------------------------------------------
* Radio Access Bearer release
* --------------------------------------------------------------------------
*/
/*
* NAS->AS - Radio access bearer release request
* NAS requests the AS to release transmission resources previously allocated
* to specific radio access bearer at the network side.
*/
typedef
struct
rab_release_req_s
{
as_stmsi_t
s_tmsi
;
/* UE identity */
as_rab_id_t
rabID
;
/* Radio access bearer identity */
}
rab_release_req_t
;
/*
* AS->NAS - Radio access bearer release indication
* AS notifies NAS that specific radio access bearer has been released.
*/
typedef
struct
rab_release_ind_s
{
as_rab_id_t
rabID
;
/* Radio access bearer identity */
}
rab_release_ind_t
;
/*
* --------------------------------------------------------------------------
* Structure of the AS messages handled by the network sublayer
* --------------------------------------------------------------------------
*/
typedef
struct
as_message_s
{
uint16_t
msgID
;
union
{
broadcast_info_ind_t
broadcast_info_ind
;
cell_info_req_t
cell_info_req
;
cell_info_cnf_t
cell_info_cnf
;
cell_info_ind_t
cell_info_ind
;
paging_req_t
paging_req
;
paging_ind_t
paging_ind
;
nas_establish_req_t
nas_establish_req
;
nas_establish_ind_t
nas_establish_ind
;
nas_establish_rsp_t
nas_establish_rsp
;
nas_establish_cnf_t
nas_establish_cnf
;
nas_release_req_t
nas_release_req
;
nas_release_ind_t
nas_release_ind
;
ul_info_transfer_req_t
ul_info_transfer_req
;
ul_info_transfer_cnf_t
ul_info_transfer_cnf
;
ul_info_transfer_ind_t
ul_info_transfer_ind
;
dl_info_transfer_req_t
dl_info_transfer_req
;
dl_info_transfer_cnf_t
dl_info_transfer_cnf
;
dl_info_transfer_ind_t
dl_info_transfer_ind
;
rab_establish_req_t
rab_establish_req
;
rab_establish_ind_t
rab_establish_ind
;
rab_establish_rsp_t
rab_establish_rsp
;
rab_establish_cnf_t
rab_establish_cnf
;
rab_release_req_t
rab_release_req
;
rab_release_ind_t
rab_release_ind
;
}
__attribute__
((
__packed__
))
msg
;
}
as_message_t
;
/****************************************************************************/
/******************** G L O B A L V A R I A B L E S ********************/
/****************************************************************************/
/****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/
int
as_message_decode
(
const
char
*
buffer
,
as_message_t
*
msg
,
int
length
);
int
as_message_encode
(
char
*
buffer
,
as_message_t
*
msg
,
int
length
);
/* Implemented in the network_api.c body file */
int
as_message_send
(
as_message_t
*
as_msg
);
#endif
/* __AS_MESSAGE_H__*/
openair3/NAS/COMMON/commonDef.h
deleted
100644 → 0
View file @
07c8d000
/*
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the FreeBSD Project.
*/
/*
Source commonDef.h
Version 0.1
Date 2012/02/27
Product NAS stack
Subsystem include
Author Frederic Maurel
Description Contains global common definitions
*****************************************************************************/
#ifndef __COMMONDEF_H__
#define __COMMONDEF_H__
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>
typedef
signed
char
boolean_t
;
#if !defined(TRUE)
#define TRUE (boolean_t)0x01
#endif
#if !defined(FALSE)
#define FALSE (boolean_t)0x00
#endif
#define BOOL_NOT(b) (b^TRUE)
#define NAS_UE_ID_FMT "0x%06x"
/****************************************************************************/
/********************* G L O B A L C O N S T A N T S *******************/
/****************************************************************************/
#define RETURNok (0)
#define RETURNerror (-1)
/*
* Name of the environment variable which defines the default directory
* where the NAS application is executed and where are located files
* where non-volatile data are stored
*/
#define DEFAULT_NAS_PATH "PWD"
/****************************************************************************/
/************************ G L O B A L T Y P E S ************************/
/****************************************************************************/
/*
-----------------------------------------------------------------------------
Standard data type definitions
-----------------------------------------------------------------------------
*/
typedef
int8_t
SByte_t
;
/* 8 bit signed integer */
typedef
uint8_t
Byte_t
;
/* 8 bit unsigned integer */
/*
-----------------------------------------------------------------------------
Common NAS data type definitions
-----------------------------------------------------------------------------
*/
typedef
uint8_t
Stat_t
;
/* Registration status */
typedef
uint16_t
lac_t
;
/* Location Area Code */
typedef
uint8_t
rac_t
;
/* Routing Area Code */
typedef
uint16_t
tac_t
;
/* Tracking Area Code */
typedef
uint32_t
ci_t
;
/* Cell Identifier */
typedef
uint8_t
AcT_t
;
/* Access Technology */
/*
* International Mobile Subscriber Identity
*/
typedef
struct
{
Byte_t
length
;
union
{
struct
{
Byte_t
digit2
:
4
;
Byte_t
digit1
:
4
;
Byte_t
digit4
:
4
;
Byte_t
digit3
:
4
;
Byte_t
digit6
:
4
;
Byte_t
digit5
:
4
;
Byte_t
digit8
:
4
;
Byte_t
digit7
:
4
;
Byte_t
digit10
:
4
;
Byte_t
digit9
:
4
;
Byte_t
digit12
:
4
;
Byte_t
digit11
:
4
;
Byte_t
digit14
:
4
;
Byte_t
digit13
:
4
;
#define EVEN_PARITY 0
#define ODD_PARITY 1
Byte_t
parity
:
4
;
Byte_t
digit15
:
4
;
}
num
;
#define IMSI_SIZE 8
Byte_t
value
[
IMSI_SIZE
];
}
u
;
}
imsi_t
;
#define NAS_IMSI2STR(iMsI_t_PtR,iMsI_sTr, MaXlEn) \
{\
int l_offset = 0;\
int l_ret = 0;\
l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u%u%u%u%u",\
iMsI_t_PtR->u.num.digit1, iMsI_t_PtR->u.num.digit2,\
iMsI_t_PtR->u.num.digit3, iMsI_t_PtR->u.num.digit4,\
iMsI_t_PtR->u.num.digit5);\
if ((iMsI_t_PtR->u.num.digit6 != 0xf) && (l_ret > 0)) {\
l_offset += l_ret;\
l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u", iMsI_t_PtR->u.num.digit6);\
}\
if (l_ret > 0) {\
l_offset += l_ret;\
l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u%u%u%u%u%u%u%u",\
iMsI_t_PtR->u.num.digit7, iMsI_t_PtR->u.num.digit8,\
iMsI_t_PtR->u.num.digit9, iMsI_t_PtR->u.num.digit10,\
iMsI_t_PtR->u.num.digit11, iMsI_t_PtR->u.num.digit12,\
iMsI_t_PtR->u.num.digit13, iMsI_t_PtR->u.num.digit14);\
}\
if ((iMsI_t_PtR->u.num.digit15 != 0xf) && (l_ret > 0)) {\
l_offset += l_ret;\
l_ret = snprintf(iMsI_sTr + l_offset, MaXlEn - l_offset, "%u", iMsI_t_PtR->u.num.digit15);\
}\
}
/*
* Mobile subscriber dialing number
*/
typedef
struct
{
Byte_t
ext
:
1
;
/* Type Of Number */
#define MSISDN_TON_UNKNOWKN 0b000
#define MSISDN_TON_INTERNATIONAL 0b001
#define MSISDN_TON_NATIONAL 0b010
#define MSISDN_TON_NETWORK 0b011
#define MSISDN_TON_SUBCRIBER 0b100
#define MSISDN_TON_ABBREVIATED 0b110
#define MSISDN_TON_RESERVED 0b111
Byte_t
ton
:
3
;
/* Numbering Plan Identification */
#define MSISDN_NPI_UNKNOWN 0b0000
#define MSISDN_NPI_ISDN_TELEPHONY 0b0001
#define MSISDN_NPI_GENERIC 0b0010
#define MSISDN_NPI_DATA 0b0011
#define MSISDN_NPI_TELEX 0b0100
#define MSISDN_NPI_MARITIME_MOBILE 0b0101
#define MSISDN_NPI_LAND_MOBILE 0b0110
#define MSISDN_NPI_ISDN_MOBILE 0b0111
#define MSISDN_NPI_PRIVATE 0b1110
#define MSISDN_NPI_RESERVED 0b1111
Byte_t
npi
:
4
;
/* Dialing Number */
struct
{
Byte_t
lsb
:
4
;
Byte_t
msb
:
4
;
#define MSISDN_DIGIT_SIZE 10
}
digit
[
MSISDN_DIGIT_SIZE
];
}
msisdn_t
;
/*
* International Mobile Equipment Identity
*/
typedef
imsi_t
imei_t
;
/*
* Public Land Mobile Network identifier
* PLMN = BCD encoding (Mobile Country Code + Mobile Network Code)
*/
typedef
struct
{
Byte_t
MCCdigit2
:
4
;
Byte_t
MCCdigit1
:
4
;
Byte_t
MNCdigit3
:
4
;
Byte_t
MCCdigit3
:
4
;
Byte_t
MNCdigit2
:
4
;
Byte_t
MNCdigit1
:
4
;
}
plmn_t
;
/*
* Location Area Identification
*/
typedef
struct
{
plmn_t
plmn
;
/* <MCC> + <MNC> */
lac_t
lac
;
/* Location Area Code */
}
lai_t
;
/*
* GPRS Routing Area Identification
*/
typedef
struct
{
plmn_t
plmn
;
/* <MCC> + <MNC> */
lac_t
lac
;
/* Location Area Code */
rac_t
rac
;
/* Routing Area Code */
}
RAI_t
;
/*
* EPS Tracking Area Identification
*/
typedef
struct
{
plmn_t
plmn
;
/* <MCC> + <MNC> */
tac_t
tac
;
/* Tracking Area Code */
}
tai_t
;
/*
* EPS Globally Unique MME Identity
*/
typedef
struct
{
plmn_t
plmn
;
/* <MCC> + <MNC> */
uint16_t
MMEgid
;
/* MME group identifier */
uint8_t
MMEcode
;
/* MME code */
}
gummei_t
;
/*
* EPS Globally Unique Temporary UE Identity
*/
typedef
struct
{
gummei_t
gummei
;
/* Globally Unique MME Identity */
uint32_t
m_tmsi
;
/* M-Temporary Mobile Subscriber Identity */
}
GUTI_t
;
#define GUTI2STR(GuTi_PtR, GuTi_StR, MaXlEn) \
{\
int l_offset = 0;\
int l_ret = 0;\
l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%03u.",\
GuTi_PtR->gummei.plmn.MCCdigit3 * 100 +\
GuTi_PtR->gummei.plmn.MCCdigit2 * 10 +\
GuTi_PtR->gummei.plmn.MCCdigit1);\
if (l_ret > 0) {\
l_offset += l_ret;\
} else {\
l_offset = MaXlEn;\
}\
if (GuTi_PtR->gummei.plmn.MNCdigit1 != 0xf) {\
l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%03u|%04x|%02x|%08x",\
GuTi_PtR->gummei.plmn.MNCdigit3 * 100 +\
GuTi_PtR->gummei.plmn.MNCdigit2 * 10 +\
GuTi_PtR->gummei.plmn.MNCdigit1,\
GuTi_PtR->gummei.MMEgid,\
GuTi_PtR->gummei.MMEcode,\
GuTi_PtR->m_tmsi);\
} else {\
l_ret += snprintf(GuTi_StR + l_offset,MaXlEn-l_offset, "%02u|%04x|%02x|%08x",\
GuTi_PtR->gummei.plmn.MNCdigit2 * 10 +\
GuTi_PtR->gummei.plmn.MNCdigit1,\
GuTi_PtR->gummei.MMEgid,\
GuTi_PtR->gummei.MMEcode,\
GuTi_PtR->m_tmsi);\
}\
}
/* Checks PLMN validity */
#define PLMN_IS_VALID(plmn) (((plmn).MCCdigit1 & \
(plmn).MCCdigit2 & \
(plmn).MCCdigit3) != 0x0F)
/* Checks TAC validity */
#define TAC_IS_VALID(tac) (((tac) != 0x0000) && ((tac) != 0xFFF0))
/* Checks TAI validity */
#define TAI_IS_VALID(tai) (PLMN_IS_VALID((tai).plmn) && \
TAC_IS_VALID((tai).tac))
/*
* A list of PLMNs
*/
#define PLMN_LIST_T(SIZE) struct {Byte_t n_plmns; plmn_t plmn[SIZE];}
/*
* A list of TACs
*/
#define TAC_LIST_T(SIZE) struct {Byte_t n_tacs; TAC_t tac[SIZE];}
/*
* A list of TAIs
*/
#define TAI_LIST_T(SIZE) struct {Byte_t n_tais; tai_t tai[SIZE];}
typedef
enum
eps_protocol_discriminator_e
{
/* Protocol discriminator identifier for EPS Mobility Management */
EPS_MOBILITY_MANAGEMENT_MESSAGE
=
0x7
,
/* Protocol discriminator identifier for EPS Session Management */
EPS_SESSION_MANAGEMENT_MESSAGE
=
0x2
,
}
eps_protocol_discriminator_t
;
/****************************************************************************/
/******************** G L O B A L V A R I A B L E S ********************/
/****************************************************************************/
/****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/
#endif
/* __COMMONDEF_H__*/
openair3/NAS/COMMON/networkDef.h
deleted
100644 → 0
View file @
07c8d000
/*
* Copyright (c) 2015, EURECOM (www.eurecom.fr)
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice, this
* list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* The views and conclusions contained in the software and documentation are those
* of the authors and should not be interpreted as representing official policies,
* either expressed or implied, of the FreeBSD Project.
*/
/*****************************************************************************
Source networkDef.h
Version 0.1
Date 2012/09/21
Product NAS stack
Subsystem include
Author Frederic Maurel
Description Contains network's global definitions
*****************************************************************************/
#ifndef __NETWORKDEF_H__
#define __NETWORKDEF_H__
/****************************************************************************/
/********************* G L O B A L C O N S T A N T S *******************/
/****************************************************************************/
/*
* ----------------------
* Network selection mode
* ----------------------
*/
#define NET_PLMN_AUTO 0
#define NET_PLMN_MANUAL 1
/*
* ---------------------------
* Network registration status
* ---------------------------
*/
/* not registered, not currently searching an operator to register to */
#define NET_REG_STATE_OFF 0
/* registered, home network */
#define NET_REG_STATE_HN 1
/* not registered, currently trying to attach or searching an operator
* to register to */
#define NET_REG_STATE_ON 2
/* registration denied */
#define NET_REG_STATE_DENIED 3
/* unknown (e.g. out of GERAN/UTRAN/E-UTRAN coverage) */
#define NET_REG_STATE_UNKNOWN 4
/* registered, roaming */
#define NET_REG_STATE_ROAMING 5
/* registered for "SMS only", home network */
#define NET_REG_STATE_SMS_HN 6
/* registered, for "SMS only", roaming */
#define NET_REG_STATE_SMS_ROAMING 7
/* attached for emergency bearer services only (applicable to UTRAN) */
#define NET_REG_STATE_EMERGENCY 8
/*
* ------------------------------------
* Network access technology indicators
* ------------------------------------
*/
#define NET_ACCESS_UNAVAILABLE (-1)
/* Not available */
#define NET_ACCESS_GSM 0
/* GSM */
#define NET_ACCESS_COMPACT 1
/* GSM Compact */
#define NET_ACCESS_UTRAN 2
/* UTRAN */
#define NET_ACCESS_EGPRS 3
/* GSM w/EGPRS */
#define NET_ACCESS_HSDPA 4
/* UTRAN w/HSDPA */
#define NET_ACCESS_HSUPA 5
/* UTRAN w/HSUPA */
#define NET_ACCESS_HSDUPA 6
/* UTRAN w/HSDPA and HSUPA */
#define NET_ACCESS_EUTRAN 7
/* E-UTRAN */
/*
* ---------------------------------------
* Network operator representation formats
* ---------------------------------------
*/
#define NET_FORMAT_LONG 0
/* long format alphanumeric */
#define NET_FORMAT_SHORT 1
/* short format alphanumeric */
#define NET_FORMAT_NUM 2
/* numeric format */
#define NET_FORMAT_MAX_SIZE NET_FORMAT_LONG_SIZE
/*
* -----------------------------
* Network operator availability
* -----------------------------
*/
#define NET_OPER_UNKNOWN 0
/* unknown operator */
#define NET_OPER_AVAILABLE 1
/* available operator */
#define NET_OPER_CURRENT 2
/* currently selected operator */
#define NET_OPER_FORBIDDEN 3
/* forbidden operator */
/*
* --------------------------------------
* Network connection establishment cause
* --------------------------------------
*/
#define NET_ESTABLISH_CAUSE_EMERGENCY 0x01
#define NET_ESTABLISH_CAUSE_HIGH_PRIO 0x02
#define NET_ESTABLISH_CAUSE_MT_ACCESS 0x03
#define NET_ESTABLISH_CAUSE_MO_SIGNAL 0x04
#define NET_ESTABLISH_CAUSE_MO_DATA 0x05
#define NET_ESTABLISH_CAUSE_V1020 0x06
/*
* --------------------------------------
* Network connection establishment type
* --------------------------------------
*/
#define NET_ESTABLISH_TYPE_ORIGINATING_SIGNAL 0x10
#define NET_ESTABLISH_TYPE_EMERGENCY_CALLS 0x20
#define NET_ESTABLISH_TYPE_ORIGINATING_CALLS 0x30
#define NET_ESTABLISH_TYPE_TERMINATING_CALLS 0x40
#define NET_ESTABLISH_TYPE_MO_CS_FALLBACK 0x50
/*
* -------------------
* PDN connection type
* -------------------
*/
#define NET_PDN_TYPE_IPV4 (0 + 1)
#define NET_PDN_TYPE_IPV6 (1 + 1)
#define NET_PDN_TYPE_IPV4V6 (2 + 1)
/****************************************************************************/
/************************ G L O B A L T Y P E S ************************/
/****************************************************************************/
/*
* ---------------------
* PDN connection status
* ---------------------
*/
typedef
enum
{
/* MT = The Mobile Terminal, NW = The Network */
NET_PDN_MT_DEFAULT_ACT
=
1
,
/* MT has activated a PDN connection */
NET_PDN_NW_DEFAULT_DEACT
,
/* NW has deactivated a PDN connection */
NET_PDN_MT_DEFAULT_DEACT
,
/* MT has deactivated a PDN connection */
NET_PDN_NW_DEDICATED_ACT
,
/* NW has activated an EPS bearer context */
NET_PDN_MT_DEDICATED_ACT
,
/* MT has activated an EPS bearer context */
NET_PDN_NW_DEDICATED_DEACT
,
/* NW has deactivated an EPS bearer context */
NET_PDN_MT_DEDICATED_DEACT
,
/* MT has deactivated an EPS bearer context */
}
network_pdn_state_t
;
/*
* ---------------------------
* Network operator identifier
* ---------------------------
*/
typedef
struct
{
#define NET_FORMAT_LONG_SIZE 16
/* Long alphanumeric format */
#define NET_FORMAT_SHORT_SIZE 8
/* Short alphanumeric format */
#define NET_FORMAT_NUM_SIZE 6
/* Numeric format (PLMN identifier */
union
{
unsigned
char
alpha_long
[
NET_FORMAT_LONG_SIZE
+
1
];
unsigned
char
alpha_short
[
NET_FORMAT_SHORT_SIZE
+
1
];
unsigned
char
num
[
NET_FORMAT_NUM_SIZE
+
1
];
}
id
;
}
network_plmn_t
;
/*
* -------------------------------
* EPS bearer level QoS parameters
* -------------------------------
*/
typedef
struct
{
int
gbrUL
;
/* Guaranteed Bit Rate for uplink */
int
gbrDL
;
/* Guaranteed Bit Rate for downlink */
int
mbrUL
;
/* Maximum Bit Rate for uplink */
int
mbrDL
;
/* Maximum Bit Rate for downlink */
int
qci
;
/* QoS Class Identifier */
}
network_qos_t
;
/*
* -----------------------------
* IPv4 packet filter parameters
* -----------------------------
*/
typedef
struct
{
unsigned
char
protocol
;
/* Protocol identifier */
unsigned
char
tos
;
/* Type of service */
#define NET_PACKET_FILTER_IPV4_ADDR_SIZE 4
unsigned
char
addr
[
NET_PACKET_FILTER_IPV4_ADDR_SIZE
];
unsigned
char
mask
[
NET_PACKET_FILTER_IPV4_ADDR_SIZE
];
}
network_ipv4_data_t
;
/*
* -----------------------------
* IPv6 packet filter parameters
* -----------------------------
*/
typedef
struct
{
unsigned
char
nh
;
/* Next header type */
unsigned
char
tf
;
/* Traffic class */
#define NET_PACKET_FILTER_IPV6_ADDR_SIZE 16
unsigned
char
addr
[
NET_PACKET_FILTER_IPV6_ADDR_SIZE
];
unsigned
char
mask
[
NET_PACKET_FILTER_IPV6_ADDR_SIZE
];
unsigned
int
ipsec
;
/* IPSec security parameter index */
unsigned
int
fl
;
/* Flow label */
}
network_ipv6_data_t
;
/*
* -------------
* Packet Filter
* -------------
*/
typedef
struct
{
unsigned
char
id
;
/* Packet filter identifier */
#define NET_PACKET_FILTER_DOWNLINK 0x01
#define NET_PACKET_FILTER_UPLINK 0x02
#define NET_PACKET_FILTER_BIDIR 0x03
unsigned
char
dir
;
/* Packet filter direction */
unsigned
char
precedence
;
/* Evaluation precedence */
union
{
network_ipv4_data_t
ipv4
;
network_ipv6_data_t
ipv6
;
}
data
;
unsigned
short
lport
;
/* Local (UE) port number */
unsigned
short
rport
;
/* Remote (network) port number */
}
network_pkf_t
;
/*
* ---------------------
* Traffic Flow Template
* ---------------------
*/
typedef
struct
{
int
n_pkfs
;
#define NET_PACKET_FILTER_MAX 16
network_pkf_t
*
pkf
[
NET_PACKET_FILTER_MAX
];
}
network_tft_t
;
/****************************************************************************/
/******************** G L O B A L V A R I A B L E S ********************/
/****************************************************************************/
/****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/
#endif
/* __NETWORKDEF_H__*/
openair3/UTILS/queue.h
deleted
100644 → 0
View file @
07c8d000
/*
* Copyright (c) 1991, 1993
* The Regents of the University of California. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)queue.h 8.5 (Berkeley) 8/20/94
*/
#ifndef _SYS_QUEUE_H_
#define _SYS_QUEUE_H_
/*
* This file defines five types of data structures: singly-linked lists,
* lists, simple queues, tail queues, and circular queues.
*
* A singly-linked list is headed by a single forward pointer. The
* elements are singly linked for minimum space and pointer manipulation
* overhead at the expense of O(n) removal for arbitrary elements. New
* elements can be added to the list after an existing element or at the
* head of the list. Elements being removed from the head of the list
* should use the explicit macro for this purpose for optimum
* efficiency. A singly-linked list may only be traversed in the forward
* direction. Singly-linked lists are ideal for applications with large
* datasets and few or no removals or for implementing a LIFO queue.
*
* A list is headed by a single forward pointer (or an array of forward
* pointers for a hash table header). The elements are doubly linked
* so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before
* or after an existing element or at the head of the list. A list
* may only be traversed in the forward direction.
*
* A simple queue is headed by a pair of pointers, one the head of the
* list and the other to the tail of the list. The elements are singly
* linked to save space, so elements can only be removed from the
* head of the list. New elements can be added to the list after
* an existing element, at the head of the list, or at the end of the
* list. A simple queue may only be traversed in the forward direction.
*
* A tail queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or
* after an existing element, at the head of the list, or at the end of
* the list. A tail queue may be traversed in either direction.
*
* A circle queue is headed by a pair of pointers, one to the head of the
* list and the other to the tail of the list. The elements are doubly
* linked so that an arbitrary element can be removed without a need to
* traverse the list. New elements can be added to the list before or after
* an existing element, at the head of the list, or at the end of the list.
* A circle queue may be traversed in either direction, but has a more
* complex end of list detection.
*
* For details on the use of these macros, see the queue(3) manual page.
* SLIST LIST STAILQ TAILQ CIRCLEQ
* _HEAD + + + + +
* _HEAD_INITIALIZER + + + + +
* _ENTRY + + + + +
* _INIT + + + + +
* _EMPTY + + + + +
* _FIRST + + + + +
* _NEXT + + + + +
* _PREV - - - + +
* _LAST - - + + +
* _FOREACH + + + + +
* _FOREACH_REVERSE - - - + +
* _INSERT_HEAD + + + + +
* _INSERT_BEFORE - + - + +
* _INSERT_AFTER + + + + +
* _INSERT_TAIL - - + + +
* _REMOVE_HEAD + - + - -
* _REMOVE + + + + +
*/
/*
* List definitions.
*/
#define LIST_HEAD(name, type) \
struct name { \
struct type *lh_first;
/* first element */
\
}
#define LIST_HEAD_INITIALIZER(head) \
{ NULL }
#define LIST_ENTRY(type) \
struct { \
struct type *le_next;
/* next element */
\
struct type **le_prev;
/* address of previous next element */
\
}
/*
* List functions.
*/
#define LIST_INIT(head) do { \
(head)->lh_first = NULL; \
} while (
/*CONSTCOND*/
0)
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
if (((elm)->field.le_next = (listelm)->field.le_next) != NULL) \
(listelm)->field.le_next->field.le_prev = \
&(elm)->field.le_next; \
(listelm)->field.le_next = (elm); \
(elm)->field.le_prev = &(listelm)->field.le_next; \
} while (
/*CONSTCOND*/
0)
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.le_prev = (listelm)->field.le_prev; \
(elm)->field.le_next = (listelm); \
*(listelm)->field.le_prev = (elm); \
(listelm)->field.le_prev = &(elm)->field.le_next; \
} while (
/*CONSTCOND*/
0)
#define LIST_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.le_next = (head)->lh_first) != NULL) \
(head)->lh_first->field.le_prev = &(elm)->field.le_next;\
(head)->lh_first = (elm); \
(elm)->field.le_prev = &(head)->lh_first; \
} while (
/*CONSTCOND*/
0)
#define LIST_REMOVE(elm, field) do { \
if ((elm)->field.le_next != NULL) \
(elm)->field.le_next->field.le_prev = \
(elm)->field.le_prev; \
*(elm)->field.le_prev = (elm)->field.le_next; \
} while (
/*CONSTCOND*/
0)
#define LIST_FOREACH(var, head, field) \
for ((var) = ((head)->lh_first); \
(var); \
(var) = ((var)->field.le_next))
/*
* List access methods.
*/
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
#define LIST_FIRST(head) ((head)->lh_first)
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
/*
* Singly-linked List definitions.
*/
#define SLIST_HEAD(name, type) \
struct name { \
struct type *slh_first;
/* first element */
\
}
#define SLIST_HEAD_INITIALIZER(head) \
{ NULL }
#define SLIST_ENTRY(type) \
struct { \
struct type *sle_next;
/* next element */
\
}
/*
* Singly-linked List functions.
*/
#define SLIST_INIT(head) do { \
(head)->slh_first = NULL; \
} while (
/*CONSTCOND*/
0)
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
(elm)->field.sle_next = (slistelm)->field.sle_next; \
(slistelm)->field.sle_next = (elm); \
} while (
/*CONSTCOND*/
0)
#define SLIST_INSERT_HEAD(head, elm, field) do { \
(elm)->field.sle_next = (head)->slh_first; \
(head)->slh_first = (elm); \
} while (
/*CONSTCOND*/
0)
#define SLIST_REMOVE_HEAD(head, field) do { \
(head)->slh_first = (head)->slh_first->field.sle_next; \
} while (
/*CONSTCOND*/
0)
#define SLIST_REMOVE(head, elm, type, field) do { \
if ((head)->slh_first == (elm)) { \
SLIST_REMOVE_HEAD((head), field); \
} \
else { \
struct type *curelm = (head)->slh_first; \
while(curelm->field.sle_next != (elm)) \
curelm = curelm->field.sle_next; \
curelm->field.sle_next = \
curelm->field.sle_next->field.sle_next; \
} \
} while (
/*CONSTCOND*/
0)
#define SLIST_FOREACH(var, head, field) \
for((var) = (head)->slh_first; (var); (var) = (var)->field.sle_next)
/*
* Singly-linked List access methods.
*/
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
#define SLIST_FIRST(head) ((head)->slh_first)
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
/*
* Singly-linked Tail queue declarations.
*/
#define STAILQ_HEAD(name, type) \
struct name { \
struct type *stqh_first;
/* first element */
\
struct type **stqh_last;
/* addr of last next element */
\
}
#define STAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).stqh_first }
#define STAILQ_ENTRY(type) \
struct { \
struct type *stqe_next;
/* next element */
\
}
/*
* Singly-linked Tail queue functions.
*/
#define STAILQ_INIT(head) do { \
(head)->stqh_first = NULL; \
(head)->stqh_last = &(head)->stqh_first; \
} while (
/*CONSTCOND*/
0)
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.stqe_next = (head)->stqh_first) == NULL) \
(head)->stqh_last = &(elm)->field.stqe_next; \
(head)->stqh_first = (elm); \
} while (
/*CONSTCOND*/
0)
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.stqe_next = NULL; \
*(head)->stqh_last = (elm); \
(head)->stqh_last = &(elm)->field.stqe_next; \
} while (
/*CONSTCOND*/
0)
#define STAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.stqe_next = (listelm)->field.stqe_next) == NULL)\
(head)->stqh_last = &(elm)->field.stqe_next; \
(listelm)->field.stqe_next = (elm); \
} while (
/*CONSTCOND*/
0)
#define STAILQ_REMOVE_HEAD(head, field) do { \
if (((head)->stqh_first = (head)->stqh_first->field.stqe_next) == NULL) \
(head)->stqh_last = &(head)->stqh_first; \
} while (
/*CONSTCOND*/
0)
#define STAILQ_REMOVE(head, elm, type, field) do { \
if ((head)->stqh_first == (elm)) { \
STAILQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->stqh_first; \
while (curelm->field.stqe_next != (elm)) \
curelm = curelm->field.stqe_next; \
if ((curelm->field.stqe_next = \
curelm->field.stqe_next->field.stqe_next) == NULL) \
(head)->stqh_last = &(curelm)->field.stqe_next; \
} \
} while (
/*CONSTCOND*/
0)
#define STAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->stqh_first); \
(var); \
(var) = ((var)->field.stqe_next))
#define STAILQ_CONCAT(head1, head2) do { \
if (!STAILQ_EMPTY((head2))) { \
*(head1)->stqh_last = (head2)->stqh_first; \
(head1)->stqh_last = (head2)->stqh_last; \
STAILQ_INIT((head2)); \
} \
} while (
/*CONSTCOND*/
0)
/*
* Singly-linked Tail queue access methods.
*/
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
#define STAILQ_FIRST(head) ((head)->stqh_first)
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
/*
* Simple queue definitions.
*/
#define SIMPLEQ_HEAD(name, type) \
struct name { \
struct type *sqh_first;
/* first element */
\
struct type **sqh_last;
/* addr of last next element */
\
}
#define SIMPLEQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).sqh_first }
#define SIMPLEQ_ENTRY(type) \
struct { \
struct type *sqe_next;
/* next element */
\
}
/*
* Simple queue functions.
*/
#define SIMPLEQ_INIT(head) do { \
(head)->sqh_first = NULL; \
(head)->sqh_last = &(head)->sqh_first; \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.sqe_next = (head)->sqh_first) == NULL) \
(head)->sqh_last = &(elm)->field.sqe_next; \
(head)->sqh_first = (elm); \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.sqe_next = NULL; \
*(head)->sqh_last = (elm); \
(head)->sqh_last = &(elm)->field.sqe_next; \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.sqe_next = (listelm)->field.sqe_next) == NULL)\
(head)->sqh_last = &(elm)->field.sqe_next; \
(listelm)->field.sqe_next = (elm); \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_REMOVE_HEAD(head, field) do { \
if (((head)->sqh_first = (head)->sqh_first->field.sqe_next) == NULL) \
(head)->sqh_last = &(head)->sqh_first; \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_REMOVE(head, elm, type, field) do { \
if ((head)->sqh_first == (elm)) { \
SIMPLEQ_REMOVE_HEAD((head), field); \
} else { \
struct type *curelm = (head)->sqh_first; \
while (curelm->field.sqe_next != (elm)) \
curelm = curelm->field.sqe_next; \
if ((curelm->field.sqe_next = \
curelm->field.sqe_next->field.sqe_next) == NULL) \
(head)->sqh_last = &(curelm)->field.sqe_next; \
} \
} while (
/*CONSTCOND*/
0)
#define SIMPLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->sqh_first); \
(var); \
(var) = ((var)->field.sqe_next))
/*
* Simple queue access methods.
*/
#define SIMPLEQ_EMPTY(head) ((head)->sqh_first == NULL)
#define SIMPLEQ_FIRST(head) ((head)->sqh_first)
#define SIMPLEQ_NEXT(elm, field) ((elm)->field.sqe_next)
/*
* Tail queue definitions.
*/
#define _TAILQ_HEAD(name, type, qual) \
struct name { \
qual type *tqh_first;
/* first element */
\
qual type *qual *tqh_last;
/* addr of last next element */
\
}
#define TAILQ_HEAD(name, type) _TAILQ_HEAD(name, struct type,)
#define TAILQ_HEAD_INITIALIZER(head) \
{ NULL, &(head).tqh_first }
#define _TAILQ_ENTRY(type, qual) \
struct { \
qual type *tqe_next;
/* next element */
\
qual type *qual *tqe_prev;
/* address of previous next element */
\
}
#define TAILQ_ENTRY(type) _TAILQ_ENTRY(struct type,)
/*
* Tail queue functions.
*/
#define TAILQ_INIT(head) do { \
(head)->tqh_first = NULL; \
(head)->tqh_last = &(head)->tqh_first; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
if (((elm)->field.tqe_next = (head)->tqh_first) != NULL) \
(head)->tqh_first->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(head)->tqh_first = (elm); \
(elm)->field.tqe_prev = &(head)->tqh_first; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.tqe_next = NULL; \
(elm)->field.tqe_prev = (head)->tqh_last; \
*(head)->tqh_last = (elm); \
(head)->tqh_last = &(elm)->field.tqe_next; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
if (((elm)->field.tqe_next = (listelm)->field.tqe_next) != NULL)\
(elm)->field.tqe_next->field.tqe_prev = \
&(elm)->field.tqe_next; \
else \
(head)->tqh_last = &(elm)->field.tqe_next; \
(listelm)->field.tqe_next = (elm); \
(elm)->field.tqe_prev = &(listelm)->field.tqe_next; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
(elm)->field.tqe_next = (listelm); \
*(listelm)->field.tqe_prev = (elm); \
(listelm)->field.tqe_prev = &(elm)->field.tqe_next; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_REMOVE(head, elm, field) do { \
if (((elm)->field.tqe_next) != NULL) \
(elm)->field.tqe_next->field.tqe_prev = \
(elm)->field.tqe_prev; \
else \
(head)->tqh_last = (elm)->field.tqe_prev; \
*(elm)->field.tqe_prev = (elm)->field.tqe_next; \
} while (
/*CONSTCOND*/
0)
#define TAILQ_FOREACH(var, head, field) \
for ((var) = ((head)->tqh_first); \
(var); \
(var) = ((var)->field.tqe_next))
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
for ((var) = (*(((struct headname *)((head)->tqh_last))->tqh_last)); \
(var); \
(var) = (*(((struct headname *)((var)->field.tqe_prev))->tqh_last)))
#define TAILQ_CONCAT(head1, head2, field) do { \
if (!TAILQ_EMPTY(head2)) { \
*(head1)->tqh_last = (head2)->tqh_first; \
(head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
(head1)->tqh_last = (head2)->tqh_last; \
TAILQ_INIT((head2)); \
} \
} while (
/*CONSTCOND*/
0)
/*
* Tail queue access methods.
*/
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
#define TAILQ_FIRST(head) ((head)->tqh_first)
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
#define TAILQ_LAST(head, headname) \
(*(((struct headname *)((head)->tqh_last))->tqh_last))
#define TAILQ_PREV(elm, headname, field) \
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
/*
* Circular queue definitions.
*/
#define CIRCLEQ_HEAD(name, type) \
struct name { \
struct type *cqh_first;
/* first element */
\
struct type *cqh_last;
/* last element */
\
}
#define CIRCLEQ_HEAD_INITIALIZER(head) \
{ (void *)&head, (void *)&head }
#define CIRCLEQ_ENTRY(type) \
struct { \
struct type *cqe_next;
/* next element */
\
struct type *cqe_prev;
/* previous element */
\
}
/*
* Circular queue functions.
*/
#define CIRCLEQ_INIT(head) do { \
(head)->cqh_first = (void *)(head); \
(head)->cqh_last = (void *)(head); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm)->field.cqe_next; \
(elm)->field.cqe_prev = (listelm); \
if ((listelm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(listelm)->field.cqe_next->field.cqe_prev = (elm); \
(listelm)->field.cqe_next = (elm); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
(elm)->field.cqe_next = (listelm); \
(elm)->field.cqe_prev = (listelm)->field.cqe_prev; \
if ((listelm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(listelm)->field.cqe_prev->field.cqe_next = (elm); \
(listelm)->field.cqe_prev = (elm); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
(elm)->field.cqe_next = (head)->cqh_first; \
(elm)->field.cqe_prev = (void *)(head); \
if ((head)->cqh_last == (void *)(head)) \
(head)->cqh_last = (elm); \
else \
(head)->cqh_first->field.cqe_prev = (elm); \
(head)->cqh_first = (elm); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
(elm)->field.cqe_next = (void *)(head); \
(elm)->field.cqe_prev = (head)->cqh_last; \
if ((head)->cqh_first == (void *)(head)) \
(head)->cqh_first = (elm); \
else \
(head)->cqh_last->field.cqe_next = (elm); \
(head)->cqh_last = (elm); \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_REMOVE(head, elm, field) do { \
if ((elm)->field.cqe_next == (void *)(head)) \
(head)->cqh_last = (elm)->field.cqe_prev; \
else \
(elm)->field.cqe_next->field.cqe_prev = \
(elm)->field.cqe_prev; \
if ((elm)->field.cqe_prev == (void *)(head)) \
(head)->cqh_first = (elm)->field.cqe_next; \
else \
(elm)->field.cqe_prev->field.cqe_next = \
(elm)->field.cqe_next; \
} while (
/*CONSTCOND*/
0)
#define CIRCLEQ_FOREACH(var, head, field) \
for ((var) = ((head)->cqh_first); \
(var) != (const void *)(head); \
(var) = ((var)->field.cqe_next))
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
for ((var) = ((head)->cqh_last); \
(var) != (const void *)(head); \
(var) = ((var)->field.cqe_prev))
/*
* Circular queue access methods.
*/
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
#define CIRCLEQ_NEXT(elm, field) ((elm)->field.cqe_next)
#define CIRCLEQ_PREV(elm, field) ((elm)->field.cqe_prev)
#define CIRCLEQ_LOOP_NEXT(head, elm, field) \
(((elm)->field.cqe_next == (void *)(head)) \
? ((head)->cqh_first) \
: (elm->field.cqe_next))
#define CIRCLEQ_LOOP_PREV(head, elm, field) \
(((elm)->field.cqe_prev == (void *)(head)) \
? ((head)->cqh_last) \
: (elm->field.cqe_prev))
#endif
/* sys/queue.h */
openair3/UTILS/tree.h
deleted
100644 → 0
View file @
07c8d000
/*
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef _SYS_TREE_H_
#define _SYS_TREE_H_
/*
* This file defines data structures for different types of trees:
* splay trees and red-black trees.
*
* A splay tree is a self-organizing data structure. Every operation
* on the tree causes a splay to happen. The splay moves the requested
* node to the root of the tree and partly rebalances it.
*
* This has the benefit that request locality causes faster lookups as
* the requested nodes move to the top of the tree. On the other hand,
* every lookup causes memory writes.
*
* The Balance Theorem bounds the total access time for m operations
* and n inserts on an initially empty tree as O((m + n)lg n). The
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
*
* A red-black tree is a binary search tree with the node color as an
* extra attribute. It fulfills a set of conditions:
* - every search path from the root to a leaf consists of the
* same number of black nodes,
* - each red node (except for the root) has a black parent,
* - each leaf node is black.
*
* Every operation on a red-black tree is bounded as O(lg n).
* The maximum height of a red-black tree is 2lg (n+1).
*/
#define SPLAY_HEAD(name, type) \
struct name { \
struct type *sph_root;
/* root of the tree */
\
}
#define SPLAY_INITIALIZER(root) \
{ NULL }
#define SPLAY_INIT(root) do { \
(root)->sph_root = NULL; \
} while (0)
#define SPLAY_ENTRY(type) \
struct { \
struct type *spe_left;
/* left element */
\
struct type *spe_right;
/* right element */
\
}
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
#define SPLAY_ROOT(head) (head)->sph_root
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (0)
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
(head)->sph_root = tmp; \
} while (0)
#define SPLAY_LINKLEFT(head, tmp, field) do { \
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
} while (0)
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
tmp = (head)->sph_root; \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
} while (0)
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field);\
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
} while (0)
/* Generates prototypes and inline functions */
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
void name##_SPLAY(struct name *, struct type *); \
void name##_SPLAY_MINMAX(struct name *, int); \
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
\
/* Finds the node with the same key as elm */
\
static __inline struct type * \
name##_SPLAY_FIND(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) \
return(NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) \
return (head->sph_root); \
return (NULL); \
} \
\
static __inline struct type * \
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
{ \
name##_SPLAY(head, elm); \
if (SPLAY_RIGHT(elm, field) != NULL) { \
elm = SPLAY_RIGHT(elm, field); \
while (SPLAY_LEFT(elm, field) != NULL) { \
elm = SPLAY_LEFT(elm, field); \
} \
} else \
elm = NULL; \
return (elm); \
} \
\
static __inline struct type * \
name##_SPLAY_MIN_MAX(struct name *head, int val) \
{ \
name##_SPLAY_MINMAX(head, val); \
return (SPLAY_ROOT(head)); \
}
/* Main splay operation.
* Moves node close to the key of elm to top
*/
#define SPLAY_GENERATE(name, type, field, cmp) \
struct type * \
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
{ \
if (SPLAY_EMPTY(head)) { \
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
} else { \
int __comp; \
name##_SPLAY(head, elm); \
__comp = (cmp)(elm, (head)->sph_root); \
if(__comp < 0) { \
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field);\
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
SPLAY_LEFT((head)->sph_root, field) = NULL; \
} else if (__comp > 0) { \
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field);\
SPLAY_LEFT(elm, field) = (head)->sph_root; \
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
} else \
return ((head)->sph_root); \
} \
(head)->sph_root = (elm); \
return (NULL); \
} \
\
struct type * \
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *__tmp; \
if (SPLAY_EMPTY(head)) \
return (NULL); \
name##_SPLAY(head, elm); \
if ((cmp)(elm, (head)->sph_root) == 0) { \
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field);\
} else { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field);\
name##_SPLAY(head, elm); \
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
} \
return (elm); \
} \
return (NULL); \
} \
\
void \
name##_SPLAY(struct name *head, struct type *elm) \
{ \
struct type __node, *__left, *__right, *__tmp; \
int __comp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
__left = __right = &__node; \
\
while ((__comp = (cmp)(elm, (head)->sph_root))) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) < 0){ \
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if ((cmp)(elm, __tmp) > 0){ \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
} \
\
/* Splay with either the minimum or the maximum element \
* Used to find minimum or maximum element in tree. \
*/
\
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
{ \
struct type __node, *__left, *__right, *__tmp; \
\
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL;\
__left = __right = &__node; \
\
while (1) { \
if (__comp < 0) { \
__tmp = SPLAY_LEFT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp < 0){ \
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
if (SPLAY_LEFT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKLEFT(head, __right, field); \
} else if (__comp > 0) { \
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
if (__tmp == NULL) \
break; \
if (__comp > 0) { \
SPLAY_ROTATE_LEFT(head, __tmp, field); \
if (SPLAY_RIGHT((head)->sph_root, field) == NULL)\
break; \
} \
SPLAY_LINKRIGHT(head, __left, field); \
} \
} \
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
}
#define SPLAY_NEGINF -1
#define SPLAY_INF 1
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
#define SPLAY_FOREACH(x, name, head) \
for ((x) = SPLAY_MIN(name, head); \
(x) != NULL; \
(x) = SPLAY_NEXT(name, head, x))
/* Macros that define a red-back tree */
#define RB_HEAD(name, type) \
struct name { \
struct type *rbh_root;
/* root of the tree */
\
}
#define RB_INITIALIZER(root) \
{ NULL }
#define RB_INIT(root) do { \
(root)->rbh_root = NULL; \
} while (0)
#define RB_BLACK 0
#define RB_RED 1
#define RB_ENTRY(type) \
struct { \
struct type *rbe_left;
/* left element */
\
struct type *rbe_right;
/* right element */
\
struct type *rbe_parent;
/* parent element */
\
int rbe_color;
/* node color */
\
}
#define RB_LEFT(elm, field) (elm)->field.rbe_left
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
#define RB_COLOR(elm, field) (elm)->field.rbe_color
#define RB_ROOT(head) (head)->rbh_root
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
#define RB_SET(elm, parent, field) do { \
RB_PARENT(elm, field) = parent; \
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
RB_COLOR(elm, field) = RB_RED; \
} while (0)
#define RB_SET_BLACKRED(black, red, field) do { \
RB_COLOR(black, field) = RB_BLACK; \
RB_COLOR(red, field) = RB_RED; \
} while (0)
#ifndef RB_AUGMENT
#define RB_AUGMENT(x)
#endif
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
(tmp) = RB_RIGHT(elm, field); \
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field))) { \
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
} \
RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
else \
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
} else \
(head)->rbh_root = (tmp); \
RB_LEFT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \
if ((RB_PARENT(tmp, field))) \
RB_AUGMENT(RB_PARENT(tmp, field)); \
} while (0)
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
(tmp) = RB_LEFT(elm, field); \
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field))) { \
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
} \
RB_AUGMENT(elm); \
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field))) { \
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
else \
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
} else \
(head)->rbh_root = (tmp); \
RB_RIGHT(tmp, field) = (elm); \
RB_PARENT(elm, field) = (tmp); \
RB_AUGMENT(tmp); \
if ((RB_PARENT(tmp, field))) \
RB_AUGMENT(RB_PARENT(tmp, field)); \
} while (0)
/* Generates prototypes and inline functions */
#define RB_PROTOTYPE(name, type, field, cmp) \
void name##_RB_INSERT_COLOR(struct name *, struct type *); \
void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
struct type *name##_RB_REMOVE(struct name *, struct type *); \
struct type *name##_RB_INSERT(struct name *, struct type *); \
struct type *name##_RB_FIND(struct name *, struct type *); \
struct type *name##_RB_NEXT(struct type *); \
struct type *name##_RB_MINMAX(struct name *, int); \
\
/* Main rb operation.
* Moves node close to the key of elm to top
*/
#define RB_GENERATE(name, type, field, cmp) \
void \
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
{ \
struct type *parent, *gparent, *tmp; \
while ((parent = RB_PARENT(elm, field)) && \
RB_COLOR(parent, field) == RB_RED) { \
gparent = RB_PARENT(parent, field); \
if (parent == RB_LEFT(gparent, field)) { \
tmp = RB_RIGHT(gparent, field); \
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
RB_COLOR(tmp, field) = RB_BLACK; \
RB_SET_BLACKRED(parent, gparent, field);\
elm = gparent; \
continue; \
} \
if (RB_RIGHT(parent, field) == elm) { \
RB_ROTATE_LEFT(head, parent, tmp, field);\
tmp = parent; \
parent = elm; \
elm = tmp; \
} \
RB_SET_BLACKRED(parent, gparent, field); \
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
} else { \
tmp = RB_LEFT(gparent, field); \
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
RB_COLOR(tmp, field) = RB_BLACK; \
RB_SET_BLACKRED(parent, gparent, field);\
elm = gparent; \
continue; \
} \
if (RB_LEFT(parent, field) == elm) { \
RB_ROTATE_RIGHT(head, parent, tmp, field);\
tmp = parent; \
parent = elm; \
elm = tmp; \
} \
RB_SET_BLACKRED(parent, gparent, field); \
RB_ROTATE_LEFT(head, gparent, tmp, field); \
} \
} \
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
} \
\
void \
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, struct type *elm) \
{ \
struct type *tmp; \
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
elm != RB_ROOT(head)) { \
if (RB_LEFT(parent, field) == elm) { \
tmp = RB_RIGHT(parent, field); \
if (RB_COLOR(tmp, field) == RB_RED) { \
RB_SET_BLACKRED(tmp, parent, field); \
RB_ROTATE_LEFT(head, parent, tmp, field);\
tmp = RB_RIGHT(parent, field); \
} \
if ((RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
(RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
RB_COLOR(tmp, field) = RB_RED; \
elm = parent; \
parent = RB_PARENT(elm, field); \
} else { \
if (RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) {\
struct type *oleft; \
if ((oleft = RB_LEFT(tmp, field)))\
RB_COLOR(oleft, field) = RB_BLACK;\
RB_COLOR(tmp, field) = RB_RED; \
RB_ROTATE_RIGHT(head, tmp, oleft, field);\
tmp = RB_RIGHT(parent, field); \
} \
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
RB_COLOR(parent, field) = RB_BLACK; \
if (RB_RIGHT(tmp, field)) \
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK;\
RB_ROTATE_LEFT(head, parent, tmp, field);\
elm = RB_ROOT(head); \
break; \
} \
} else { \
tmp = RB_LEFT(parent, field); \
if (RB_COLOR(tmp, field) == RB_RED) { \
RB_SET_BLACKRED(tmp, parent, field); \
RB_ROTATE_RIGHT(head, parent, tmp, field);\
tmp = RB_LEFT(parent, field); \
} \
if ((RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) &&\
(RB_RIGHT(tmp, field) == NULL || \
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) {\
RB_COLOR(tmp, field) = RB_RED; \
elm = parent; \
parent = RB_PARENT(elm, field); \
} else { \
if (RB_LEFT(tmp, field) == NULL || \
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) {\
struct type *oright; \
if ((oright = RB_RIGHT(tmp, field)))\
RB_COLOR(oright, field) = RB_BLACK;\
RB_COLOR(tmp, field) = RB_RED; \
RB_ROTATE_LEFT(head, tmp, oright, field);\
tmp = RB_LEFT(parent, field); \
} \
RB_COLOR(tmp, field) = RB_COLOR(parent, field);\
RB_COLOR(parent, field) = RB_BLACK; \
if (RB_LEFT(tmp, field)) \
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK;\
RB_ROTATE_RIGHT(head, parent, tmp, field);\
elm = RB_ROOT(head); \
break; \
} \
} \
} \
if (elm) \
RB_COLOR(elm, field) = RB_BLACK; \
} \
\
struct type * \
name##_RB_REMOVE(struct name *head, struct type *elm) \
{ \
struct type *child, *parent, *old = elm; \
int color; \
if (RB_LEFT(elm, field) == NULL) \
child = RB_RIGHT(elm, field); \
else if (RB_RIGHT(elm, field) == NULL) \
child = RB_LEFT(elm, field); \
else { \
struct type *left; \
elm = RB_RIGHT(elm, field); \
while ((left = RB_LEFT(elm, field))) \
elm = left; \
child = RB_RIGHT(elm, field); \
parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \
if (child) \
RB_PARENT(child, field) = parent; \
if (parent) { \
if (RB_LEFT(parent, field) == elm) \
RB_LEFT(parent, field) = child; \
else \
RB_RIGHT(parent, field) = child; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = child; \
if (RB_PARENT(elm, field) == old) \
parent = elm; \
(elm)->field = (old)->field; \
if (RB_PARENT(old, field)) { \
if (RB_LEFT(RB_PARENT(old, field), field) == old)\
RB_LEFT(RB_PARENT(old, field), field) = elm;\
else \
RB_RIGHT(RB_PARENT(old, field), field) = elm;\
RB_AUGMENT(RB_PARENT(old, field)); \
} else \
RB_ROOT(head) = elm; \
RB_PARENT(RB_LEFT(old, field), field) = elm; \
if (RB_RIGHT(old, field)) \
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
if (parent) { \
left = parent; \
do { \
RB_AUGMENT(left); \
} while ((left = RB_PARENT(left, field))); \
} \
goto color; \
} \
parent = RB_PARENT(elm, field); \
color = RB_COLOR(elm, field); \
if (child) \
RB_PARENT(child, field) = parent; \
if (parent) { \
if (RB_LEFT(parent, field) == elm) \
RB_LEFT(parent, field) = child; \
else \
RB_RIGHT(parent, field) = child; \
RB_AUGMENT(parent); \
} else \
RB_ROOT(head) = child; \
color: \
if (color == RB_BLACK) \
name##_RB_REMOVE_COLOR(head, parent, child); \
return (old); \
} \
\
/* Inserts a node into the RB tree */
\
struct type * \
name##_RB_INSERT(struct name *head, struct type *elm) \
{ \
struct type *tmp; \
struct type *parent = NULL; \
int comp = 0; \
tmp = RB_ROOT(head); \
while (tmp) { \
parent = tmp; \
comp = (cmp)(elm, parent); \
if (comp < 0) \
tmp = RB_LEFT(tmp, field); \
else if (comp > 0) \
tmp = RB_RIGHT(tmp, field); \
else \
return (tmp); \
} \
RB_SET(elm, parent, field); \
if (parent != NULL) { \
if (comp < 0) \
RB_LEFT(parent, field) = elm; \
else \
RB_RIGHT(parent, field) = elm; \
RB_AUGMENT(parent); \
} else \
{ \
RB_ROOT(head) = elm; \
} \
name##_RB_INSERT_COLOR(head, elm); \
return (NULL); \
} \
\
/* Finds the node with the same key as elm */
\
struct type * \
name##_RB_FIND(struct name *head, struct type *elm) \
{ \
struct type *tmp = RB_ROOT(head); \
int comp; \
while (tmp) { \
comp = cmp(elm, tmp); \
if (comp < 0) \
tmp = RB_LEFT(tmp, field); \
else if (comp > 0) \
tmp = RB_RIGHT(tmp, field); \
else \
return (tmp); \
} \
return (NULL); \
} \
\
struct type * \
name##_RB_NEXT(struct type *elm) \
{ \
if (RB_RIGHT(elm, field)) { \
elm = RB_RIGHT(elm, field); \
while (RB_LEFT(elm, field)) \
elm = RB_LEFT(elm, field); \
} else { \
if (RB_PARENT(elm, field) && \
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
elm = RB_PARENT(elm, field); \
else { \
while (RB_PARENT(elm, field) && \
(elm == RB_RIGHT(RB_PARENT(elm, field), field)))\
elm = RB_PARENT(elm, field); \
elm = RB_PARENT(elm, field); \
} \
} \
return (elm); \
} \
\
struct type * \
name##_RB_MINMAX(struct name *head, int val) \
{ \
struct type *tmp = RB_ROOT(head); \
struct type *parent = NULL; \
while (tmp) { \
parent = tmp; \
if (val < 0) \
tmp = RB_LEFT(tmp, field); \
else \
tmp = RB_RIGHT(tmp, field); \
} \
return (parent); \
}
#define RB_NEGINF -1
#define RB_INF 1
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
#define RB_FOREACH(x, name, head) \
for ((x) = RB_MIN(name, head); \
(x) != NULL; \
(x) = name##_RB_NEXT(x))
#endif
/* _SYS_TREE_H_ */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment