astyle --recursive --indent=spaces=2 --style=kr --indent-col1-comments --break-blocks --convert-tabs --max-code-length=200
This is done for better merging branch/LG_PRE_RELEASE_0.3 into trunk (same process is applied on this branch) git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7073 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -30,7 +30,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#ifdef CMAKER
|
#ifdef CMAKER
|
||||||
#include <platform_types.h>
|
#include <platform_types.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(ENB_MODE)
|
#if defined(ENB_MODE)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -41,24 +41,24 @@
|
|||||||
/* Obtain a backtrace and print it to stdout. */
|
/* Obtain a backtrace and print it to stdout. */
|
||||||
void display_backtrace(void)
|
void display_backtrace(void)
|
||||||
{
|
{
|
||||||
void *array[10];
|
void *array[10];
|
||||||
size_t size;
|
size_t size;
|
||||||
char **strings;
|
char **strings;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
size = backtrace(array, 10);
|
size = backtrace(array, 10);
|
||||||
strings = backtrace_symbols(array, size);
|
strings = backtrace_symbols(array, size);
|
||||||
|
|
||||||
printf("Obtained %zd stack frames.\n", size);
|
printf("Obtained %zd stack frames.\n", size);
|
||||||
|
|
||||||
for (i = 0; i < size; i++)
|
for (i = 0; i < size; i++)
|
||||||
printf("%s\n", strings[i]);
|
printf("%s\n", strings[i]);
|
||||||
|
|
||||||
free(strings);
|
free(strings);
|
||||||
}
|
}
|
||||||
|
|
||||||
void backtrace_handle_signal(siginfo_t *info)
|
void backtrace_handle_signal(siginfo_t *info)
|
||||||
{
|
{
|
||||||
display_backtrace();
|
display_backtrace();
|
||||||
//exit(EXIT_FAILURE);
|
//exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -62,41 +62,41 @@ typedef unsigned long message_number_t;
|
|||||||
#define MESSAGE_NUMBER_SIZE (sizeof(unsigned long))
|
#define MESSAGE_NUMBER_SIZE (sizeof(unsigned long))
|
||||||
|
|
||||||
typedef enum message_priorities_e {
|
typedef enum message_priorities_e {
|
||||||
MESSAGE_PRIORITY_MAX = 100,
|
MESSAGE_PRIORITY_MAX = 100,
|
||||||
MESSAGE_PRIORITY_MAX_LEAST = 85,
|
MESSAGE_PRIORITY_MAX_LEAST = 85,
|
||||||
MESSAGE_PRIORITY_MED_PLUS = 70,
|
MESSAGE_PRIORITY_MED_PLUS = 70,
|
||||||
MESSAGE_PRIORITY_MED = 55,
|
MESSAGE_PRIORITY_MED = 55,
|
||||||
MESSAGE_PRIORITY_MED_LEAST = 40,
|
MESSAGE_PRIORITY_MED_LEAST = 40,
|
||||||
MESSAGE_PRIORITY_MIN_PLUS = 25,
|
MESSAGE_PRIORITY_MIN_PLUS = 25,
|
||||||
MESSAGE_PRIORITY_MIN = 10,
|
MESSAGE_PRIORITY_MIN = 10,
|
||||||
} message_priorities_t;
|
} message_priorities_t;
|
||||||
|
|
||||||
typedef struct message_info_s {
|
typedef struct message_info_s {
|
||||||
task_id_t id;
|
task_id_t id;
|
||||||
message_priorities_t priority;
|
message_priorities_t priority;
|
||||||
/* Message payload size */
|
/* Message payload size */
|
||||||
MessageHeaderSize size;
|
MessageHeaderSize size;
|
||||||
/* Printable name */
|
/* Printable name */
|
||||||
const char * const name;
|
const char * const name;
|
||||||
} message_info_t;
|
} message_info_t;
|
||||||
|
|
||||||
typedef enum task_priorities_e {
|
typedef enum task_priorities_e {
|
||||||
TASK_PRIORITY_MAX = 100,
|
TASK_PRIORITY_MAX = 100,
|
||||||
TASK_PRIORITY_MAX_LEAST = 85,
|
TASK_PRIORITY_MAX_LEAST = 85,
|
||||||
TASK_PRIORITY_MED_PLUS = 70,
|
TASK_PRIORITY_MED_PLUS = 70,
|
||||||
TASK_PRIORITY_MED = 55,
|
TASK_PRIORITY_MED = 55,
|
||||||
TASK_PRIORITY_MED_LEAST = 40,
|
TASK_PRIORITY_MED_LEAST = 40,
|
||||||
TASK_PRIORITY_MIN_PLUS = 25,
|
TASK_PRIORITY_MIN_PLUS = 25,
|
||||||
TASK_PRIORITY_MIN = 10,
|
TASK_PRIORITY_MIN = 10,
|
||||||
} task_priorities_t;
|
} task_priorities_t;
|
||||||
|
|
||||||
typedef struct task_info_s {
|
typedef struct task_info_s {
|
||||||
thread_id_t thread;
|
thread_id_t thread;
|
||||||
task_id_t parent_task;
|
task_id_t parent_task;
|
||||||
task_priorities_t priority;
|
task_priorities_t priority;
|
||||||
unsigned int queue_size;
|
unsigned int queue_size;
|
||||||
/* Printable name */
|
/* Printable name */
|
||||||
const char * const name;
|
const char * const name;
|
||||||
} task_info_t;
|
} task_info_t;
|
||||||
|
|
||||||
/** \brief Update the itti LTE time reference for messages
|
/** \brief Update the itti LTE time reference for messages
|
||||||
@@ -205,8 +205,8 @@ const char *itti_get_task_name(task_id_t task_id);
|
|||||||
* @returns NULL in case of failure or newly allocated mesage ref
|
* @returns NULL in case of failure or newly allocated mesage ref
|
||||||
**/
|
**/
|
||||||
MessageDef *itti_alloc_new_message(
|
MessageDef *itti_alloc_new_message(
|
||||||
task_id_t origin_task_id,
|
task_id_t origin_task_id,
|
||||||
MessagesIds message_id);
|
MessagesIds message_id);
|
||||||
|
|
||||||
/** \brief Alloc and memset(0) a new itti message.
|
/** \brief Alloc and memset(0) a new itti message.
|
||||||
* \param origin_task_id Task ID of the sending task
|
* \param origin_task_id Task ID of the sending task
|
||||||
@@ -215,9 +215,9 @@ MessageDef *itti_alloc_new_message(
|
|||||||
* @returns NULL in case of failure or newly allocated mesage ref
|
* @returns NULL in case of failure or newly allocated mesage ref
|
||||||
**/
|
**/
|
||||||
MessageDef *itti_alloc_new_message_sized(
|
MessageDef *itti_alloc_new_message_sized(
|
||||||
task_id_t origin_task_id,
|
task_id_t origin_task_id,
|
||||||
MessagesIds message_id,
|
MessagesIds message_id,
|
||||||
MessageHeaderSize size);
|
MessageHeaderSize size);
|
||||||
|
|
||||||
/** \brief handle signals and wait for all threads to join when the process complete.
|
/** \brief handle signals and wait for all threads to join when the process complete.
|
||||||
* This function should be called from the main thread after having created all ITTI tasks.
|
* This function should be called from the main thread after having created all ITTI tasks.
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -55,7 +55,7 @@ const char * const messages_definition_xml = {
|
|||||||
|
|
||||||
/* Map task id to printable name. */
|
/* Map task id to printable name. */
|
||||||
const task_info_t tasks_info[] = {
|
const task_info_t tasks_info[] = {
|
||||||
{0, TASK_UNKNOWN, 0, 0, "TASK_UNKNOWN"},
|
{0, TASK_UNKNOWN, 0, 0, "TASK_UNKNOWN"},
|
||||||
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) { tHREADiD##_THREAD, TASK_UNKNOWN, pRIO, qUEUEsIZE, #tHREADiD },
|
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) { tHREADiD##_THREAD, TASK_UNKNOWN, pRIO, qUEUEsIZE, #tHREADiD },
|
||||||
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) { sUBtASKiD##_THREAD, tHREADiD##_THREAD, 0, qUEUEsIZE, #sUBtASKiD },
|
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) { sUBtASKiD##_THREAD, tHREADiD##_THREAD, 0, qUEUEsIZE, #sUBtASKiD },
|
||||||
#include <tasks_def.h>
|
#include <tasks_def.h>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -63,19 +63,17 @@
|
|||||||
#include <messages_types.h>
|
#include <messages_types.h>
|
||||||
|
|
||||||
/* This enum defines messages ids. Each one is unique. */
|
/* This enum defines messages ids. Each one is unique. */
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) iD,
|
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) iD,
|
||||||
#include <messages_def.h>
|
#include <messages_def.h>
|
||||||
#undef MESSAGE_DEF
|
#undef MESSAGE_DEF
|
||||||
|
|
||||||
MESSAGES_ID_MAX,
|
MESSAGES_ID_MAX,
|
||||||
} MessagesIds;
|
} MessagesIds;
|
||||||
|
|
||||||
//! Thread id of each task
|
//! Thread id of each task
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
THREAD_NULL = 0,
|
||||||
THREAD_NULL = 0,
|
|
||||||
|
|
||||||
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) THREAD_##tHREADiD,
|
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) THREAD_##tHREADiD,
|
||||||
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE)
|
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE)
|
||||||
@@ -83,13 +81,12 @@ typedef enum
|
|||||||
#undef SUB_TASK_DEF
|
#undef SUB_TASK_DEF
|
||||||
#undef TASK_DEF
|
#undef TASK_DEF
|
||||||
|
|
||||||
THREAD_MAX,
|
THREAD_MAX,
|
||||||
THREAD_FIRST = 1,
|
THREAD_FIRST = 1,
|
||||||
} thread_id_t;
|
} thread_id_t;
|
||||||
|
|
||||||
//! Sub-tasks id, to defined offset form thread id
|
//! Sub-tasks id, to defined offset form thread id
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) tHREADiD##_THREAD = THREAD_##tHREADiD,
|
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) tHREADiD##_THREAD = THREAD_##tHREADiD,
|
||||||
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) sUBtASKiD##_THREAD = THREAD_##tHREADiD,
|
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) sUBtASKiD##_THREAD = THREAD_##tHREADiD,
|
||||||
#include <tasks_def.h>
|
#include <tasks_def.h>
|
||||||
@@ -98,9 +95,8 @@ typedef enum
|
|||||||
} task_thread_id_t;
|
} task_thread_id_t;
|
||||||
|
|
||||||
//! Tasks id of each task
|
//! Tasks id of each task
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
TASK_UNKNOWN = 0,
|
||||||
TASK_UNKNOWN = 0,
|
|
||||||
|
|
||||||
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) tHREADiD,
|
#define TASK_DEF(tHREADiD, pRIO, qUEUEsIZE) tHREADiD,
|
||||||
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) sUBtASKiD,
|
#define SUB_TASK_DEF(tHREADiD, sUBtASKiD, qUEUEsIZE) sUBtASKiD,
|
||||||
@@ -108,12 +104,11 @@ typedef enum
|
|||||||
#undef SUB_TASK_DEF
|
#undef SUB_TASK_DEF
|
||||||
#undef TASK_DEF
|
#undef TASK_DEF
|
||||||
|
|
||||||
TASK_MAX,
|
TASK_MAX,
|
||||||
TASK_FIRST = 1,
|
TASK_FIRST = 1,
|
||||||
} task_id_t;
|
} task_id_t;
|
||||||
|
|
||||||
typedef union msg_s
|
typedef union msg_s {
|
||||||
{
|
|
||||||
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) sTRUCT fIELDnAME;
|
#define MESSAGE_DEF(iD, pRIO, sTRUCT, fIELDnAME) sTRUCT fIELDnAME;
|
||||||
#include <messages_def.h>
|
#include <messages_def.h>
|
||||||
#undef MESSAGE_DEF
|
#undef MESSAGE_DEF
|
||||||
@@ -121,26 +116,24 @@ typedef union msg_s
|
|||||||
|
|
||||||
typedef uint16_t MessageHeaderSize;
|
typedef uint16_t MessageHeaderSize;
|
||||||
|
|
||||||
typedef struct itti_lte_time_s
|
typedef struct itti_lte_time_s {
|
||||||
{
|
uint32_t frame;
|
||||||
uint32_t frame;
|
uint8_t slot;
|
||||||
uint8_t slot;
|
|
||||||
} itti_lte_time_t;
|
} itti_lte_time_t;
|
||||||
|
|
||||||
/** @struct MessageHeader
|
/** @struct MessageHeader
|
||||||
* @brief Message Header structure for inter-task communication.
|
* @brief Message Header structure for inter-task communication.
|
||||||
*/
|
*/
|
||||||
typedef struct MessageHeader_s
|
typedef struct MessageHeader_s {
|
||||||
{
|
MessagesIds messageId; /**< Unique message id as referenced in enum MessagesIds */
|
||||||
MessagesIds messageId; /**< Unique message id as referenced in enum MessagesIds */
|
|
||||||
|
|
||||||
task_id_t originTaskId; /**< ID of the sender task */
|
task_id_t originTaskId; /**< ID of the sender task */
|
||||||
task_id_t destinationTaskId; /**< ID of the destination task */
|
task_id_t destinationTaskId; /**< ID of the destination task */
|
||||||
instance_t instance; /**< Task instance for virtualization */
|
instance_t instance; /**< Task instance for virtualization */
|
||||||
|
|
||||||
MessageHeaderSize ittiMsgSize; /**< Message size (not including header size) */
|
MessageHeaderSize ittiMsgSize; /**< Message size (not including header size) */
|
||||||
|
|
||||||
itti_lte_time_t lte_time; /**< Reference LTE time */
|
itti_lte_time_t lte_time; /**< Reference LTE time */
|
||||||
} MessageHeader;
|
} MessageHeader;
|
||||||
|
|
||||||
/** @struct MessageDef
|
/** @struct MessageDef
|
||||||
@@ -148,10 +141,9 @@ typedef struct MessageHeader_s
|
|||||||
* \internal
|
* \internal
|
||||||
* The attached attribute \c __packed__ is neccessary, because the memory allocation code expects \ref ittiMsg directly following \ref ittiMsgHeader.
|
* The attached attribute \c __packed__ is neccessary, because the memory allocation code expects \ref ittiMsg directly following \ref ittiMsgHeader.
|
||||||
*/
|
*/
|
||||||
typedef struct __attribute__ ((__packed__)) MessageDef_s
|
typedef struct __attribute__ ((__packed__)) MessageDef_s {
|
||||||
{
|
MessageHeader ittiMsgHeader; /**< Message header */
|
||||||
MessageHeader ittiMsgHeader; /**< Message header */
|
msg_t ittiMsg; /**< Union of payloads as defined in x_messages_def.h headers */
|
||||||
msg_t ittiMsg; /**< Union of payloads as defined in x_messages_def.h headers */
|
|
||||||
} MessageDef;
|
} MessageDef;
|
||||||
|
|
||||||
#endif /* INTERTASK_INTERFACE_TYPES_H_ */
|
#endif /* INTERTASK_INTERFACE_TYPES_H_ */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -38,14 +38,12 @@
|
|||||||
#ifndef INTERTASK_MESSAGES_TYPES_H_
|
#ifndef INTERTASK_MESSAGES_TYPES_H_
|
||||||
#define INTERTASK_MESSAGES_TYPES_H_
|
#define INTERTASK_MESSAGES_TYPES_H_
|
||||||
|
|
||||||
typedef struct IttiMsgEmpty_s
|
typedef struct IttiMsgEmpty_s {
|
||||||
{
|
|
||||||
} IttiMsgEmpty;
|
} IttiMsgEmpty;
|
||||||
|
|
||||||
typedef struct IttiMsgText_s
|
typedef struct IttiMsgText_s {
|
||||||
{
|
uint32_t size;
|
||||||
uint32_t size;
|
char text[];
|
||||||
char text[];
|
|
||||||
} IttiMsgText;
|
} IttiMsgText;
|
||||||
|
|
||||||
#endif /* INTERTASK_MESSAGES_TYPES_H_ */
|
#endif /* INTERTASK_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -42,19 +42,18 @@
|
|||||||
#define MESSAGE_NUMBER_CHAR_FORMAT "%11u"
|
#define MESSAGE_NUMBER_CHAR_FORMAT "%11u"
|
||||||
|
|
||||||
/* Intertask message types */
|
/* Intertask message types */
|
||||||
enum itti_message_types_e
|
enum itti_message_types_e {
|
||||||
{
|
ITTI_DUMP_XML_DEFINITION = CHARS_TO_UINT32 ('\n', 'I', 'x', 'd'),
|
||||||
ITTI_DUMP_XML_DEFINITION = CHARS_TO_UINT32 ('\n', 'I', 'x', 'd'),
|
ITTI_DUMP_XML_DEFINITION_END = CHARS_TO_UINT32 ('i', 'X', 'D', '\n'),
|
||||||
ITTI_DUMP_XML_DEFINITION_END = CHARS_TO_UINT32 ('i', 'X', 'D', '\n'),
|
|
||||||
|
|
||||||
ITTI_DUMP_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 'm', 's'),
|
ITTI_DUMP_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 'm', 's'),
|
||||||
ITTI_DUMP_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'M', 'S', '\n'),
|
ITTI_DUMP_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'M', 'S', '\n'),
|
||||||
|
|
||||||
ITTI_STATISTIC_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 's', 't'),
|
ITTI_STATISTIC_MESSAGE_TYPE = CHARS_TO_UINT32 ('\n', 'I', 's', 't'),
|
||||||
ITTI_STATISTIC_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'S', 'T', '\n'),
|
ITTI_STATISTIC_MESSAGE_TYPE_END = CHARS_TO_UINT32 ('i', 'S', 'T', '\n'),
|
||||||
|
|
||||||
/* This signal is not meant to be used by remote analyzer */
|
/* This signal is not meant to be used by remote analyzer */
|
||||||
ITTI_DUMP_EXIT_SIGNAL = CHARS_TO_UINT32 ('e', 'X', 'I', 'T'),
|
ITTI_DUMP_EXIT_SIGNAL = CHARS_TO_UINT32 ('e', 'X', 'I', 'T'),
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef uint32_t itti_message_types_t;
|
typedef uint32_t itti_message_types_t;
|
||||||
@@ -63,13 +62,13 @@ typedef uint32_t itti_message_types_t;
|
|||||||
* remote process and this one.
|
* remote process and this one.
|
||||||
*/
|
*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* The size of this structure */
|
/* The size of this structure */
|
||||||
uint32_t message_size;
|
uint32_t message_size;
|
||||||
itti_message_types_t message_type;
|
itti_message_types_t message_type;
|
||||||
} itti_socket_header_t;
|
} itti_socket_header_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char message_number_char[12]; /* 9 chars are needed to store an unsigned 32 bits value in decimal, but must be a multiple of 32 bits to avoid alignment issues */
|
char message_number_char[12]; /* 9 chars are needed to store an unsigned 32 bits value in decimal, but must be a multiple of 32 bits to avoid alignment issues */
|
||||||
} itti_signal_header_t;
|
} itti_signal_header_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+345
-360
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -63,18 +63,18 @@ typedef int32_t items_group_position_t;
|
|||||||
typedef int32_t items_group_index_t;
|
typedef int32_t items_group_index_t;
|
||||||
|
|
||||||
typedef union items_group_positions_u {
|
typedef union items_group_positions_u {
|
||||||
uint64_t all;
|
uint64_t all;
|
||||||
struct {
|
struct {
|
||||||
items_group_position_t put;
|
items_group_position_t put;
|
||||||
items_group_position_t get;
|
items_group_position_t get;
|
||||||
} ind;
|
} ind;
|
||||||
} items_group_positions_t;
|
} items_group_positions_t;
|
||||||
|
|
||||||
typedef struct items_group_s {
|
typedef struct items_group_s {
|
||||||
items_group_position_t number_plus_one;
|
items_group_position_t number_plus_one;
|
||||||
volatile uint32_t minimum;
|
volatile uint32_t minimum;
|
||||||
volatile items_group_positions_t positions;
|
volatile items_group_positions_t positions;
|
||||||
volatile items_group_index_t *indexes;
|
volatile items_group_index_t *indexes;
|
||||||
} items_group_t;
|
} items_group_t;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------*/
|
||||||
@@ -95,40 +95,40 @@ typedef uint8_t pool_id_t;
|
|||||||
typedef uint8_t item_status_t;
|
typedef uint8_t item_status_t;
|
||||||
|
|
||||||
typedef struct memory_pool_item_start_s {
|
typedef struct memory_pool_item_start_s {
|
||||||
pool_item_start_mark_t start_mark;
|
pool_item_start_mark_t start_mark;
|
||||||
|
|
||||||
pool_id_t pool_id;
|
pool_id_t pool_id;
|
||||||
item_status_t item_status;
|
item_status_t item_status;
|
||||||
uint16_t info[MEMORY_POOL_ITEM_INFO_NUMBER];
|
uint16_t info[MEMORY_POOL_ITEM_INFO_NUMBER];
|
||||||
} memory_pool_item_start_t;
|
} memory_pool_item_start_t;
|
||||||
|
|
||||||
typedef struct memory_pool_item_end_s {
|
typedef struct memory_pool_item_end_s {
|
||||||
pool_item_end_mark_t end_mark;
|
pool_item_end_mark_t end_mark;
|
||||||
} memory_pool_item_end_t;
|
} memory_pool_item_end_t;
|
||||||
|
|
||||||
typedef struct memory_pool_item_s {
|
typedef struct memory_pool_item_s {
|
||||||
memory_pool_item_start_t start;
|
memory_pool_item_start_t start;
|
||||||
memory_pool_data_t data[0];
|
memory_pool_data_t data[0];
|
||||||
memory_pool_item_end_t end;
|
memory_pool_item_end_t end;
|
||||||
} memory_pool_item_t;
|
} memory_pool_item_t;
|
||||||
|
|
||||||
typedef struct memory_pool_s {
|
typedef struct memory_pool_s {
|
||||||
pool_start_mark_t start_mark;
|
pool_start_mark_t start_mark;
|
||||||
|
|
||||||
pool_id_t pool_id;
|
pool_id_t pool_id;
|
||||||
uint32_t item_data_number;
|
uint32_t item_data_number;
|
||||||
uint32_t pool_item_size;
|
uint32_t pool_item_size;
|
||||||
items_group_t items_group_free;
|
items_group_t items_group_free;
|
||||||
memory_pool_item_t *items;
|
memory_pool_item_t *items;
|
||||||
} memory_pool_t;
|
} memory_pool_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct memory_pools_s {
|
typedef struct memory_pools_s {
|
||||||
pools_start_mark_t start_mark;
|
pools_start_mark_t start_mark;
|
||||||
|
|
||||||
uint32_t pools_number;
|
uint32_t pools_number;
|
||||||
uint32_t pools_defined;
|
uint32_t pools_defined;
|
||||||
memory_pool_t *pools;
|
memory_pool_t *pools;
|
||||||
} memory_pools_t;
|
} memory_pools_t;
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------*/
|
||||||
@@ -149,370 +149,421 @@ static const pools_start_mark_t POOLS_START_MARK = CHARS_TO_UINT32 ('P'
|
|||||||
/*------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------*/
|
||||||
static inline uint32_t items_group_number_items (items_group_t *items_group)
|
static inline uint32_t items_group_number_items (items_group_t *items_group)
|
||||||
{
|
{
|
||||||
return items_group->number_plus_one - 1;
|
return items_group->number_plus_one - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline uint32_t items_group_free_items (items_group_t *items_group)
|
static inline uint32_t items_group_free_items (items_group_t *items_group)
|
||||||
{
|
{
|
||||||
items_group_positions_t positions;
|
items_group_positions_t positions;
|
||||||
uint32_t free_items;
|
uint32_t free_items;
|
||||||
|
|
||||||
positions.all = items_group->positions.all;
|
positions.all = items_group->positions.all;
|
||||||
|
|
||||||
free_items = items_group->number_plus_one + positions.ind.put - positions.ind.get;
|
free_items = items_group->number_plus_one + positions.ind.put - positions.ind.get;
|
||||||
free_items %= items_group->number_plus_one;
|
free_items %= items_group->number_plus_one;
|
||||||
|
|
||||||
return free_items;
|
return free_items;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline items_group_index_t items_group_get_free_item (items_group_t *items_group)
|
static inline items_group_index_t items_group_get_free_item (items_group_t *items_group)
|
||||||
{
|
{
|
||||||
items_group_position_t get_raw;
|
items_group_position_t get_raw;
|
||||||
items_group_position_t put;
|
items_group_position_t put;
|
||||||
items_group_position_t get;
|
items_group_position_t get;
|
||||||
items_group_position_t free_items;
|
items_group_position_t free_items;
|
||||||
|
|
||||||
items_group_index_t index = ITEMS_GROUP_INDEX_INVALID;
|
items_group_index_t index = ITEMS_GROUP_INDEX_INVALID;
|
||||||
|
|
||||||
/* Get current put position */
|
/* Get current put position */
|
||||||
put = items_group->positions.ind.put % items_group->number_plus_one;
|
put = items_group->positions.ind.put % items_group->number_plus_one;
|
||||||
/* Get current get position and increase it */
|
/* Get current get position and increase it */
|
||||||
get_raw = __sync_fetch_and_add (&items_group->positions.ind.get, 1);
|
get_raw = __sync_fetch_and_add (&items_group->positions.ind.get, 1);
|
||||||
get = get_raw % items_group->number_plus_one;
|
get = get_raw % items_group->number_plus_one;
|
||||||
if(put == get)
|
|
||||||
{
|
if(put == get) {
|
||||||
/* No more item free, restore previous position */
|
/* No more item free, restore previous position */
|
||||||
__sync_fetch_and_sub (&items_group->positions.ind.get, 1);
|
__sync_fetch_and_sub (&items_group->positions.ind.get, 1);
|
||||||
|
} else {
|
||||||
|
/* Get index at current get position */
|
||||||
|
index = items_group->indexes[get];
|
||||||
|
|
||||||
|
if (index <= ITEMS_GROUP_INDEX_INVALID) {
|
||||||
|
/* Index has not yet been completely freed, restore previous get position */
|
||||||
|
__sync_fetch_and_sub (&items_group->positions.ind.get, 1);
|
||||||
|
} else {
|
||||||
|
if (get_raw == items_group->number_plus_one) {
|
||||||
|
/* Wrap get position */
|
||||||
|
__sync_fetch_and_sub (&items_group->positions.ind.get, items_group->number_plus_one);
|
||||||
|
}
|
||||||
|
|
||||||
|
free_items = items_group_free_items(items_group);
|
||||||
|
|
||||||
|
/* Updates minimum free items if needed */
|
||||||
|
while (items_group->minimum > free_items) {
|
||||||
|
items_group->minimum = free_items;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Clear index at current get position to indicate that item is free */
|
||||||
|
items_group->indexes[get] = ITEMS_GROUP_INDEX_INVALID;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
{
|
|
||||||
/* Get index at current get position */
|
|
||||||
index = items_group->indexes[get];
|
|
||||||
if (index <= ITEMS_GROUP_INDEX_INVALID)
|
|
||||||
{
|
|
||||||
/* Index has not yet been completely freed, restore previous get position */
|
|
||||||
__sync_fetch_and_sub (&items_group->positions.ind.get, 1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (get_raw == items_group->number_plus_one)
|
|
||||||
{
|
|
||||||
/* Wrap get position */
|
|
||||||
__sync_fetch_and_sub (&items_group->positions.ind.get, items_group->number_plus_one);
|
|
||||||
}
|
|
||||||
|
|
||||||
free_items = items_group_free_items(items_group);
|
return (index);
|
||||||
/* Updates minimum free items if needed */
|
|
||||||
while (items_group->minimum > free_items)
|
|
||||||
{
|
|
||||||
items_group->minimum = free_items;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Clear index at current get position to indicate that item is free */
|
|
||||||
items_group->indexes[get] = ITEMS_GROUP_INDEX_INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return (index);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int items_group_put_free_item (items_group_t *items_group, items_group_index_t index)
|
static inline int items_group_put_free_item (items_group_t *items_group, items_group_index_t index)
|
||||||
{
|
{
|
||||||
items_group_position_t put_raw;
|
items_group_position_t put_raw;
|
||||||
items_group_position_t put;
|
items_group_position_t put;
|
||||||
|
|
||||||
/* Get current put position and increase it */
|
/* Get current put position and increase it */
|
||||||
put_raw = __sync_fetch_and_add (&items_group->positions.ind.put, 1);
|
put_raw = __sync_fetch_and_add (&items_group->positions.ind.put, 1);
|
||||||
put = put_raw % items_group->number_plus_one;
|
put = put_raw % items_group->number_plus_one;
|
||||||
|
|
||||||
if (put_raw == items_group->number_plus_one)
|
if (put_raw == items_group->number_plus_one) {
|
||||||
{
|
/* Wrap position */
|
||||||
/* Wrap position */
|
__sync_fetch_and_sub (&items_group->positions.ind.put, items_group->number_plus_one);
|
||||||
__sync_fetch_and_sub (&items_group->positions.ind.put, items_group->number_plus_one);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
AssertError (items_group->indexes[put] <= ITEMS_GROUP_INDEX_INVALID, return (EXIT_FAILURE),
|
AssertError (items_group->indexes[put] <= ITEMS_GROUP_INDEX_INVALID, return (EXIT_FAILURE),
|
||||||
"Index at current put position (%d) is not marked as free (%d)!\n", put, items_group->number_plus_one);
|
"Index at current put position (%d) is not marked as free (%d)!\n", put, items_group->number_plus_one);
|
||||||
|
|
||||||
/* Save freed item index at current put position */
|
/* Save freed item index at current put position */
|
||||||
items_group->indexes[put] = index;
|
items_group->indexes[put] = index;
|
||||||
return (EXIT_SUCCESS);
|
return (EXIT_SUCCESS);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------*/
|
||||||
static inline memory_pools_t *memory_pools_from_handler (memory_pools_handle_t memory_pools_handle)
|
static inline memory_pools_t *memory_pools_from_handler (memory_pools_handle_t memory_pools_handle)
|
||||||
{
|
{
|
||||||
memory_pools_t *memory_pools;
|
memory_pools_t *memory_pools;
|
||||||
|
|
||||||
/* Recover memory_pools */
|
/* Recover memory_pools */
|
||||||
memory_pools = (memory_pools_t *) memory_pools_handle;
|
memory_pools = (memory_pools_t *) memory_pools_handle;
|
||||||
/* Sanity check on passed handle */
|
/* Sanity check on passed handle */
|
||||||
AssertError (memory_pools->start_mark == POOLS_START_MARK, memory_pools = NULL,
|
AssertError (memory_pools->start_mark == POOLS_START_MARK, memory_pools = NULL,
|
||||||
"Handle %p is not a valid memory pools handle, start mark is missing!\n", memory_pools_handle);
|
"Handle %p is not a valid memory pools handle, start mark is missing!\n", memory_pools_handle);
|
||||||
|
|
||||||
return (memory_pools);
|
return (memory_pools);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline memory_pool_item_t *memory_pool_item_from_handler (memory_pool_item_handle_t memory_pool_item_handle)
|
static inline memory_pool_item_t *memory_pool_item_from_handler (memory_pool_item_handle_t memory_pool_item_handle)
|
||||||
{
|
{
|
||||||
void *address;
|
void *address;
|
||||||
memory_pool_item_t *memory_pool_item;
|
memory_pool_item_t *memory_pool_item;
|
||||||
|
|
||||||
/* Recover memory_pools */
|
/* Recover memory_pools */
|
||||||
address = memory_pool_item_handle - sizeof(memory_pool_item_start_t);
|
address = memory_pool_item_handle - sizeof(memory_pool_item_start_t);
|
||||||
memory_pool_item = (memory_pool_item_t *) address;
|
memory_pool_item = (memory_pool_item_t *) address;
|
||||||
|
|
||||||
/* Sanity check on passed handle */
|
/* Sanity check on passed handle */
|
||||||
AssertError (memory_pool_item->start.start_mark == POOL_ITEM_START_MARK, memory_pool_item = NULL,
|
AssertError (memory_pool_item->start.start_mark == POOL_ITEM_START_MARK, memory_pool_item = NULL,
|
||||||
"Handle %p is not a valid memory pool item handle, start mark is missing!\n", memory_pool_item);
|
"Handle %p is not a valid memory pool item handle, start mark is missing!\n", memory_pool_item);
|
||||||
|
|
||||||
return (memory_pool_item);
|
return (memory_pool_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline memory_pool_item_t *memory_pool_item_from_index (memory_pool_t *memory_pool, items_group_index_t index)
|
static inline memory_pool_item_t *memory_pool_item_from_index (memory_pool_t *memory_pool, items_group_index_t index)
|
||||||
{
|
{
|
||||||
void *address;
|
void *address;
|
||||||
|
|
||||||
address = (void *) memory_pool->items;
|
address = (void *) memory_pool->items;
|
||||||
address += index * memory_pool->pool_item_size;
|
address += index * memory_pool->pool_item_size;
|
||||||
|
|
||||||
return (address);
|
return (address);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*------------------------------------------------------------------------------*/
|
/*------------------------------------------------------------------------------*/
|
||||||
memory_pools_handle_t memory_pools_create (uint32_t pools_number)
|
memory_pools_handle_t memory_pools_create (uint32_t pools_number)
|
||||||
{
|
{
|
||||||
memory_pools_t *memory_pools;
|
memory_pools_t *memory_pools;
|
||||||
pool_id_t pool;
|
pool_id_t pool;
|
||||||
|
|
||||||
AssertFatal (pools_number <= MAX_POOLS_NUMBER, "Too many memory pools requested (%d/%d)!\n", pools_number, MAX_POOLS_NUMBER); /* Limit to a reasonable number of pools */
|
AssertFatal (pools_number <= MAX_POOLS_NUMBER, "Too many memory pools requested (%d/%d)!\n", pools_number, MAX_POOLS_NUMBER); /* Limit to a reasonable number of pools */
|
||||||
|
|
||||||
/* Allocate memory_pools */
|
/* Allocate memory_pools */
|
||||||
memory_pools = malloc (sizeof(memory_pools_t));
|
memory_pools = malloc (sizeof(memory_pools_t));
|
||||||
AssertFatal (memory_pools != NULL, "Memory pools structure allocation failed!\n");
|
AssertFatal (memory_pools != NULL, "Memory pools structure allocation failed!\n");
|
||||||
|
|
||||||
/* Initialize memory_pools */
|
/* Initialize memory_pools */
|
||||||
{
|
{
|
||||||
memory_pools->start_mark = POOLS_START_MARK;
|
memory_pools->start_mark = POOLS_START_MARK;
|
||||||
memory_pools->pools_number = pools_number;
|
memory_pools->pools_number = pools_number;
|
||||||
memory_pools->pools_defined = 0;
|
memory_pools->pools_defined = 0;
|
||||||
|
|
||||||
/* Allocate pools */
|
/* Allocate pools */
|
||||||
memory_pools->pools = calloc (pools_number, sizeof(memory_pool_t));
|
memory_pools->pools = calloc (pools_number, sizeof(memory_pool_t));
|
||||||
AssertFatal (memory_pools->pools != NULL, "Memory pools allocation failed!\n");
|
AssertFatal (memory_pools->pools != NULL, "Memory pools allocation failed!\n");
|
||||||
|
|
||||||
/* Initialize pools */
|
/* Initialize pools */
|
||||||
for (pool = 0; pool < pools_number; pool++)
|
for (pool = 0; pool < pools_number; pool++) {
|
||||||
{
|
memory_pools->pools[pool].start_mark = POOL_START_MARK;
|
||||||
memory_pools->pools[pool].start_mark = POOL_START_MARK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return ((memory_pools_handle_t) memory_pools);
|
return ((memory_pools_handle_t) memory_pools);
|
||||||
}
|
}
|
||||||
|
|
||||||
char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle)
|
char *memory_pools_statistics(memory_pools_handle_t memory_pools_handle)
|
||||||
{
|
{
|
||||||
memory_pools_t *memory_pools;
|
memory_pools_t *memory_pools;
|
||||||
pool_id_t pool;
|
pool_id_t pool;
|
||||||
char *statistics;
|
char *statistics;
|
||||||
int printed_chars;
|
int printed_chars;
|
||||||
uint32_t allocated_pool_memory;
|
uint32_t allocated_pool_memory;
|
||||||
uint32_t allocated_pools_memory = 0;
|
uint32_t allocated_pools_memory = 0;
|
||||||
items_group_t *items_group;
|
items_group_t *items_group;
|
||||||
uint32_t pool_items_size;
|
uint32_t pool_items_size;
|
||||||
|
|
||||||
/* Recover memory_pools */
|
/* Recover memory_pools */
|
||||||
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
||||||
AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle);
|
AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle);
|
||||||
|
|
||||||
statistics = malloc(memory_pools->pools_defined * 200);
|
statistics = malloc(memory_pools->pools_defined * 200);
|
||||||
|
|
||||||
printed_chars = sprintf (&statistics[0], "Pool: size, number, minimum, free, address space and memory used in Kbytes\n");
|
printed_chars = sprintf (&statistics[0], "Pool: size, number, minimum, free, address space and memory used in Kbytes\n");
|
||||||
for (pool = 0; pool < memory_pools->pools_defined; pool++)
|
|
||||||
{
|
|
||||||
items_group = &memory_pools->pools[pool].items_group_free;
|
|
||||||
allocated_pool_memory = items_group_number_items (items_group) * memory_pools->pools[pool].pool_item_size;
|
|
||||||
allocated_pools_memory += allocated_pool_memory;
|
|
||||||
pool_items_size = memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t);
|
|
||||||
printed_chars += sprintf (&statistics[printed_chars], " %2u: %6u, %6u, %6u, %6u, [%p-%p] %6u\n",
|
|
||||||
pool, pool_items_size,
|
|
||||||
items_group_number_items (items_group),
|
|
||||||
items_group->minimum,
|
|
||||||
items_group_free_items (items_group),
|
|
||||||
memory_pools->pools[pool].items,
|
|
||||||
((void *) memory_pools->pools[pool].items) + allocated_pool_memory,
|
|
||||||
allocated_pool_memory / (1024));
|
|
||||||
}
|
|
||||||
printed_chars = sprintf (&statistics[printed_chars], "Pools memory %u Kbytes\n", allocated_pools_memory / (1024));
|
|
||||||
|
|
||||||
return (statistics);
|
for (pool = 0; pool < memory_pools->pools_defined; pool++) {
|
||||||
|
items_group = &memory_pools->pools[pool].items_group_free;
|
||||||
|
allocated_pool_memory = items_group_number_items (items_group) * memory_pools->pools[pool].pool_item_size;
|
||||||
|
allocated_pools_memory += allocated_pool_memory;
|
||||||
|
pool_items_size = memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t);
|
||||||
|
printed_chars += sprintf (&statistics[printed_chars], " %2u: %6u, %6u, %6u, %6u, [%p-%p] %6u\n",
|
||||||
|
pool, pool_items_size,
|
||||||
|
items_group_number_items (items_group),
|
||||||
|
items_group->minimum,
|
||||||
|
items_group_free_items (items_group),
|
||||||
|
memory_pools->pools[pool].items,
|
||||||
|
((void *) memory_pools->pools[pool].items) + allocated_pool_memory,
|
||||||
|
allocated_pool_memory / (1024));
|
||||||
|
}
|
||||||
|
|
||||||
|
printed_chars = sprintf (&statistics[printed_chars], "Pools memory %u Kbytes\n", allocated_pools_memory / (1024));
|
||||||
|
|
||||||
|
return (statistics);
|
||||||
}
|
}
|
||||||
|
|
||||||
int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size)
|
int memory_pools_add_pool (memory_pools_handle_t memory_pools_handle, uint32_t pool_items_number, uint32_t pool_item_size)
|
||||||
{
|
{
|
||||||
memory_pools_t *memory_pools;
|
memory_pools_t *memory_pools;
|
||||||
memory_pool_t *memory_pool;
|
memory_pool_t *memory_pool;
|
||||||
pool_id_t pool;
|
pool_id_t pool;
|
||||||
items_group_index_t item_index;
|
items_group_index_t item_index;
|
||||||
memory_pool_item_t *memory_pool_item;
|
memory_pool_item_t *memory_pool_item;
|
||||||
|
|
||||||
AssertFatal (pool_items_number <= MAX_POOL_ITEMS_NUMBER, "Too many items for a memory pool (%u/%d)!\n", pool_items_number, MAX_POOL_ITEMS_NUMBER); /* Limit to a reasonable number of items */
|
AssertFatal (pool_items_number <= MAX_POOL_ITEMS_NUMBER, "Too many items for a memory pool (%u/%d)!\n", pool_items_number, MAX_POOL_ITEMS_NUMBER); /* Limit to a reasonable number of items */
|
||||||
AssertFatal (pool_item_size <= MAX_POOL_ITEM_SIZE, "Item size is too big for memory pool items (%u/%d)!\n", pool_item_size, MAX_POOL_ITEM_SIZE); /* Limit to a reasonable item size */
|
AssertFatal (pool_item_size <= MAX_POOL_ITEM_SIZE, "Item size is too big for memory pool items (%u/%d)!\n", pool_item_size, MAX_POOL_ITEM_SIZE); /* Limit to a reasonable item size */
|
||||||
|
|
||||||
/* Recover memory_pools */
|
/* Recover memory_pools */
|
||||||
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
||||||
AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle);
|
AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle);
|
||||||
|
|
||||||
/* Check number of already created pools */
|
/* Check number of already created pools */
|
||||||
AssertFatal (memory_pools->pools_defined < memory_pools->pools_number, "Can not allocate more memory pool (%d)!\n", memory_pools->pools_number);
|
AssertFatal (memory_pools->pools_defined < memory_pools->pools_number, "Can not allocate more memory pool (%d)!\n", memory_pools->pools_number);
|
||||||
|
|
||||||
/* Select pool */
|
/* Select pool */
|
||||||
pool = memory_pools->pools_defined;
|
pool = memory_pools->pools_defined;
|
||||||
memory_pool = &memory_pools->pools[pool];
|
memory_pool = &memory_pools->pools[pool];
|
||||||
|
|
||||||
/* Initialize pool */
|
/* Initialize pool */
|
||||||
{
|
{
|
||||||
memory_pool->pool_id = pool;
|
memory_pool->pool_id = pool;
|
||||||
/* Item size in memory_pool_data_t items by excess */
|
/* Item size in memory_pool_data_t items by excess */
|
||||||
memory_pool->item_data_number = (pool_item_size + sizeof(memory_pool_data_t) - 1) / sizeof(memory_pool_data_t);
|
memory_pool->item_data_number = (pool_item_size + sizeof(memory_pool_data_t) - 1) / sizeof(memory_pool_data_t);
|
||||||
memory_pool->pool_item_size = (memory_pool->item_data_number * sizeof(memory_pool_data_t)) + sizeof(memory_pool_item_t);
|
memory_pool->pool_item_size = (memory_pool->item_data_number * sizeof(memory_pool_data_t)) + sizeof(memory_pool_item_t);
|
||||||
memory_pool->items_group_free.number_plus_one = pool_items_number + 1;
|
memory_pool->items_group_free.number_plus_one = pool_items_number + 1;
|
||||||
memory_pool->items_group_free.minimum = pool_items_number;
|
memory_pool->items_group_free.minimum = pool_items_number;
|
||||||
memory_pool->items_group_free.positions.ind.put = pool_items_number;
|
memory_pool->items_group_free.positions.ind.put = pool_items_number;
|
||||||
memory_pool->items_group_free.positions.ind.get = 0;
|
memory_pool->items_group_free.positions.ind.get = 0;
|
||||||
|
|
||||||
/* Allocate free indexes */
|
/* Allocate free indexes */
|
||||||
memory_pool->items_group_free.indexes = malloc(memory_pool->items_group_free.number_plus_one * sizeof(items_group_index_t));
|
memory_pool->items_group_free.indexes = malloc(memory_pool->items_group_free.number_plus_one * sizeof(items_group_index_t));
|
||||||
AssertFatal (memory_pool->items_group_free.indexes != NULL, "Memory pool indexes allocation failed!\n");
|
AssertFatal (memory_pool->items_group_free.indexes != NULL, "Memory pool indexes allocation failed!\n");
|
||||||
|
|
||||||
/* Initialize free indexes */
|
/* Initialize free indexes */
|
||||||
for (item_index = 0; item_index < pool_items_number; item_index++)
|
for (item_index = 0; item_index < pool_items_number; item_index++) {
|
||||||
{
|
memory_pool->items_group_free.indexes[item_index] = item_index;
|
||||||
memory_pool->items_group_free.indexes[item_index] = item_index;
|
|
||||||
}
|
|
||||||
/* Last index is not allocated */
|
|
||||||
memory_pool->items_group_free.indexes[item_index] = ITEMS_GROUP_INDEX_INVALID;
|
|
||||||
|
|
||||||
/* Allocate items */
|
|
||||||
memory_pool->items = calloc (pool_items_number, memory_pool->pool_item_size);
|
|
||||||
AssertFatal (memory_pool->items != NULL, "Memory pool items allocation failed!\n");
|
|
||||||
|
|
||||||
/* Initialize items */
|
|
||||||
for (item_index = 0; item_index < pool_items_number; item_index++)
|
|
||||||
{
|
|
||||||
memory_pool_item = memory_pool_item_from_index (memory_pool, item_index);
|
|
||||||
memory_pool_item->start.start_mark = POOL_ITEM_START_MARK;
|
|
||||||
memory_pool_item->start.pool_id = pool;
|
|
||||||
memory_pool_item->start.item_status = ITEM_STATUS_FREE;
|
|
||||||
memory_pool_item->data[memory_pool->item_data_number] = POOL_ITEM_END_MARK;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_pools->pools_defined ++;
|
/* Last index is not allocated */
|
||||||
|
memory_pool->items_group_free.indexes[item_index] = ITEMS_GROUP_INDEX_INVALID;
|
||||||
|
|
||||||
return (0);
|
/* Allocate items */
|
||||||
|
memory_pool->items = calloc (pool_items_number, memory_pool->pool_item_size);
|
||||||
|
AssertFatal (memory_pool->items != NULL, "Memory pool items allocation failed!\n");
|
||||||
|
|
||||||
|
/* Initialize items */
|
||||||
|
for (item_index = 0; item_index < pool_items_number; item_index++) {
|
||||||
|
memory_pool_item = memory_pool_item_from_index (memory_pool, item_index);
|
||||||
|
memory_pool_item->start.start_mark = POOL_ITEM_START_MARK;
|
||||||
|
memory_pool_item->start.pool_id = pool;
|
||||||
|
memory_pool_item->start.item_status = ITEM_STATUS_FREE;
|
||||||
|
memory_pool_item->data[memory_pool->item_data_number] = POOL_ITEM_END_MARK;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memory_pools->pools_defined ++;
|
||||||
|
|
||||||
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_pools_handle, uint32_t item_size, uint16_t info_0, uint16_t info_1)
|
memory_pool_item_handle_t memory_pools_allocate (memory_pools_handle_t memory_pools_handle, uint32_t item_size, uint16_t info_0, uint16_t info_1)
|
||||||
{
|
{
|
||||||
memory_pools_t *memory_pools;
|
memory_pools_t *memory_pools;
|
||||||
memory_pool_item_t *memory_pool_item;
|
memory_pool_item_t *memory_pool_item;
|
||||||
memory_pool_item_handle_t memory_pool_item_handle = NULL;
|
memory_pool_item_handle_t memory_pool_item_handle = NULL;
|
||||||
pool_id_t pool;
|
pool_id_t pool;
|
||||||
items_group_index_t item_index = ITEMS_GROUP_INDEX_INVALID;
|
items_group_index_t item_index = ITEMS_GROUP_INDEX_INVALID;
|
||||||
|
|
||||||
#if defined(OAI_EMU) || defined(RTAI)
|
#if defined(OAI_EMU) || defined(RTAI)
|
||||||
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC,
|
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC,
|
||||||
__sync_or_and_fetch (&vcd_mp_alloc, 1L << info_0));
|
__sync_or_and_fetch (&vcd_mp_alloc, 1L << info_0));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Recover memory_pools */
|
/* Recover memory_pools */
|
||||||
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
||||||
AssertError (memory_pools != NULL, {}, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle);
|
AssertError (memory_pools != NULL, {}, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle);
|
||||||
|
|
||||||
for (pool = 0; pool < memory_pools->pools_defined; pool++)
|
for (pool = 0; pool < memory_pools->pools_defined; pool++) {
|
||||||
{
|
if ((memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t)) < item_size) {
|
||||||
if ((memory_pools->pools[pool].item_data_number * sizeof(memory_pool_data_t)) < item_size)
|
/* This memory pool has too small items, skip it */
|
||||||
{
|
continue;
|
||||||
/* This memory pool has too small items, skip it */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
item_index = items_group_get_free_item(&memory_pools->pools[pool].items_group_free);
|
|
||||||
if (item_index <= ITEMS_GROUP_INDEX_INVALID)
|
|
||||||
{
|
|
||||||
/* Allocation failed, skip this pool */
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Allocation succeed, exit searching loop */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (item_index > ITEMS_GROUP_INDEX_INVALID)
|
item_index = items_group_get_free_item(&memory_pools->pools[pool].items_group_free);
|
||||||
{
|
|
||||||
/* Convert item index into memory_pool_item address */
|
|
||||||
memory_pool_item = memory_pool_item_from_index (&memory_pools->pools[pool], item_index);
|
|
||||||
/* Sanity check on item status, must be free */
|
|
||||||
AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_FREE, "Item status is not set to free (%d) in pool %u, item %d!\n",
|
|
||||||
memory_pool_item->start.item_status, pool, item_index);
|
|
||||||
|
|
||||||
memory_pool_item->start.item_status = ITEM_STATUS_ALLOCATED;
|
if (item_index <= ITEMS_GROUP_INDEX_INVALID) {
|
||||||
memory_pool_item->start.info[0] = info_0;
|
/* Allocation failed, skip this pool */
|
||||||
memory_pool_item->start.info[1] = info_1;
|
continue;
|
||||||
memory_pool_item_handle = memory_pool_item->data;
|
} else {
|
||||||
|
/* Allocation succeed, exit searching loop */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
MP_DEBUG(" Alloc [%2u][%6d]{%6d}, %3u %3u, %6u, %p, %p, %p\n",
|
if (item_index > ITEMS_GROUP_INDEX_INVALID) {
|
||||||
pool, item_index,
|
/* Convert item index into memory_pool_item address */
|
||||||
items_group_free_items (&memory_pools->pools[pool].items_group_free),
|
memory_pool_item = memory_pool_item_from_index (&memory_pools->pools[pool], item_index);
|
||||||
info_0, info_1,
|
/* Sanity check on item status, must be free */
|
||||||
item_size,
|
AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_FREE, "Item status is not set to free (%d) in pool %u, item %d!\n",
|
||||||
memory_pools->pools[pool].items,
|
memory_pool_item->start.item_status, pool, item_index);
|
||||||
memory_pool_item,
|
|
||||||
memory_pool_item_handle);
|
memory_pool_item->start.item_status = ITEM_STATUS_ALLOCATED;
|
||||||
}
|
memory_pool_item->start.info[0] = info_0;
|
||||||
else
|
memory_pool_item->start.info[1] = info_1;
|
||||||
{
|
memory_pool_item_handle = memory_pool_item->data;
|
||||||
MP_DEBUG(" Alloc [--][------]{------}, %3u %3u, %6u, failed!\n", info_0, info_1, item_size);
|
|
||||||
}
|
MP_DEBUG(" Alloc [%2u][%6d]{%6d}, %3u %3u, %6u, %p, %p, %p\n",
|
||||||
|
pool, item_index,
|
||||||
|
items_group_free_items (&memory_pools->pools[pool].items_group_free),
|
||||||
|
info_0, info_1,
|
||||||
|
item_size,
|
||||||
|
memory_pools->pools[pool].items,
|
||||||
|
memory_pool_item,
|
||||||
|
memory_pool_item_handle);
|
||||||
|
} else {
|
||||||
|
MP_DEBUG(" Alloc [--][------]{------}, %3u %3u, %6u, failed!\n", info_0, info_1, item_size);
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(OAI_EMU) || defined(RTAI)
|
#if defined(OAI_EMU) || defined(RTAI)
|
||||||
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC,
|
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLE_MP_ALLOC,
|
||||||
__sync_and_and_fetch (&vcd_mp_alloc, ~(1L << info_0)));
|
__sync_and_and_fetch (&vcd_mp_alloc, ~(1L << info_0)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return memory_pool_item_handle;
|
return memory_pool_item_handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0)
|
int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, uint16_t info_0)
|
||||||
{
|
{
|
||||||
memory_pools_t *memory_pools;
|
memory_pools_t *memory_pools;
|
||||||
memory_pool_item_t *memory_pool_item;
|
memory_pool_item_t *memory_pool_item;
|
||||||
pool_id_t pool;
|
pool_id_t pool;
|
||||||
items_group_index_t item_index;
|
items_group_index_t item_index;
|
||||||
uint32_t item_size;
|
uint32_t item_size;
|
||||||
uint32_t pool_item_size;
|
uint32_t pool_item_size;
|
||||||
uint16_t info_1;
|
uint16_t info_1;
|
||||||
int result;
|
int result;
|
||||||
|
|
||||||
/* Recover memory_pools */
|
/* Recover memory_pools */
|
||||||
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
||||||
AssertError (memory_pools != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pools for handle %p!\n", memory_pools_handle);
|
AssertError (memory_pools != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pools for handle %p!\n", memory_pools_handle);
|
||||||
|
|
||||||
/* Recover memory pool item */
|
/* Recover memory pool item */
|
||||||
memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle);
|
memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle);
|
||||||
AssertError (memory_pool_item != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle);
|
AssertError (memory_pool_item != NULL, return (EXIT_FAILURE), "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle);
|
||||||
|
|
||||||
info_1 = memory_pool_item->start.info[1];
|
info_1 = memory_pool_item->start.info[1];
|
||||||
|
|
||||||
#if defined(OAI_EMU) || defined(RTAI)
|
#if defined(OAI_EMU) || defined(RTAI)
|
||||||
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE,
|
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE,
|
||||||
__sync_or_and_fetch (&vcd_mp_free, 1L << info_1));
|
__sync_or_and_fetch (&vcd_mp_free, 1L << info_1));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Recover pool index */
|
||||||
|
pool = memory_pool_item->start.pool_id;
|
||||||
|
AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined);
|
||||||
|
|
||||||
|
item_size = memory_pools->pools[pool].item_data_number;
|
||||||
|
pool_item_size = memory_pools->pools[pool].pool_item_size;
|
||||||
|
item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size;
|
||||||
|
|
||||||
|
MP_DEBUG(" Free [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n",
|
||||||
|
pool, item_index,
|
||||||
|
items_group_free_items (&memory_pools->pools[pool].items_group_free),
|
||||||
|
memory_pool_item->start.info[0], info_1,
|
||||||
|
memory_pool_item_handle, memory_pool_item,
|
||||||
|
memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t))));
|
||||||
|
|
||||||
|
/* Sanity check on calculated item index */
|
||||||
|
AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index),
|
||||||
|
"Incorrect memory pool item address (%p, %p) for pool %u, item %d!\n",
|
||||||
|
memory_pool_item, memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index);
|
||||||
|
/* Sanity check on end marker, must still be present (no write overflow) */
|
||||||
|
AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK,
|
||||||
|
"Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index);
|
||||||
|
/* Sanity check on item status, must be allocated */
|
||||||
|
AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED,
|
||||||
|
"Trying to free a non allocated (%x) memory pool item (pool %u, item %d)!\n",
|
||||||
|
memory_pool_item->start.item_status, pool, item_index);
|
||||||
|
|
||||||
|
memory_pool_item->start.item_status = ITEM_STATUS_FREE;
|
||||||
|
|
||||||
|
result = items_group_put_free_item(&memory_pools->pools[pool].items_group_free, item_index);
|
||||||
|
|
||||||
|
AssertError (result == EXIT_SUCCESS, {}, "Failed to free memory pool item (pool %u, item %d)!\n", pool, item_index);
|
||||||
|
|
||||||
|
#if defined(OAI_EMU) || defined(RTAI)
|
||||||
|
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE,
|
||||||
|
__sync_and_and_fetch (&vcd_mp_free, ~(1L << info_1)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info)
|
||||||
|
{
|
||||||
|
memory_pools_t *memory_pools;
|
||||||
|
memory_pool_item_t *memory_pool_item;
|
||||||
|
pool_id_t pool;
|
||||||
|
items_group_index_t item_index;
|
||||||
|
uint32_t item_size;
|
||||||
|
uint32_t pool_item_size;
|
||||||
|
|
||||||
|
AssertFatal (index < MEMORY_POOL_ITEM_INFO_NUMBER, "Incorrect info index (%d/%d)!\n", index, MEMORY_POOL_ITEM_INFO_NUMBER);
|
||||||
|
|
||||||
|
/* Recover memory pool item */
|
||||||
|
memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle);
|
||||||
|
AssertFatal (memory_pool_item != NULL, "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle);
|
||||||
|
|
||||||
|
/* Set info[1] */
|
||||||
|
memory_pool_item->start.info[index] = info;
|
||||||
|
|
||||||
|
/* Check item validity and log (not mandatory) */
|
||||||
|
if (1) {
|
||||||
|
/* Recover memory_pools */
|
||||||
|
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
||||||
|
AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle);
|
||||||
|
|
||||||
/* Recover pool index */
|
/* Recover pool index */
|
||||||
pool = memory_pool_item->start.pool_id;
|
pool = memory_pool_item->start.pool_id;
|
||||||
AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined);
|
AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined);
|
||||||
@@ -521,10 +572,10 @@ int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_it
|
|||||||
pool_item_size = memory_pools->pools[pool].pool_item_size;
|
pool_item_size = memory_pools->pools[pool].pool_item_size;
|
||||||
item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size;
|
item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size;
|
||||||
|
|
||||||
MP_DEBUG(" Free [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n",
|
MP_DEBUG(" Info [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n",
|
||||||
pool, item_index,
|
pool, item_index,
|
||||||
items_group_free_items (&memory_pools->pools[pool].items_group_free),
|
items_group_free_items (&memory_pools->pools[pool].items_group_free),
|
||||||
memory_pool_item->start.info[0], info_1,
|
memory_pool_item->start.info[0], memory_pool_item->start.info[1],
|
||||||
memory_pool_item_handle, memory_pool_item,
|
memory_pool_item_handle, memory_pool_item,
|
||||||
memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t))));
|
memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t))));
|
||||||
|
|
||||||
@@ -537,73 +588,7 @@ int memory_pools_free (memory_pools_handle_t memory_pools_handle, memory_pool_it
|
|||||||
"Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index);
|
"Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index);
|
||||||
/* Sanity check on item status, must be allocated */
|
/* Sanity check on item status, must be allocated */
|
||||||
AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED,
|
AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED,
|
||||||
"Trying to free a non allocated (%x) memory pool item (pool %u, item %d)!\n",
|
"Trying to free a non allocated (%x) memory pool item (pool %u, item %d)\n",
|
||||||
memory_pool_item->start.item_status, pool, item_index);
|
memory_pool_item->start.item_status, pool, item_index);
|
||||||
|
}
|
||||||
memory_pool_item->start.item_status = ITEM_STATUS_FREE;
|
|
||||||
|
|
||||||
result = items_group_put_free_item(&memory_pools->pools[pool].items_group_free, item_index);
|
|
||||||
|
|
||||||
AssertError (result == EXIT_SUCCESS, {}, "Failed to free memory pool item (pool %u, item %d)!\n", pool, item_index);
|
|
||||||
|
|
||||||
#if defined(OAI_EMU) || defined(RTAI)
|
|
||||||
vcd_signal_dumper_dump_variable_by_name(VCD_SIGNAL_DUMPER_VARIABLE_MP_FREE,
|
|
||||||
__sync_and_and_fetch (&vcd_mp_free, ~(1L << info_1)));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return (result);
|
|
||||||
}
|
|
||||||
|
|
||||||
void memory_pools_set_info (memory_pools_handle_t memory_pools_handle, memory_pool_item_handle_t memory_pool_item_handle, int index, uint16_t info)
|
|
||||||
{
|
|
||||||
memory_pools_t *memory_pools;
|
|
||||||
memory_pool_item_t *memory_pool_item;
|
|
||||||
pool_id_t pool;
|
|
||||||
items_group_index_t item_index;
|
|
||||||
uint32_t item_size;
|
|
||||||
uint32_t pool_item_size;
|
|
||||||
|
|
||||||
AssertFatal (index < MEMORY_POOL_ITEM_INFO_NUMBER, "Incorrect info index (%d/%d)!\n", index, MEMORY_POOL_ITEM_INFO_NUMBER);
|
|
||||||
|
|
||||||
/* Recover memory pool item */
|
|
||||||
memory_pool_item = memory_pool_item_from_handler (memory_pool_item_handle);
|
|
||||||
AssertFatal (memory_pool_item != NULL, "Failed to retrieve memory pool item for handle %p!\n", memory_pool_item_handle);
|
|
||||||
|
|
||||||
/* Set info[1] */
|
|
||||||
memory_pool_item->start.info[index] = info;
|
|
||||||
|
|
||||||
/* Check item validity and log (not mandatory) */
|
|
||||||
if (1)
|
|
||||||
{
|
|
||||||
/* Recover memory_pools */
|
|
||||||
memory_pools = memory_pools_from_handler (memory_pools_handle);
|
|
||||||
AssertFatal (memory_pools != NULL, "Failed to retrieve memory pool for handle %p!\n", memory_pools_handle);
|
|
||||||
|
|
||||||
/* Recover pool index */
|
|
||||||
pool = memory_pool_item->start.pool_id;
|
|
||||||
AssertFatal (pool < memory_pools->pools_defined, "Pool index is invalid (%u/%u)!\n", pool, memory_pools->pools_defined);
|
|
||||||
|
|
||||||
item_size = memory_pools->pools[pool].item_data_number;
|
|
||||||
pool_item_size = memory_pools->pools[pool].pool_item_size;
|
|
||||||
item_index = (((void *) memory_pool_item) - ((void *) memory_pools->pools[pool].items)) / pool_item_size;
|
|
||||||
|
|
||||||
MP_DEBUG(" Info [%2u][%6d]{%6d}, %3u %3u, %p, %p, %p, %u\n",
|
|
||||||
pool, item_index,
|
|
||||||
items_group_free_items (&memory_pools->pools[pool].items_group_free),
|
|
||||||
memory_pool_item->start.info[0], memory_pool_item->start.info[1],
|
|
||||||
memory_pool_item_handle, memory_pool_item,
|
|
||||||
memory_pools->pools[pool].items, ((uint32_t) (item_size * sizeof(memory_pool_data_t))));
|
|
||||||
|
|
||||||
/* Sanity check on calculated item index */
|
|
||||||
AssertFatal (memory_pool_item == memory_pool_item_from_index(&memory_pools->pools[pool], item_index),
|
|
||||||
"Incorrect memory pool item address (%p, %p) for pool %u, item %d!\n",
|
|
||||||
memory_pool_item, memory_pool_item_from_index(&memory_pools->pools[pool], item_index), pool, item_index);
|
|
||||||
/* Sanity check on end marker, must still be present (no write overflow) */
|
|
||||||
AssertFatal (memory_pool_item->data[item_size] == POOL_ITEM_END_MARK,
|
|
||||||
"Memory pool item is corrupted, end mark is not present for pool %u, item %d!\n", pool, item_index);
|
|
||||||
/* Sanity check on item status, must be allocated */
|
|
||||||
AssertFatal (memory_pool_item->start.item_status == ITEM_STATUS_ALLOCATED,
|
|
||||||
"Trying to free a non allocated (%x) memory pool item (pool %u, item %d)\n",
|
|
||||||
memory_pool_item->start.item_status, pool, item_index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
+73
-73
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -65,85 +65,85 @@ static sigset_t set;
|
|||||||
|
|
||||||
int signal_mask(void)
|
int signal_mask(void)
|
||||||
{
|
{
|
||||||
/* We set the signal mask to avoid threads other than the main thread
|
/* We set the signal mask to avoid threads other than the main thread
|
||||||
* to receive the timer signal. Note that threads created will inherit this
|
* to receive the timer signal. Note that threads created will inherit this
|
||||||
* configuration.
|
* configuration.
|
||||||
*/
|
*/
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
|
|
||||||
sigaddset (&set, SIGTIMER);
|
sigaddset (&set, SIGTIMER);
|
||||||
sigaddset (&set, SIGUSR1);
|
sigaddset (&set, SIGUSR1);
|
||||||
sigaddset (&set, SIGABRT);
|
sigaddset (&set, SIGABRT);
|
||||||
sigaddset (&set, SIGSEGV);
|
sigaddset (&set, SIGSEGV);
|
||||||
sigaddset (&set, SIGINT);
|
sigaddset (&set, SIGINT);
|
||||||
|
|
||||||
if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) {
|
if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) {
|
||||||
perror ("sigprocmask");
|
perror ("sigprocmask");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int signal_handle(int *end)
|
int signal_handle(int *end)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
siginfo_t info;
|
siginfo_t info;
|
||||||
|
|
||||||
sigemptyset(&set);
|
sigemptyset(&set);
|
||||||
|
|
||||||
sigaddset (&set, SIGTIMER);
|
sigaddset (&set, SIGTIMER);
|
||||||
sigaddset (&set, SIGUSR1);
|
sigaddset (&set, SIGUSR1);
|
||||||
sigaddset (&set, SIGABRT);
|
sigaddset (&set, SIGABRT);
|
||||||
sigaddset (&set, SIGSEGV);
|
sigaddset (&set, SIGSEGV);
|
||||||
sigaddset (&set, SIGINT);
|
sigaddset (&set, SIGINT);
|
||||||
|
|
||||||
if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) {
|
if (sigprocmask(SIG_BLOCK, &set, NULL) < 0) {
|
||||||
perror ("sigprocmask");
|
perror ("sigprocmask");
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Block till a signal is received.
|
||||||
|
* NOTE: The signals defined by set are required to be blocked at the time
|
||||||
|
* of the call to sigwait() otherwise sigwait() is not successful.
|
||||||
|
*/
|
||||||
|
if ((ret = sigwaitinfo(&set, &info)) == -1) {
|
||||||
|
perror ("sigwait");
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("Received signal %d\n", info.si_signo);
|
||||||
|
|
||||||
|
/* Real-time signals are non constant and are therefore not suitable for
|
||||||
|
* use in switch.
|
||||||
|
*/
|
||||||
|
if (info.si_signo == SIGTIMER) {
|
||||||
|
timer_handle_signal(&info);
|
||||||
|
} else {
|
||||||
|
/* Dispatch the signal to sub-handlers */
|
||||||
|
switch(info.si_signo) {
|
||||||
|
case SIGUSR1:
|
||||||
|
SIG_DEBUG("Received SIGUSR1\n");
|
||||||
|
*end = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGSEGV: /* Fall through */
|
||||||
|
case SIGABRT:
|
||||||
|
SIG_DEBUG("Received SIGABORT\n");
|
||||||
|
backtrace_handle_signal(&info);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SIGINT:
|
||||||
|
printf("Received SIGINT\n");
|
||||||
|
itti_send_terminate_message(TASK_UNKNOWN);
|
||||||
|
*end = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
SIG_ERROR("Received unknown signal %d\n", info.si_signo);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Block till a signal is received.
|
return 0;
|
||||||
* NOTE: The signals defined by set are required to be blocked at the time
|
|
||||||
* of the call to sigwait() otherwise sigwait() is not successful.
|
|
||||||
*/
|
|
||||||
if ((ret = sigwaitinfo(&set, &info)) == -1) {
|
|
||||||
perror ("sigwait");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Received signal %d\n", info.si_signo);
|
|
||||||
|
|
||||||
/* Real-time signals are non constant and are therefore not suitable for
|
|
||||||
* use in switch.
|
|
||||||
*/
|
|
||||||
if (info.si_signo == SIGTIMER) {
|
|
||||||
timer_handle_signal(&info);
|
|
||||||
} else {
|
|
||||||
/* Dispatch the signal to sub-handlers */
|
|
||||||
switch(info.si_signo) {
|
|
||||||
case SIGUSR1:
|
|
||||||
SIG_DEBUG("Received SIGUSR1\n");
|
|
||||||
*end = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SIGSEGV: /* Fall through */
|
|
||||||
case SIGABRT:
|
|
||||||
SIG_DEBUG("Received SIGABORT\n");
|
|
||||||
backtrace_handle_signal(&info);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SIGINT:
|
|
||||||
printf("Received SIGINT\n");
|
|
||||||
itti_send_terminate_message(TASK_UNKNOWN);
|
|
||||||
*end = 1;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
SIG_ERROR("Received unknown signal %d\n", info.si_signo);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
+146
-140
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -58,18 +58,18 @@
|
|||||||
int timer_handle_signal(siginfo_t *info);
|
int timer_handle_signal(siginfo_t *info);
|
||||||
|
|
||||||
struct timer_elm_s {
|
struct timer_elm_s {
|
||||||
task_id_t task_id; ///< Task ID which has requested the timer
|
task_id_t task_id; ///< Task ID which has requested the timer
|
||||||
int32_t instance; ///< Instance of the task which has requested the timer
|
int32_t instance; ///< Instance of the task which has requested the timer
|
||||||
timer_t timer; ///< Unique timer id
|
timer_t timer; ///< Unique timer id
|
||||||
timer_type_t type; ///< Timer type
|
timer_type_t type; ///< Timer type
|
||||||
void *timer_arg; ///< Optional argument that will be passed when timer expires
|
void *timer_arg; ///< Optional argument that will be passed when timer expires
|
||||||
STAILQ_ENTRY(timer_elm_s) entries; ///< Pointer to next element
|
STAILQ_ENTRY(timer_elm_s) entries; ///< Pointer to next element
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct timer_desc_s {
|
typedef struct timer_desc_s {
|
||||||
STAILQ_HEAD(timer_list_head, timer_elm_s) timer_queue;
|
STAILQ_HEAD(timer_list_head, timer_elm_s) timer_queue;
|
||||||
pthread_mutex_t timer_list_mutex;
|
pthread_mutex_t timer_list_mutex;
|
||||||
struct timespec timeout;
|
struct timespec timeout;
|
||||||
} timer_desc_t;
|
} timer_desc_t;
|
||||||
|
|
||||||
static timer_desc_t timer_desc;
|
static timer_desc_t timer_desc;
|
||||||
@@ -84,169 +84,175 @@ do { \
|
|||||||
|
|
||||||
int timer_handle_signal(siginfo_t *info)
|
int timer_handle_signal(siginfo_t *info)
|
||||||
{
|
{
|
||||||
struct timer_elm_s *timer_p;
|
struct timer_elm_s *timer_p;
|
||||||
MessageDef *message_p;
|
MessageDef *message_p;
|
||||||
timer_has_expired_t *timer_expired_p;
|
timer_has_expired_t *timer_expired_p;
|
||||||
task_id_t task_id;
|
task_id_t task_id;
|
||||||
int32_t instance;
|
int32_t instance;
|
||||||
|
|
||||||
/* Get back pointer to timer list element */
|
/* Get back pointer to timer list element */
|
||||||
timer_p = (struct timer_elm_s *)info->si_ptr;
|
timer_p = (struct timer_elm_s *)info->si_ptr;
|
||||||
|
|
||||||
TMR_DEBUG("Timer with id 0x%lx has expired\n", (long)timer_p->timer);
|
TMR_DEBUG("Timer with id 0x%lx has expired\n", (long)timer_p->timer);
|
||||||
|
|
||||||
task_id = timer_p->task_id;
|
task_id = timer_p->task_id;
|
||||||
instance = timer_p->instance;
|
instance = timer_p->instance;
|
||||||
message_p = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED);
|
message_p = itti_alloc_new_message(TASK_TIMER, TIMER_HAS_EXPIRED);
|
||||||
|
|
||||||
timer_expired_p = &message_p->ittiMsg.timer_has_expired;
|
timer_expired_p = &message_p->ittiMsg.timer_has_expired;
|
||||||
|
|
||||||
timer_expired_p->timer_id = (long)timer_p->timer;
|
timer_expired_p->timer_id = (long)timer_p->timer;
|
||||||
timer_expired_p->arg = timer_p->timer_arg;
|
timer_expired_p->arg = timer_p->timer_arg;
|
||||||
|
|
||||||
/* Timer is a one shot timer, remove it */
|
/* Timer is a one shot timer, remove it */
|
||||||
if (timer_p->type == TIMER_ONE_SHOT) {
|
if (timer_p->type == TIMER_ONE_SHOT) {
|
||||||
// if (timer_delete(timer_p->timer) < 0) {
|
// if (timer_delete(timer_p->timer) < 0) {
|
||||||
// TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
// TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
||||||
// }
|
// }
|
||||||
// TMR_DEBUG("Removed timer 0x%lx\n", (long)timer_p->timer);
|
// TMR_DEBUG("Removed timer 0x%lx\n", (long)timer_p->timer);
|
||||||
// pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
// pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
||||||
// STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, timer_elm_s, entries);
|
// STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, timer_elm_s, entries);
|
||||||
// pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
// pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
||||||
// free(timer_p);
|
// free(timer_p);
|
||||||
// timer_p = NULL;
|
// timer_p = NULL;
|
||||||
if (timer_remove((long)timer_p->timer) != 0) {
|
if (timer_remove((long)timer_p->timer) != 0) {
|
||||||
TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
TMR_DEBUG("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Notify task of timer expiry */
|
|
||||||
if (itti_send_msg_to_task(task_id, instance, message_p) < 0) {
|
|
||||||
TMR_DEBUG("Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id);
|
|
||||||
free(message_p);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
/* Notify task of timer expiry */
|
||||||
|
if (itti_send_msg_to_task(task_id, instance, message_p) < 0) {
|
||||||
|
TMR_DEBUG("Failed to send msg TIMER_HAS_EXPIRED to task %u\n", task_id);
|
||||||
|
free(message_p);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timer_setup(
|
int timer_setup(
|
||||||
uint32_t interval_sec,
|
uint32_t interval_sec,
|
||||||
uint32_t interval_us,
|
uint32_t interval_us,
|
||||||
task_id_t task_id,
|
task_id_t task_id,
|
||||||
int32_t instance,
|
int32_t instance,
|
||||||
timer_type_t type,
|
timer_type_t type,
|
||||||
void *timer_arg,
|
void *timer_arg,
|
||||||
long *timer_id)
|
long *timer_id)
|
||||||
{
|
{
|
||||||
struct sigevent se;
|
struct sigevent se;
|
||||||
struct itimerspec its;
|
struct itimerspec its;
|
||||||
struct timer_elm_s *timer_p;
|
struct timer_elm_s *timer_p;
|
||||||
timer_t timer;
|
timer_t timer;
|
||||||
|
|
||||||
if (timer_id == NULL) {
|
if (timer_id == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
AssertFatal (type < TIMER_TYPE_MAX, "Invalid timer type (%d/%d)!\n", type, TIMER_TYPE_MAX);
|
|
||||||
|
|
||||||
/* Allocate new timer list element */
|
AssertFatal (type < TIMER_TYPE_MAX, "Invalid timer type (%d/%d)!\n", type, TIMER_TYPE_MAX);
|
||||||
timer_p = malloc(sizeof(struct timer_elm_s));
|
|
||||||
if (timer_p == NULL) {
|
|
||||||
TMR_ERROR("Failed to create new timer element\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&timer, 0, sizeof(timer_t));
|
/* Allocate new timer list element */
|
||||||
memset(&se, 0, sizeof(struct sigevent));
|
timer_p = malloc(sizeof(struct timer_elm_s));
|
||||||
|
|
||||||
timer_p->task_id = task_id;
|
if (timer_p == NULL) {
|
||||||
timer_p->instance = instance;
|
TMR_ERROR("Failed to create new timer element\n");
|
||||||
timer_p->type = type;
|
return -1;
|
||||||
timer_p->timer_arg = timer_arg;
|
}
|
||||||
|
|
||||||
/* Setting up alarm */
|
memset(&timer, 0, sizeof(timer_t));
|
||||||
/* Set and enable alarm */
|
memset(&se, 0, sizeof(struct sigevent));
|
||||||
se.sigev_notify = SIGEV_SIGNAL;
|
|
||||||
se.sigev_signo = SIGTIMER;
|
|
||||||
se.sigev_value.sival_ptr = timer_p;
|
|
||||||
/* At the timer creation, the timer structure will be filled in with timer_id,
|
|
||||||
* which is unique for this process. This id is allocated by kernel and the
|
|
||||||
* value might be used to distinguish timers.
|
|
||||||
*/
|
|
||||||
if (timer_create(CLOCK_REALTIME, &se, &timer) < 0) {
|
|
||||||
TMR_ERROR("Failed to create timer: (%s:%d)\n", strerror(errno), errno);
|
|
||||||
free(timer_p);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill in the first expiration value. */
|
timer_p->task_id = task_id;
|
||||||
its.it_value.tv_sec = interval_sec;
|
timer_p->instance = instance;
|
||||||
its.it_value.tv_nsec = interval_us * 1000;
|
timer_p->type = type;
|
||||||
|
timer_p->timer_arg = timer_arg;
|
||||||
|
|
||||||
if (type == TIMER_PERIODIC) {
|
/* Setting up alarm */
|
||||||
/* Asked for periodic timer. We set the interval time */
|
/* Set and enable alarm */
|
||||||
its.it_interval.tv_sec = interval_sec;
|
se.sigev_notify = SIGEV_SIGNAL;
|
||||||
its.it_interval.tv_nsec = interval_us * 1000;
|
se.sigev_signo = SIGTIMER;
|
||||||
} else {
|
se.sigev_value.sival_ptr = timer_p;
|
||||||
/* Asked for one-shot timer. Do not set the interval field */
|
|
||||||
its.it_interval.tv_sec = 0;
|
|
||||||
its.it_interval.tv_nsec = 0;
|
|
||||||
}
|
|
||||||
timer_settime(timer, 0, &its, NULL);
|
|
||||||
/* Simply set the timer_id argument. so it can be used by caller */
|
|
||||||
*timer_id = (long)timer;
|
|
||||||
TMR_DEBUG("Requesting new %s timer with id 0x%lx that expires within "
|
|
||||||
"%d sec and %d usec\n",
|
|
||||||
type == TIMER_PERIODIC ? "periodic" : "single shot",
|
|
||||||
*timer_id, interval_sec, interval_us);
|
|
||||||
|
|
||||||
timer_p->timer = timer;
|
/* At the timer creation, the timer structure will be filled in with timer_id,
|
||||||
|
* which is unique for this process. This id is allocated by kernel and the
|
||||||
|
* value might be used to distinguish timers.
|
||||||
|
*/
|
||||||
|
if (timer_create(CLOCK_REALTIME, &se, &timer) < 0) {
|
||||||
|
TMR_ERROR("Failed to create timer: (%s:%d)\n", strerror(errno), errno);
|
||||||
|
free(timer_p);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* Lock the queue and insert the timer at the tail */
|
/* Fill in the first expiration value. */
|
||||||
pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
its.it_value.tv_sec = interval_sec;
|
||||||
STAILQ_INSERT_TAIL(&timer_desc.timer_queue, timer_p, entries);
|
its.it_value.tv_nsec = interval_us * 1000;
|
||||||
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
|
||||||
|
|
||||||
return 0;
|
if (type == TIMER_PERIODIC) {
|
||||||
|
/* Asked for periodic timer. We set the interval time */
|
||||||
|
its.it_interval.tv_sec = interval_sec;
|
||||||
|
its.it_interval.tv_nsec = interval_us * 1000;
|
||||||
|
} else {
|
||||||
|
/* Asked for one-shot timer. Do not set the interval field */
|
||||||
|
its.it_interval.tv_sec = 0;
|
||||||
|
its.it_interval.tv_nsec = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
timer_settime(timer, 0, &its, NULL);
|
||||||
|
/* Simply set the timer_id argument. so it can be used by caller */
|
||||||
|
*timer_id = (long)timer;
|
||||||
|
TMR_DEBUG("Requesting new %s timer with id 0x%lx that expires within "
|
||||||
|
"%d sec and %d usec\n",
|
||||||
|
type == TIMER_PERIODIC ? "periodic" : "single shot",
|
||||||
|
*timer_id, interval_sec, interval_us);
|
||||||
|
|
||||||
|
timer_p->timer = timer;
|
||||||
|
|
||||||
|
/* Lock the queue and insert the timer at the tail */
|
||||||
|
pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
||||||
|
STAILQ_INSERT_TAIL(&timer_desc.timer_queue, timer_p, entries);
|
||||||
|
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timer_remove(long timer_id)
|
int timer_remove(long timer_id)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
struct timer_elm_s *timer_p;
|
struct timer_elm_s *timer_p;
|
||||||
|
|
||||||
TMR_DEBUG("Removing timer 0x%lx\n", timer_id);
|
TMR_DEBUG("Removing timer 0x%lx\n", timer_id);
|
||||||
|
|
||||||
pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
pthread_mutex_lock(&timer_desc.timer_list_mutex);
|
||||||
TIMER_SEARCH(timer_p, timer, ((timer_t)timer_id), &timer_desc.timer_queue);
|
TIMER_SEARCH(timer_p, timer, ((timer_t)timer_id), &timer_desc.timer_queue);
|
||||||
|
|
||||||
/* We didn't find the timer in list */
|
/* We didn't find the timer in list */
|
||||||
if (timer_p == NULL) {
|
if (timer_p == NULL) {
|
||||||
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
|
||||||
TMR_ERROR("Didn't find timer 0x%lx in list\n", timer_id);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, timer_elm_s, entries);
|
|
||||||
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
||||||
|
TMR_ERROR("Didn't find timer 0x%lx in list\n", timer_id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (timer_delete(timer_p->timer) < 0) {
|
STAILQ_REMOVE(&timer_desc.timer_queue, timer_p, timer_elm_s, entries);
|
||||||
TMR_ERROR("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
pthread_mutex_unlock(&timer_desc.timer_list_mutex);
|
||||||
rc = -1;
|
|
||||||
}
|
if (timer_delete(timer_p->timer) < 0) {
|
||||||
free(timer_p);
|
TMR_ERROR("Failed to delete timer 0x%lx\n", (long)timer_p->timer);
|
||||||
timer_p = NULL;
|
rc = -1;
|
||||||
return rc;
|
}
|
||||||
|
|
||||||
|
free(timer_p);
|
||||||
|
timer_p = NULL;
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
int timer_init(void)
|
int timer_init(void)
|
||||||
{
|
{
|
||||||
TMR_DEBUG("Initializing TIMER task interface\n");
|
TMR_DEBUG("Initializing TIMER task interface\n");
|
||||||
|
|
||||||
memset(&timer_desc, 0, sizeof(timer_desc_t));
|
memset(&timer_desc, 0, sizeof(timer_desc_t));
|
||||||
|
|
||||||
STAILQ_INIT(&timer_desc.timer_queue);
|
STAILQ_INIT(&timer_desc.timer_queue);
|
||||||
pthread_mutex_init(&timer_desc.timer_list_mutex, NULL);
|
pthread_mutex_init(&timer_desc.timer_list_mutex, NULL);
|
||||||
|
|
||||||
TMR_DEBUG("Initializing TIMER task interface: DONE\n");
|
TMR_DEBUG("Initializing TIMER task interface: DONE\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+14
-14
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -35,9 +35,9 @@
|
|||||||
#define SIGTIMER SIGRTMIN
|
#define SIGTIMER SIGRTMIN
|
||||||
|
|
||||||
typedef enum timer_type_s {
|
typedef enum timer_type_s {
|
||||||
TIMER_PERIODIC,
|
TIMER_PERIODIC,
|
||||||
TIMER_ONE_SHOT,
|
TIMER_ONE_SHOT,
|
||||||
TIMER_TYPE_MAX,
|
TIMER_TYPE_MAX,
|
||||||
} timer_type_t;
|
} timer_type_t;
|
||||||
|
|
||||||
int timer_handle_signal(siginfo_t *info);
|
int timer_handle_signal(siginfo_t *info);
|
||||||
@@ -52,13 +52,13 @@ int timer_handle_signal(siginfo_t *info);
|
|||||||
* @returns -1 on failure, 0 otherwise
|
* @returns -1 on failure, 0 otherwise
|
||||||
**/
|
**/
|
||||||
int timer_setup(
|
int timer_setup(
|
||||||
uint32_t interval_sec,
|
uint32_t interval_sec,
|
||||||
uint32_t interval_us,
|
uint32_t interval_us,
|
||||||
task_id_t task_id,
|
task_id_t task_id,
|
||||||
int32_t instance,
|
int32_t instance,
|
||||||
timer_type_t type,
|
timer_type_t type,
|
||||||
void *timer_arg,
|
void *timer_arg,
|
||||||
long *timer_id);
|
long *timer_id);
|
||||||
|
|
||||||
/** \brief Remove the timer from list
|
/** \brief Remove the timer from list
|
||||||
* \param timer_id unique timer id
|
* \param timer_id unique timer id
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
OpenAirInterface
|
OpenAirInterface
|
||||||
Copyright(c) 1999 - 2014 Eurecom
|
Copyright(c) 1999 - 2014 Eurecom
|
||||||
|
|
||||||
OpenAirInterface is free software: you can redistribute it and/or modify
|
OpenAirInterface is free software: you can redistribute it and/or modify
|
||||||
@@ -14,15 +14,15 @@
|
|||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with OpenAirInterface.The full GNU General Public License is
|
along with OpenAirInterface.The full GNU General Public License is
|
||||||
included in this distribution in the file called "COPYING". If not,
|
included in this distribution in the file called "COPYING". If not,
|
||||||
see <http://www.gnu.org/licenses/>.
|
see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
Contact Information
|
Contact Information
|
||||||
OpenAirInterface Admin: openair_admin@eurecom.fr
|
OpenAirInterface Admin: openair_admin@eurecom.fr
|
||||||
OpenAirInterface Tech : openair_tech@eurecom.fr
|
OpenAirInterface Tech : openair_tech@eurecom.fr
|
||||||
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
OpenAirInterface Dev : openair4g-devel@eurecom.fr
|
||||||
|
|
||||||
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
|
||||||
|
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
@@ -36,8 +36,8 @@
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------------------------//
|
||||||
typedef struct {
|
typedef struct {
|
||||||
void *arg;
|
void *arg;
|
||||||
long timer_id;
|
long timer_id;
|
||||||
} timer_has_expired_t;
|
} timer_has_expired_t;
|
||||||
|
|
||||||
#endif /* TIMER_MESSAGES_TYPES_H_ */
|
#endif /* TIMER_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
+110
-110
@@ -48,32 +48,32 @@
|
|||||||
#define MAX_APN_PER_UE (5)
|
#define MAX_APN_PER_UE (5)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
RAT_WLAN = 0,
|
RAT_WLAN = 0,
|
||||||
RAT_VIRTUAL = 1,
|
RAT_VIRTUAL = 1,
|
||||||
RAT_UTRAN = 1000,
|
RAT_UTRAN = 1000,
|
||||||
RAT_GERAN = 1001,
|
RAT_GERAN = 1001,
|
||||||
RAT_GAN = 1002,
|
RAT_GAN = 1002,
|
||||||
RAT_HSPA_EVOLUTION = 1003,
|
RAT_HSPA_EVOLUTION = 1003,
|
||||||
RAT_EUTRAN = 1004,
|
RAT_EUTRAN = 1004,
|
||||||
RAT_CDMA2000_1X = 2000,
|
RAT_CDMA2000_1X = 2000,
|
||||||
RAT_HRPD = 2001,
|
RAT_HRPD = 2001,
|
||||||
RAT_UMB = 2002,
|
RAT_UMB = 2002,
|
||||||
RAT_EHRPD = 2003,
|
RAT_EHRPD = 2003,
|
||||||
} rat_type_t;
|
} rat_type_t;
|
||||||
|
|
||||||
#define NUMBER_OF_RAT_TYPE 11
|
#define NUMBER_OF_RAT_TYPE 11
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
SS_SERVICE_GRANTED = 0,
|
SS_SERVICE_GRANTED = 0,
|
||||||
SS_OPERATOR_DETERMINED_BARRING = 1,
|
SS_OPERATOR_DETERMINED_BARRING = 1,
|
||||||
SS_MAX,
|
SS_MAX,
|
||||||
} subscriber_status_t;
|
} subscriber_status_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NAM_PACKET_AND_CIRCUIT = 0,
|
NAM_PACKET_AND_CIRCUIT = 0,
|
||||||
NAM_RESERVED = 1,
|
NAM_RESERVED = 1,
|
||||||
NAM_ONLY_PACKET = 2,
|
NAM_ONLY_PACKET = 2,
|
||||||
NAM_MAX,
|
NAM_MAX,
|
||||||
} network_access_mode_t;
|
} network_access_mode_t;
|
||||||
|
|
||||||
typedef uint64_t bitrate_t;
|
typedef uint64_t bitrate_t;
|
||||||
@@ -100,154 +100,154 @@ typedef uint32_t ard_t;
|
|||||||
#define ARD_MAX (1U << 6)
|
#define ARD_MAX (1U << 6)
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
plmn_t plmn;
|
plmn_t plmn;
|
||||||
unsigned cell_identity:28;
|
unsigned cell_identity:28;
|
||||||
} cgi_t;
|
} cgi_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
struct {
|
struct {
|
||||||
uint8_t imei[13];
|
uint8_t imei[13];
|
||||||
uint8_t sotfware_version[2];
|
uint8_t sotfware_version[2];
|
||||||
} id;
|
} id;
|
||||||
uint8_t imeisv[15];
|
uint8_t imeisv[15];
|
||||||
} me_identity_t;
|
} me_identity_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
bitrate_t br_ul;
|
bitrate_t br_ul;
|
||||||
bitrate_t br_dl;
|
bitrate_t br_dl;
|
||||||
} ambr_t;
|
} ambr_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
IPv4 = 0,
|
IPv4 = 0,
|
||||||
IPv6 = 1,
|
IPv6 = 1,
|
||||||
IPv4_AND_v6 = 2,
|
IPv4_AND_v6 = 2,
|
||||||
IPv4_OR_v6 = 3,
|
IPv4_OR_v6 = 3,
|
||||||
IP_MAX,
|
IP_MAX,
|
||||||
} pdn_type_t;
|
} pdn_type_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
pdn_type_t pdn_type;
|
pdn_type_t pdn_type;
|
||||||
struct {
|
struct {
|
||||||
uint8_t ipv4_address[4];
|
uint8_t ipv4_address[4];
|
||||||
uint8_t ipv6_address[16];
|
uint8_t ipv6_address[16];
|
||||||
} address;
|
} address;
|
||||||
} ip_address_t;
|
} ip_address_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
QCI_1 = 1,
|
QCI_1 = 1,
|
||||||
QCI_2 = 2,
|
QCI_2 = 2,
|
||||||
QCI_3 = 3,
|
QCI_3 = 3,
|
||||||
QCI_4 = 4,
|
QCI_4 = 4,
|
||||||
QCI_5 = 5,
|
QCI_5 = 5,
|
||||||
QCI_6 = 6,
|
QCI_6 = 6,
|
||||||
QCI_7 = 7,
|
QCI_7 = 7,
|
||||||
QCI_8 = 8,
|
QCI_8 = 8,
|
||||||
QCI_9 = 9,
|
QCI_9 = 9,
|
||||||
/* Values from 128 to 254 are operator specific.
|
/* Values from 128 to 254 are operator specific.
|
||||||
* Other are reserved.
|
* Other are reserved.
|
||||||
*/
|
*/
|
||||||
QCI_MAX,
|
QCI_MAX,
|
||||||
} qci_t;
|
} qci_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PRE_EMPTION_CAPABILITY_ENABLED = 0,
|
PRE_EMPTION_CAPABILITY_ENABLED = 0,
|
||||||
PRE_EMPTION_CAPABILITY_DISABLED = 1,
|
PRE_EMPTION_CAPABILITY_DISABLED = 1,
|
||||||
PRE_EMPTION_CAPABILITY_MAX,
|
PRE_EMPTION_CAPABILITY_MAX,
|
||||||
} pre_emp_capability_t;
|
} pre_emp_capability_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
PRE_EMPTION_VULNERABILITY_ENABLED = 0,
|
PRE_EMPTION_VULNERABILITY_ENABLED = 0,
|
||||||
PRE_EMPTION_VULNERABILITY_DISABLED = 1,
|
PRE_EMPTION_VULNERABILITY_DISABLED = 1,
|
||||||
PRE_EMPTION_VULNERABILITY_MAX,
|
PRE_EMPTION_VULNERABILITY_MAX,
|
||||||
} pre_emp_vulnerability_t;
|
} pre_emp_vulnerability_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
priority_level_t priority_level;
|
priority_level_t priority_level;
|
||||||
pre_emp_vulnerability_t pre_emp_vulnerability;
|
pre_emp_vulnerability_t pre_emp_vulnerability;
|
||||||
pre_emp_capability_t pre_emp_capability;
|
pre_emp_capability_t pre_emp_capability;
|
||||||
} allocation_retention_priority_t;
|
} allocation_retention_priority_t;
|
||||||
|
|
||||||
typedef struct eps_subscribed_qos_profile_s {
|
typedef struct eps_subscribed_qos_profile_s {
|
||||||
qci_t qci;
|
qci_t qci;
|
||||||
allocation_retention_priority_t allocation_retention_priority;
|
allocation_retention_priority_t allocation_retention_priority;
|
||||||
} eps_subscribed_qos_profile_t;
|
} eps_subscribed_qos_profile_t;
|
||||||
|
|
||||||
typedef struct apn_configuration_s {
|
typedef struct apn_configuration_s {
|
||||||
context_identifier_t context_identifier;
|
context_identifier_t context_identifier;
|
||||||
|
|
||||||
/* Each APN configuration can have 0, 1, or 2 ip address:
|
/* Each APN configuration can have 0, 1, or 2 ip address:
|
||||||
* - 0 means subscribed is dynamically allocated by P-GW depending on the
|
* - 0 means subscribed is dynamically allocated by P-GW depending on the
|
||||||
* pdn_type
|
* pdn_type
|
||||||
* - 1 Only one type of IP address is returned by HSS
|
* - 1 Only one type of IP address is returned by HSS
|
||||||
* - 2 IPv4 and IPv6 address are returned by HSS and are statically
|
* - 2 IPv4 and IPv6 address are returned by HSS and are statically
|
||||||
* allocated
|
* allocated
|
||||||
*/
|
*/
|
||||||
uint8_t nb_ip_address;
|
uint8_t nb_ip_address;
|
||||||
ip_address_t ip_address[2];
|
ip_address_t ip_address[2];
|
||||||
|
|
||||||
pdn_type_t pdn_type;
|
pdn_type_t pdn_type;
|
||||||
char service_selection[APN_MAX_LENGTH];
|
char service_selection[APN_MAX_LENGTH];
|
||||||
int service_selection_length;
|
int service_selection_length;
|
||||||
eps_subscribed_qos_profile_t subscribed_qos;
|
eps_subscribed_qos_profile_t subscribed_qos;
|
||||||
ambr_t ambr;
|
ambr_t ambr;
|
||||||
} apn_configuration_t;
|
} apn_configuration_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ALL_APN_CONFIGURATIONS_INCLUDED = 0,
|
ALL_APN_CONFIGURATIONS_INCLUDED = 0,
|
||||||
MODIFIED_ADDED_APN_CONFIGURATIONS_INCLUDED = 1,
|
MODIFIED_ADDED_APN_CONFIGURATIONS_INCLUDED = 1,
|
||||||
ALL_APN_MAX,
|
ALL_APN_MAX,
|
||||||
} all_apn_conf_ind_t;
|
} all_apn_conf_ind_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
context_identifier_t context_identifier;
|
context_identifier_t context_identifier;
|
||||||
all_apn_conf_ind_t all_apn_conf_ind;
|
all_apn_conf_ind_t all_apn_conf_ind;
|
||||||
/* Number of APNs provided */
|
/* Number of APNs provided */
|
||||||
uint8_t nb_apns;
|
uint8_t nb_apns;
|
||||||
/* List of APNs configuration 1 to n elements */
|
/* List of APNs configuration 1 to n elements */
|
||||||
struct apn_configuration_s apn_configuration[MAX_APN_PER_UE];
|
struct apn_configuration_s apn_configuration[MAX_APN_PER_UE];
|
||||||
} apn_config_profile_t;
|
} apn_config_profile_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
subscriber_status_t subscriber_status;
|
subscriber_status_t subscriber_status;
|
||||||
char msisdn[MSISDN_LENGTH + 1];
|
char msisdn[MSISDN_LENGTH + 1];
|
||||||
uint8_t msisdn_length;
|
uint8_t msisdn_length;
|
||||||
network_access_mode_t access_mode;
|
network_access_mode_t access_mode;
|
||||||
access_restriction_t access_restriction;
|
access_restriction_t access_restriction;
|
||||||
ambr_t subscribed_ambr;
|
ambr_t subscribed_ambr;
|
||||||
apn_config_profile_t apn_config_profile;
|
apn_config_profile_t apn_config_profile;
|
||||||
rau_tau_timer_t rau_tau_timer;
|
rau_tau_timer_t rau_tau_timer;
|
||||||
} subscription_data_t;
|
} subscription_data_t;
|
||||||
|
|
||||||
typedef struct authentication_info_s {
|
typedef struct authentication_info_s {
|
||||||
uint8_t nb_of_vectors;
|
uint8_t nb_of_vectors;
|
||||||
eutran_vector_t eutran_vector;
|
eutran_vector_t eutran_vector;
|
||||||
} authentication_info_t;
|
} authentication_info_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE = 4181,
|
DIAMETER_AUTHENTICATION_DATA_UNAVAILABLE = 4181,
|
||||||
DIAMETER_ERROR_USER_UNKNOWN = 5001,
|
DIAMETER_ERROR_USER_UNKNOWN = 5001,
|
||||||
DIAMETER_ERROR_ROAMING_NOT_ALLOWED = 5004,
|
DIAMETER_ERROR_ROAMING_NOT_ALLOWED = 5004,
|
||||||
DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION = 5420,
|
DIAMETER_ERROR_UNKNOWN_EPS_SUBSCRIPTION = 5420,
|
||||||
DIAMETER_ERROR_RAT_NOT_ALLOWED = 5421,
|
DIAMETER_ERROR_RAT_NOT_ALLOWED = 5421,
|
||||||
DIAMETER_ERROR_EQUIPMENT_UNKNOWN = 5422,
|
DIAMETER_ERROR_EQUIPMENT_UNKNOWN = 5422,
|
||||||
DIAMETER_ERROR_UNKOWN_SERVING_NODE = 5423,
|
DIAMETER_ERROR_UNKOWN_SERVING_NODE = 5423,
|
||||||
} s6a_experimental_result_t;
|
} s6a_experimental_result_t;
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
DIAMETER_SUCCESS = 2001,
|
DIAMETER_SUCCESS = 2001,
|
||||||
} s6a_base_result_t;
|
} s6a_base_result_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
#define S6A_RESULT_BASE 0x0
|
#define S6A_RESULT_BASE 0x0
|
||||||
#define S6A_RESULT_EXPERIMENTAL 0x1
|
#define S6A_RESULT_EXPERIMENTAL 0x1
|
||||||
unsigned present:1;
|
unsigned present:1;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
/* Experimental result as defined in 3GPP TS 29.272 */
|
/* Experimental result as defined in 3GPP TS 29.272 */
|
||||||
s6a_experimental_result_t experimental;
|
s6a_experimental_result_t experimental;
|
||||||
/* Diameter basics results as defined in RFC 3588 */
|
/* Diameter basics results as defined in RFC 3588 */
|
||||||
s6a_base_result_t base;
|
s6a_base_result_t base;
|
||||||
} choice;
|
} choice;
|
||||||
} s6a_result_t;
|
} s6a_result_t;
|
||||||
|
|
||||||
#endif /* COMMON_TYPES_H_ */
|
#endif /* COMMON_TYPES_H_ */
|
||||||
|
|||||||
@@ -32,57 +32,57 @@
|
|||||||
#include "../SGW-LITE/sgw_lite_ie_defs.h"
|
#include "../SGW-LITE/sgw_lite_ie_defs.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Teid_t context_teid; ///< Tunnel Endpoint Identifier
|
Teid_t context_teid; ///< Tunnel Endpoint Identifier
|
||||||
ebi_t eps_bearer_id;
|
ebi_t eps_bearer_id;
|
||||||
} Gtpv1uCreateTunnelReq;
|
} Gtpv1uCreateTunnelReq;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0)
|
uint8_t status; ///< Status of S1U endpoint creation (Failed = 0xFF or Success = 0x0)
|
||||||
Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier
|
Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier
|
||||||
Teid_t S1u_teid; ///< Tunnel Endpoint Identifier
|
Teid_t S1u_teid; ///< Tunnel Endpoint Identifier
|
||||||
ebi_t eps_bearer_id;
|
ebi_t eps_bearer_id;
|
||||||
} Gtpv1uCreateTunnelResp;
|
} Gtpv1uCreateTunnelResp;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Teid_t context_teid; ///< S11 Tunnel Endpoint Identifier
|
Teid_t context_teid; ///< S11 Tunnel Endpoint Identifier
|
||||||
Teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier
|
Teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier
|
||||||
Teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier
|
Teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier
|
||||||
ip_address_t enb_ip_address_for_S1u;
|
ip_address_t enb_ip_address_for_S1u;
|
||||||
ebi_t eps_bearer_id;
|
ebi_t eps_bearer_id;
|
||||||
} Gtpv1uUpdateTunnelReq;
|
} Gtpv1uUpdateTunnelReq;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t status; ///< Status (Failed = 0xFF or Success = 0x0)
|
uint8_t status; ///< Status (Failed = 0xFF or Success = 0x0)
|
||||||
Teid_t context_teid; ///< S11 Tunnel Endpoint Identifier
|
Teid_t context_teid; ///< S11 Tunnel Endpoint Identifier
|
||||||
Teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier
|
Teid_t sgw_S1u_teid; ///< SGW S1U local Tunnel Endpoint Identifier
|
||||||
Teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier
|
Teid_t enb_S1u_teid; ///< eNB S1U Tunnel Endpoint Identifier
|
||||||
ebi_t eps_bearer_id;
|
ebi_t eps_bearer_id;
|
||||||
} Gtpv1uUpdateTunnelResp;
|
} Gtpv1uUpdateTunnelResp;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier
|
Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier
|
||||||
Teid_t S1u_teid; ///< local S1U Tunnel Endpoint Identifier to be deleted
|
Teid_t S1u_teid; ///< local S1U Tunnel Endpoint Identifier to be deleted
|
||||||
} Gtpv1uDeleteTunnelReq;
|
} Gtpv1uDeleteTunnelReq;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t status; ///< Status of S1U endpoint deleteion (Failed = 0xFF or Success = 0x0)
|
uint8_t status; ///< Status of S1U endpoint deleteion (Failed = 0xFF or Success = 0x0)
|
||||||
Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier
|
Teid_t context_teid; ///< local SGW S11 Tunnel Endpoint Identifier
|
||||||
Teid_t S1u_teid; ///< local S1U Tunnel Endpoint Identifier to be deleted
|
Teid_t S1u_teid; ///< local S1U Tunnel Endpoint Identifier to be deleted
|
||||||
} Gtpv1uDeleteTunnelResp;
|
} Gtpv1uDeleteTunnelResp;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint32_t offset; ///< start of message offset in buffer
|
uint32_t offset; ///< start of message offset in buffer
|
||||||
Teid_t local_S1u_teid; ///< Tunnel Endpoint Identifier
|
Teid_t local_S1u_teid; ///< Tunnel Endpoint Identifier
|
||||||
} Gtpv1uTunnelDataInd;
|
} Gtpv1uTunnelDataInd;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
uint32_t length;
|
uint32_t length;
|
||||||
uint32_t offset; ///< start of message offset in buffer
|
uint32_t offset; ///< start of message offset in buffer
|
||||||
Teid_t local_S1u_teid; ///< Tunnel Endpoint Identifier
|
Teid_t local_S1u_teid; ///< Tunnel Endpoint Identifier
|
||||||
Teid_t S1u_enb_teid; ///< Tunnel Endpoint Identifier
|
Teid_t S1u_enb_teid; ///< Tunnel Endpoint Identifier
|
||||||
} Gtpv1uTunnelDataReq;
|
} Gtpv1uTunnelDataReq;
|
||||||
|
|
||||||
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
|
#endif /* GTPV1_U_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -30,66 +30,66 @@
|
|||||||
#define SGI_FORWARD_MESSAGES_TYPES_H_
|
#define SGI_FORWARD_MESSAGES_TYPES_H_
|
||||||
|
|
||||||
typedef enum SGIStatus_e {
|
typedef enum SGIStatus_e {
|
||||||
SGI_STATUS_OK = 0,
|
SGI_STATUS_OK = 0,
|
||||||
SGI_STATUS_ERROR_CONTEXT_ALREADY_EXIST = 50,
|
SGI_STATUS_ERROR_CONTEXT_ALREADY_EXIST = 50,
|
||||||
SGI_STATUS_ERROR_CONTEXT_NOT_FOUND = 51,
|
SGI_STATUS_ERROR_CONTEXT_NOT_FOUND = 51,
|
||||||
SGI_STATUS_ERROR_INVALID_MESSAGE_FORMAT = 52,
|
SGI_STATUS_ERROR_INVALID_MESSAGE_FORMAT = 52,
|
||||||
SGI_STATUS_ERROR_SERVICE_NOT_SUPPORTED = 53,
|
SGI_STATUS_ERROR_SERVICE_NOT_SUPPORTED = 53,
|
||||||
SGI_STATUS_ERROR_SYSTEM_FAILURE = 54,
|
SGI_STATUS_ERROR_SYSTEM_FAILURE = 54,
|
||||||
SGI_STATUS_ERROR_NO_RESOURCES_AVAILABLE = 55,
|
SGI_STATUS_ERROR_NO_RESOURCES_AVAILABLE = 55,
|
||||||
SGI_STATUS_ERROR_NO_MEMORY_AVAILABLE = 56,
|
SGI_STATUS_ERROR_NO_MEMORY_AVAILABLE = 56,
|
||||||
SGI_STATUS_MAX,
|
SGI_STATUS_MAX,
|
||||||
} SGIStatus_t;
|
} SGIStatus_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
||||||
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
||||||
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
||||||
pdn_type_t pdn_type; ///< PDN Type
|
pdn_type_t pdn_type; ///< PDN Type
|
||||||
PAA_t paa; ///< PDN Address Allocation
|
PAA_t paa; ///< PDN Address Allocation
|
||||||
} SGICreateEndpointReq;
|
} SGICreateEndpointReq;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SGIStatus_t status; ///< Status of endpoint creation (Failed = 0xFF or Success = 0x0)
|
SGIStatus_t status; ///< Status of endpoint creation (Failed = 0xFF or Success = 0x0)
|
||||||
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
||||||
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
||||||
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
||||||
pdn_type_t pdn_type; ///< PDN Type
|
pdn_type_t pdn_type; ///< PDN Type
|
||||||
PAA_t paa; ///< PDN Address Allocation
|
PAA_t paa; ///< PDN Address Allocation
|
||||||
} SGICreateEndpointResp;
|
} SGICreateEndpointResp;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
||||||
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
||||||
Teid_t enb_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
Teid_t enb_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
||||||
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
||||||
} SGIUpdateEndpointReq;
|
} SGIUpdateEndpointReq;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SGIStatus_t status; ///< Status of endpoint creation (Failed = 0xFF or Success = 0x0)
|
SGIStatus_t status; ///< Status of endpoint creation (Failed = 0xFF or Success = 0x0)
|
||||||
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
||||||
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
||||||
Teid_t enb_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
Teid_t enb_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
||||||
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
||||||
} SGIUpdateEndpointResp;
|
} SGIUpdateEndpointResp;
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
||||||
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
||||||
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
||||||
pdn_type_t pdn_type; ///< PDN Type
|
pdn_type_t pdn_type; ///< PDN Type
|
||||||
PAA_t paa; ///< PDN Address Allocation
|
PAA_t paa; ///< PDN Address Allocation
|
||||||
} SGIDeleteEndpointReq;
|
} SGIDeleteEndpointReq;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
SGIStatus_t status; ///< Status of endpoint deletion (Failed = 0xFF or Success = 0x0)
|
SGIStatus_t status; ///< Status of endpoint deletion (Failed = 0xFF or Success = 0x0)
|
||||||
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
Teid_t context_teid; ///< Tunnel Endpoint Identifier S11
|
||||||
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
Teid_t sgw_S1u_teid; ///< Tunnel Endpoint Identifier S1-U
|
||||||
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
ebi_t eps_bearer_id; ///< EPS bearer identifier
|
||||||
pdn_type_t pdn_type; ///< PDN Type
|
pdn_type_t pdn_type; ///< PDN Type
|
||||||
PAA_t paa; ///< PDN Address Allocation
|
PAA_t paa; ///< PDN Address Allocation
|
||||||
} SGIDeleteEndpointResp;
|
} SGIDeleteEndpointResp;
|
||||||
|
|
||||||
#endif /* SGI_FORWARD_MESSAGES_TYPES_H_ */
|
#endif /* SGI_FORWARD_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -35,37 +35,37 @@
|
|||||||
#define MME_APP_INITIAL_CONTEXT_SETUP_RSP(mSGpTR) (mSGpTR)->ittiMsg.mme_app_initial_context_setup_rsp
|
#define MME_APP_INITIAL_CONTEXT_SETUP_RSP(mSGpTR) (mSGpTR)->ittiMsg.mme_app_initial_context_setup_rsp
|
||||||
|
|
||||||
typedef struct mme_app_connection_establishment_ind_s {
|
typedef struct mme_app_connection_establishment_ind_s {
|
||||||
uint32_t mme_ue_s1ap_id;
|
uint32_t mme_ue_s1ap_id;
|
||||||
nas_establish_ind_t nas;
|
nas_establish_ind_t nas;
|
||||||
|
|
||||||
/* Transparent message from s1ap to be forwarded to MME_APP or
|
/* Transparent message from s1ap to be forwarded to MME_APP or
|
||||||
* to S1AP if connection establishment is rejected by NAS.
|
* to S1AP if connection establishment is rejected by NAS.
|
||||||
*/
|
*/
|
||||||
s1ap_initial_ue_message_t transparent;
|
s1ap_initial_ue_message_t transparent;
|
||||||
} mme_app_connection_establishment_ind_t;
|
} mme_app_connection_establishment_ind_t;
|
||||||
|
|
||||||
typedef struct mme_app_connection_establishment_cnf_s {
|
typedef struct mme_app_connection_establishment_cnf_s {
|
||||||
|
|
||||||
ebi_t eps_bearer_id;
|
ebi_t eps_bearer_id;
|
||||||
FTeid_t bearer_s1u_sgw_fteid;
|
FTeid_t bearer_s1u_sgw_fteid;
|
||||||
qci_t bearer_qos_qci;
|
qci_t bearer_qos_qci;
|
||||||
priority_level_t bearer_qos_prio_level;
|
priority_level_t bearer_qos_prio_level;
|
||||||
pre_emp_vulnerability_t bearer_qos_pre_emp_vulnerability;
|
pre_emp_vulnerability_t bearer_qos_pre_emp_vulnerability;
|
||||||
pre_emp_capability_t bearer_qos_pre_emp_capability;
|
pre_emp_capability_t bearer_qos_pre_emp_capability;
|
||||||
ambr_t ambr;
|
ambr_t ambr;
|
||||||
|
|
||||||
/* Key eNB */
|
/* Key eNB */
|
||||||
uint8_t keNB[32];
|
uint8_t keNB[32];
|
||||||
uint16_t security_capabilities_encryption_algorithms;
|
uint16_t security_capabilities_encryption_algorithms;
|
||||||
uint16_t security_capabilities_integrity_algorithms;
|
uint16_t security_capabilities_integrity_algorithms;
|
||||||
|
|
||||||
nas_conn_est_cnf_t nas_conn_est_cnf;
|
nas_conn_est_cnf_t nas_conn_est_cnf;
|
||||||
} mme_app_connection_establishment_cnf_t;
|
} mme_app_connection_establishment_cnf_t;
|
||||||
|
|
||||||
typedef struct mme_app_initial_context_setup_rsp_s {
|
typedef struct mme_app_initial_context_setup_rsp_s {
|
||||||
uint32_t mme_ue_s1ap_id;
|
uint32_t mme_ue_s1ap_id;
|
||||||
ebi_t eps_bearer_id;
|
ebi_t eps_bearer_id;
|
||||||
FTeid_t bearer_s1u_enb_fteid;
|
FTeid_t bearer_s1u_enb_fteid;
|
||||||
} mme_app_initial_context_setup_rsp_t;
|
} mme_app_initial_context_setup_rsp_t;
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -67,101 +67,101 @@
|
|||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
EMM_MSG_HEADER = 1,
|
EMM_MSG_HEADER = 1,
|
||||||
EMM_MSG_ATTACH_REQUEST,
|
EMM_MSG_ATTACH_REQUEST,
|
||||||
EMM_MSG_ATTACH_ACCEPT,
|
EMM_MSG_ATTACH_ACCEPT,
|
||||||
EMM_MSG_ATTACH_COMPLETE,
|
EMM_MSG_ATTACH_COMPLETE,
|
||||||
EMM_MSG_ATTACH_REJECT,
|
EMM_MSG_ATTACH_REJECT,
|
||||||
EMM_MSG_DETACH_REQUEST,
|
EMM_MSG_DETACH_REQUEST,
|
||||||
EMM_MSG_DETACH_ACCEPT,
|
EMM_MSG_DETACH_ACCEPT,
|
||||||
EMM_MSG_TRACKING_AREA_UPDATE_REQUEST,
|
EMM_MSG_TRACKING_AREA_UPDATE_REQUEST,
|
||||||
EMM_MSG_TRACKING_AREA_UPDATE_ACCEPT,
|
EMM_MSG_TRACKING_AREA_UPDATE_ACCEPT,
|
||||||
EMM_MSG_TRACKING_AREA_UPDATE_COMPLETE,
|
EMM_MSG_TRACKING_AREA_UPDATE_COMPLETE,
|
||||||
EMM_MSG_TRACKING_AREA_UPDATE_REJECT,
|
EMM_MSG_TRACKING_AREA_UPDATE_REJECT,
|
||||||
EMM_MSG_EXTENDED_SERVICE_REQUEST,
|
EMM_MSG_EXTENDED_SERVICE_REQUEST,
|
||||||
EMM_MSG_SERVICE_REQUEST,
|
EMM_MSG_SERVICE_REQUEST,
|
||||||
EMM_MSG_SERVICE_REJECT,
|
EMM_MSG_SERVICE_REJECT,
|
||||||
EMM_MSG_GUTI_REALLOCATION_COMMAND,
|
EMM_MSG_GUTI_REALLOCATION_COMMAND,
|
||||||
EMM_MSG_GUTI_REALLOCATION_COMPLETE,
|
EMM_MSG_GUTI_REALLOCATION_COMPLETE,
|
||||||
EMM_MSG_AUTHENTICATION_REQUEST,
|
EMM_MSG_AUTHENTICATION_REQUEST,
|
||||||
EMM_MSG_AUTHENTICATION_RESPONSE,
|
EMM_MSG_AUTHENTICATION_RESPONSE,
|
||||||
EMM_MSG_AUTHENTICATION_REJECT,
|
EMM_MSG_AUTHENTICATION_REJECT,
|
||||||
EMM_MSG_AUTHENTICATION_FAILURE,
|
EMM_MSG_AUTHENTICATION_FAILURE,
|
||||||
EMM_MSG_IDENTITY_REQUEST,
|
EMM_MSG_IDENTITY_REQUEST,
|
||||||
EMM_MSG_IDENTITY_RESPONSE,
|
EMM_MSG_IDENTITY_RESPONSE,
|
||||||
EMM_MSG_SECURITY_MODE_COMMAND,
|
EMM_MSG_SECURITY_MODE_COMMAND,
|
||||||
EMM_MSG_SECURITY_MODE_COMPLETE,
|
EMM_MSG_SECURITY_MODE_COMPLETE,
|
||||||
EMM_MSG_SECURITY_MODE_REJECT,
|
EMM_MSG_SECURITY_MODE_REJECT,
|
||||||
EMM_MSG_EMM_STATUS,
|
EMM_MSG_EMM_STATUS,
|
||||||
EMM_MSG_EMM_INFORMATION,
|
EMM_MSG_EMM_INFORMATION,
|
||||||
EMM_MSG_DOWNLINK_NAS_TRANSPORT,
|
EMM_MSG_DOWNLINK_NAS_TRANSPORT,
|
||||||
EMM_MSG_UPLINK_NAS_TRANSPORT,
|
EMM_MSG_UPLINK_NAS_TRANSPORT,
|
||||||
EMM_MSG_CS_SERVICE_NOTIFICATION,
|
EMM_MSG_CS_SERVICE_NOTIFICATION,
|
||||||
} emm_message_ids_t;
|
} emm_message_ids_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
ESM_MSG_HEADER = 1,
|
ESM_MSG_HEADER = 1,
|
||||||
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST,
|
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REQUEST,
|
||||||
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT,
|
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_ACCEPT,
|
||||||
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT,
|
ESM_MSG_ACTIVATE_DEFAULT_EPS_BEARER_CONTEXT_REJECT,
|
||||||
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST,
|
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REQUEST,
|
||||||
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT,
|
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_ACCEPT,
|
||||||
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT,
|
ESM_MSG_ACTIVATE_DEDICATED_EPS_BEARER_CONTEXT_REJECT,
|
||||||
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REQUEST,
|
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REQUEST,
|
||||||
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_ACCEPT,
|
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_ACCEPT,
|
||||||
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REJECT,
|
ESM_MSG_MODIFY_EPS_BEARER_CONTEXT_REJECT,
|
||||||
ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST,
|
ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_REQUEST,
|
||||||
ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT,
|
ESM_MSG_DEACTIVATE_EPS_BEARER_CONTEXT_ACCEPT,
|
||||||
ESM_MSG_PDN_CONNECTIVITY_REQUEST,
|
ESM_MSG_PDN_CONNECTIVITY_REQUEST,
|
||||||
ESM_MSG_PDN_CONNECTIVITY_REJECT,
|
ESM_MSG_PDN_CONNECTIVITY_REJECT,
|
||||||
ESM_MSG_PDN_DISCONNECT_REQUEST,
|
ESM_MSG_PDN_DISCONNECT_REQUEST,
|
||||||
ESM_MSG_PDN_DISCONNECT_REJECT,
|
ESM_MSG_PDN_DISCONNECT_REJECT,
|
||||||
ESM_MSG_BEARER_RESOURCE_ALLOCATION_REQUEST,
|
ESM_MSG_BEARER_RESOURCE_ALLOCATION_REQUEST,
|
||||||
ESM_MSG_BEARER_RESOURCE_ALLOCATION_REJECT,
|
ESM_MSG_BEARER_RESOURCE_ALLOCATION_REJECT,
|
||||||
ESM_MSG_BEARER_RESOURCE_MODIFICATION_REQUEST,
|
ESM_MSG_BEARER_RESOURCE_MODIFICATION_REQUEST,
|
||||||
ESM_MSG_BEARER_RESOURCE_MODIFICATION_REJECT,
|
ESM_MSG_BEARER_RESOURCE_MODIFICATION_REJECT,
|
||||||
ESM_MSG_ESM_INFORMATION_REQUEST,
|
ESM_MSG_ESM_INFORMATION_REQUEST,
|
||||||
ESM_MSG_ESM_INFORMATION_RESPONSE,
|
ESM_MSG_ESM_INFORMATION_RESPONSE,
|
||||||
ESM_MSG_ESM_STATUS,
|
ESM_MSG_ESM_STATUS,
|
||||||
} esm_message_ids_t;
|
} esm_message_ids_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_raw_msg_s {
|
typedef struct nas_raw_msg_s {
|
||||||
uint32_t lenght;
|
uint32_t lenght;
|
||||||
uint8_t data[NAS_DATA_LENGHT_MAX];
|
uint8_t data[NAS_DATA_LENGHT_MAX];
|
||||||
} nas_raw_msg_t;
|
} nas_raw_msg_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_emm_plain_msg_s {
|
typedef struct nas_emm_plain_msg_s {
|
||||||
emm_message_ids_t present;
|
emm_message_ids_t present;
|
||||||
EMM_msg choice;
|
EMM_msg choice;
|
||||||
|
|
||||||
} nas_emm_plain_msg_t;
|
} nas_emm_plain_msg_t;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_emm_protected_msg_s {
|
typedef struct nas_emm_protected_msg_s {
|
||||||
nas_message_security_header_t header;
|
nas_message_security_header_t header;
|
||||||
emm_message_ids_t present;
|
emm_message_ids_t present;
|
||||||
EMM_msg choice;
|
EMM_msg choice;
|
||||||
} nas_emm_protected_msg_t;
|
} nas_emm_protected_msg_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_esm_plain_msg_s {
|
typedef struct nas_esm_plain_msg_s {
|
||||||
esm_message_ids_t present;
|
esm_message_ids_t present;
|
||||||
ESM_msg choice;
|
ESM_msg choice;
|
||||||
|
|
||||||
} nas_esm_plain_msg_t;
|
} nas_esm_plain_msg_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_esm_protected_msg_s {
|
typedef struct nas_esm_protected_msg_s {
|
||||||
nas_message_security_header_t header;
|
nas_message_security_header_t header;
|
||||||
esm_message_ids_t present;
|
esm_message_ids_t present;
|
||||||
ESM_msg choice;
|
ESM_msg choice;
|
||||||
} nas_esm_protected_msg_t;
|
} nas_esm_protected_msg_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -171,66 +171,66 @@ typedef struct nas_paging_ind_s {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct nas_pdn_connectivity_req_s {
|
typedef struct nas_pdn_connectivity_req_s {
|
||||||
int pti; // nas ref Identity of the procedure transaction executed to activate the PDN connection entry
|
int pti; // nas ref Identity of the procedure transaction executed to activate the PDN connection entry
|
||||||
unsigned ue_id; // nas ref
|
unsigned ue_id; // nas ref
|
||||||
char imsi[16];
|
char imsi[16];
|
||||||
uint8_t imsi_length;
|
uint8_t imsi_length;
|
||||||
network_qos_t qos;
|
network_qos_t qos;
|
||||||
OctetString apn;
|
OctetString apn;
|
||||||
OctetString pdn_addr;
|
OctetString pdn_addr;
|
||||||
int pdn_type;
|
int pdn_type;
|
||||||
void *proc_data;
|
void *proc_data;
|
||||||
int request_type;
|
int request_type;
|
||||||
} nas_pdn_connectivity_req_t;
|
} nas_pdn_connectivity_req_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_pdn_connectivity_rsp_s {
|
typedef struct nas_pdn_connectivity_rsp_s {
|
||||||
int pti; // nas ref Identity of the procedure transaction executed to activate the PDN connection entry
|
int pti; // nas ref Identity of the procedure transaction executed to activate the PDN connection entry
|
||||||
unsigned ue_id; // nas ref
|
unsigned ue_id; // nas ref
|
||||||
network_qos_t qos;
|
network_qos_t qos;
|
||||||
OctetString apn;
|
OctetString apn;
|
||||||
OctetString pdn_addr;
|
OctetString pdn_addr;
|
||||||
int pdn_type;
|
int pdn_type;
|
||||||
void *proc_data;
|
void *proc_data;
|
||||||
int request_type;
|
int request_type;
|
||||||
|
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
uint32_t mme_ue_s1ap_id;
|
uint32_t mme_ue_s1ap_id;
|
||||||
|
|
||||||
/* Key eNB */
|
/* Key eNB */
|
||||||
//uint8_t keNB[32];
|
//uint8_t keNB[32];
|
||||||
|
|
||||||
ambr_t ambr;
|
ambr_t ambr;
|
||||||
ambr_t apn_ambr;
|
ambr_t apn_ambr;
|
||||||
|
|
||||||
/* EPS bearer ID */
|
/* EPS bearer ID */
|
||||||
unsigned ebi:4;
|
unsigned ebi:4;
|
||||||
|
|
||||||
/* QoS */
|
/* QoS */
|
||||||
qci_t qci;
|
qci_t qci;
|
||||||
priority_level_t prio_level;
|
priority_level_t prio_level;
|
||||||
pre_emp_vulnerability_t pre_emp_vulnerability;
|
pre_emp_vulnerability_t pre_emp_vulnerability;
|
||||||
pre_emp_capability_t pre_emp_capability;
|
pre_emp_capability_t pre_emp_capability;
|
||||||
|
|
||||||
/* S-GW TEID for user-plane */
|
/* S-GW TEID for user-plane */
|
||||||
Teid_t sgw_s1u_teid;
|
Teid_t sgw_s1u_teid;
|
||||||
/* S-GW IP address for User-Plane */
|
/* S-GW IP address for User-Plane */
|
||||||
ip_address_t sgw_s1u_address;
|
ip_address_t sgw_s1u_address;
|
||||||
} nas_pdn_connectivity_rsp_t;
|
} nas_pdn_connectivity_rsp_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_pdn_connectivity_fail_s {
|
typedef struct nas_pdn_connectivity_fail_s {
|
||||||
unsigned ue_id; // nas ref
|
unsigned ue_id; // nas ref
|
||||||
} nas_pdn_connectivity_fail_t;
|
} nas_pdn_connectivity_fail_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_conn_est_ind_s {
|
typedef struct nas_conn_est_ind_s {
|
||||||
nas_establish_ind_t nas;
|
nas_establish_ind_t nas;
|
||||||
|
|
||||||
/* Transparent message from s1ap to be forwarded to MME_APP or
|
/* Transparent message from s1ap to be forwarded to MME_APP or
|
||||||
* to S1AP if connection establishment is rejected by NAS.
|
* to S1AP if connection establishment is rejected by NAS.
|
||||||
*/
|
*/
|
||||||
s1ap_initial_ue_message_t transparent;
|
s1ap_initial_ue_message_t transparent;
|
||||||
} nas_conn_est_ind_t;
|
} nas_conn_est_ind_t;
|
||||||
|
|
||||||
|
|
||||||
@@ -239,11 +239,11 @@ typedef nas_establish_rsp_t nas_conn_est_rej_t;
|
|||||||
|
|
||||||
#if defined(DISABLE_USE_NAS)
|
#if defined(DISABLE_USE_NAS)
|
||||||
typedef struct nas_conn_est_cnf_s {
|
typedef struct nas_conn_est_cnf_s {
|
||||||
uint32_t ue_id;
|
uint32_t ue_id;
|
||||||
|
|
||||||
nas_establish_cnf_t nas_establish_cnf;
|
nas_establish_cnf_t nas_establish_cnf;
|
||||||
/* Transparent message from MME_APP to S1AP */
|
/* Transparent message from MME_APP to S1AP */
|
||||||
s1ap_initial_ctxt_setup_req_t transparent;
|
s1ap_initial_ctxt_setup_req_t transparent;
|
||||||
} nas_conn_est_cnf_t;
|
} nas_conn_est_cnf_t;
|
||||||
#else
|
#else
|
||||||
typedef nas_establish_cnf_t nas_conn_est_cnf_t;
|
typedef nas_establish_cnf_t nas_conn_est_cnf_t;
|
||||||
@@ -279,69 +279,69 @@ typedef struct nas_rab_rel_req_s {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct nas_attach_req_s {
|
typedef struct nas_attach_req_s {
|
||||||
/* TODO: Set the correct size */
|
/* TODO: Set the correct size */
|
||||||
char apn[100];
|
char apn[100];
|
||||||
char imsi[16];
|
char imsi[16];
|
||||||
#define INITIAL_REQUEST (0x1)
|
#define INITIAL_REQUEST (0x1)
|
||||||
unsigned initial:1;
|
unsigned initial:1;
|
||||||
s1ap_initial_ue_message_t transparent;
|
s1ap_initial_ue_message_t transparent;
|
||||||
} nas_attach_req_t;
|
} nas_attach_req_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_auth_req_s {
|
typedef struct nas_auth_req_s {
|
||||||
/* UE imsi */
|
/* UE imsi */
|
||||||
char imsi[16];
|
char imsi[16];
|
||||||
|
|
||||||
#define NAS_FAILURE_OK 0x0
|
#define NAS_FAILURE_OK 0x0
|
||||||
#define NAS_FAILURE_IND 0x1
|
#define NAS_FAILURE_IND 0x1
|
||||||
unsigned failure:1;
|
unsigned failure:1;
|
||||||
int cause;
|
int cause;
|
||||||
} nas_auth_req_t;
|
} nas_auth_req_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_auth_resp_s {
|
typedef struct nas_auth_resp_s {
|
||||||
char imsi[16];
|
char imsi[16];
|
||||||
} nas_auth_resp_t;
|
} nas_auth_resp_t;
|
||||||
|
|
||||||
typedef struct nas_auth_param_req_s {
|
typedef struct nas_auth_param_req_s {
|
||||||
/* UE identifier */
|
/* UE identifier */
|
||||||
uint32_t ue_id;
|
uint32_t ue_id;
|
||||||
|
|
||||||
/* Imsi of the UE (In case of initial request) */
|
/* Imsi of the UE (In case of initial request) */
|
||||||
char imsi[16];
|
char imsi[16];
|
||||||
uint8_t imsi_length;
|
uint8_t imsi_length;
|
||||||
|
|
||||||
/* Indicates whether the procedure corresponds to a new connection or not */
|
/* Indicates whether the procedure corresponds to a new connection or not */
|
||||||
uint8_t initial_req:1;
|
uint8_t initial_req:1;
|
||||||
|
|
||||||
uint8_t re_synchronization:1;
|
uint8_t re_synchronization:1;
|
||||||
uint8_t auts[14];
|
uint8_t auts[14];
|
||||||
} nas_auth_param_req_t;
|
} nas_auth_param_req_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct nas_auth_param_rsp_s {
|
typedef struct nas_auth_param_rsp_s {
|
||||||
/* UE identifier */
|
/* UE identifier */
|
||||||
uint32_t ue_id;
|
uint32_t ue_id;
|
||||||
|
|
||||||
/* For future use: nb of vectors provided */
|
/* For future use: nb of vectors provided */
|
||||||
uint8_t nb_vectors;
|
uint8_t nb_vectors;
|
||||||
|
|
||||||
/* Consider only one E-UTRAN vector for the moment... */
|
/* Consider only one E-UTRAN vector for the moment... */
|
||||||
eutran_vector_t vector;
|
eutran_vector_t vector;
|
||||||
} nas_auth_param_rsp_t;
|
} nas_auth_param_rsp_t;
|
||||||
|
|
||||||
typedef struct nas_auth_param_fail_s {
|
typedef struct nas_auth_param_fail_s {
|
||||||
/* UE identifier */
|
/* UE identifier */
|
||||||
uint32_t ue_id;
|
uint32_t ue_id;
|
||||||
|
|
||||||
/* S6A mapped to NAS cause */
|
/* S6A mapped to NAS cause */
|
||||||
nas_cause_t cause;
|
nas_cause_t cause;
|
||||||
} nas_auth_param_fail_t;
|
} nas_auth_param_fail_t;
|
||||||
|
|
||||||
|
|
||||||
#if defined(DISABLE_USE_NAS)
|
#if defined(DISABLE_USE_NAS)
|
||||||
typedef struct nas_attach_accept_s {
|
typedef struct nas_attach_accept_s {
|
||||||
s1ap_initial_ctxt_setup_req_t transparent;
|
s1ap_initial_ctxt_setup_req_t transparent;
|
||||||
} nas_attach_accept_t;
|
} nas_attach_accept_t;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -33,51 +33,51 @@
|
|||||||
#define S1AP_DEREGISTER_UE_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_deregister_ue_req
|
#define S1AP_DEREGISTER_UE_REQ(mSGpTR) (mSGpTR)->ittiMsg.s1ap_deregister_ue_req
|
||||||
|
|
||||||
typedef struct s1ap_initial_ue_message_s {
|
typedef struct s1ap_initial_ue_message_s {
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
uint32_t mme_ue_s1ap_id;
|
uint32_t mme_ue_s1ap_id;
|
||||||
cgi_t e_utran_cgi;
|
cgi_t e_utran_cgi;
|
||||||
} s1ap_initial_ue_message_t;
|
} s1ap_initial_ue_message_t;
|
||||||
|
|
||||||
typedef struct s1ap_initial_ctxt_setup_req_s {
|
typedef struct s1ap_initial_ctxt_setup_req_s {
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
uint32_t mme_ue_s1ap_id;
|
uint32_t mme_ue_s1ap_id;
|
||||||
|
|
||||||
/* Key eNB */
|
/* Key eNB */
|
||||||
uint8_t keNB[32];
|
uint8_t keNB[32];
|
||||||
|
|
||||||
ambr_t ambr;
|
ambr_t ambr;
|
||||||
ambr_t apn_ambr;
|
ambr_t apn_ambr;
|
||||||
|
|
||||||
/* EPS bearer ID */
|
/* EPS bearer ID */
|
||||||
unsigned ebi:4;
|
unsigned ebi:4;
|
||||||
|
|
||||||
/* QoS */
|
/* QoS */
|
||||||
qci_t qci;
|
qci_t qci;
|
||||||
priority_level_t prio_level;
|
priority_level_t prio_level;
|
||||||
pre_emp_vulnerability_t pre_emp_vulnerability;
|
pre_emp_vulnerability_t pre_emp_vulnerability;
|
||||||
pre_emp_capability_t pre_emp_capability;
|
pre_emp_capability_t pre_emp_capability;
|
||||||
|
|
||||||
/* S-GW TEID for user-plane */
|
/* S-GW TEID for user-plane */
|
||||||
Teid_t teid;
|
Teid_t teid;
|
||||||
/* S-GW IP address for User-Plane */
|
/* S-GW IP address for User-Plane */
|
||||||
ip_address_t s_gw_address;
|
ip_address_t s_gw_address;
|
||||||
} s1ap_initial_ctxt_setup_req_t;
|
} s1ap_initial_ctxt_setup_req_t;
|
||||||
|
|
||||||
typedef struct s1ap_ue_cap_ind_s {
|
typedef struct s1ap_ue_cap_ind_s {
|
||||||
unsigned eNB_ue_s1ap_id:24;
|
unsigned eNB_ue_s1ap_id:24;
|
||||||
uint32_t mme_ue_s1ap_id;
|
uint32_t mme_ue_s1ap_id;
|
||||||
uint8_t radio_capabilities[100];
|
uint8_t radio_capabilities[100];
|
||||||
uint32_t radio_capabilities_length;
|
uint32_t radio_capabilities_length;
|
||||||
} s1ap_ue_cap_ind_t;
|
} s1ap_ue_cap_ind_t;
|
||||||
|
|
||||||
#define S1AP_ITTI_UE_PER_DEREGISTER_MESSAGE 20
|
#define S1AP_ITTI_UE_PER_DEREGISTER_MESSAGE 20
|
||||||
typedef struct s1ap_eNB_deregistered_ind_s {
|
typedef struct s1ap_eNB_deregistered_ind_s {
|
||||||
uint8_t nb_ue_to_deregister;
|
uint8_t nb_ue_to_deregister;
|
||||||
uint32_t mme_ue_s1ap_id[S1AP_ITTI_UE_PER_DEREGISTER_MESSAGE];
|
uint32_t mme_ue_s1ap_id[S1AP_ITTI_UE_PER_DEREGISTER_MESSAGE];
|
||||||
} s1ap_eNB_deregistered_ind_t;
|
} s1ap_eNB_deregistered_ind_t;
|
||||||
|
|
||||||
typedef struct s1ap_deregister_ue_req_s {
|
typedef struct s1ap_deregister_ue_req_s {
|
||||||
uint32_t mme_ue_s1ap_id;
|
uint32_t mme_ue_s1ap_id;
|
||||||
} s1ap_deregister_ue_req_t;
|
} s1ap_deregister_ue_req_t;
|
||||||
|
|
||||||
#endif /* S1AP_MESSAGES_TYPES_H_ */
|
#endif /* S1AP_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -33,62 +33,62 @@
|
|||||||
|
|
||||||
typedef struct s6a_update_location_req_s {
|
typedef struct s6a_update_location_req_s {
|
||||||
#define SKIP_SUBSCRIBER_DATA (0x1)
|
#define SKIP_SUBSCRIBER_DATA (0x1)
|
||||||
unsigned skip_subscriber_data:1;
|
unsigned skip_subscriber_data:1;
|
||||||
#define INITIAL_ATTACH (0x1)
|
#define INITIAL_ATTACH (0x1)
|
||||||
unsigned initial_attach:1;
|
unsigned initial_attach:1;
|
||||||
|
|
||||||
char imsi[IMSI_DIGITS_MAX + 1]; // username
|
char imsi[IMSI_DIGITS_MAX + 1]; // username
|
||||||
uint8_t imsi_length; // username
|
uint8_t imsi_length; // username
|
||||||
|
|
||||||
plmn_t visited_plmn; // visited plmn id
|
plmn_t visited_plmn; // visited plmn id
|
||||||
rat_type_t rat_type; // rat type
|
rat_type_t rat_type; // rat type
|
||||||
|
|
||||||
// missing // origin host
|
// missing // origin host
|
||||||
// missing // origin realm
|
// missing // origin realm
|
||||||
|
|
||||||
// missing // destination host
|
// missing // destination host
|
||||||
// missing // destination realm
|
// missing // destination realm
|
||||||
} s6a_update_location_req_t;
|
} s6a_update_location_req_t;
|
||||||
|
|
||||||
typedef struct s6a_update_location_ans_s {
|
typedef struct s6a_update_location_ans_s {
|
||||||
s6a_result_t result; // Result of the update location request procedure
|
s6a_result_t result; // Result of the update location request procedure
|
||||||
subscription_data_t subscription_data; // subscriber status,
|
subscription_data_t subscription_data; // subscriber status,
|
||||||
// Maximum Requested Bandwidth Uplink, downlink
|
// Maximum Requested Bandwidth Uplink, downlink
|
||||||
// access restriction data
|
// access restriction data
|
||||||
// msisdn
|
// msisdn
|
||||||
apn_config_profile_t apn_config_profile;// APN configuration profile
|
apn_config_profile_t apn_config_profile;// APN configuration profile
|
||||||
|
|
||||||
network_access_mode_t access_mode;
|
network_access_mode_t access_mode;
|
||||||
rau_tau_timer_t rau_tau_timer;
|
rau_tau_timer_t rau_tau_timer;
|
||||||
char imsi[IMSI_DIGITS_MAX + 1];
|
char imsi[IMSI_DIGITS_MAX + 1];
|
||||||
uint8_t imsi_length;
|
uint8_t imsi_length;
|
||||||
|
|
||||||
|
|
||||||
} s6a_update_location_ans_t;
|
} s6a_update_location_ans_t;
|
||||||
|
|
||||||
typedef struct s6a_auth_info_req_s {
|
typedef struct s6a_auth_info_req_s {
|
||||||
char imsi[IMSI_DIGITS_MAX + 1];
|
char imsi[IMSI_DIGITS_MAX + 1];
|
||||||
uint8_t imsi_length;
|
uint8_t imsi_length;
|
||||||
plmn_t visited_plmn;
|
plmn_t visited_plmn;
|
||||||
/* Number of vectors to retrieve from HSS, should be equal to one */
|
/* Number of vectors to retrieve from HSS, should be equal to one */
|
||||||
uint8_t nb_of_vectors;
|
uint8_t nb_of_vectors;
|
||||||
|
|
||||||
/* Bit to indicate that USIM has requested a re-synchronization of SQN */
|
/* Bit to indicate that USIM has requested a re-synchronization of SQN */
|
||||||
unsigned re_synchronization:1;
|
unsigned re_synchronization:1;
|
||||||
/* AUTS to provide to AUC.
|
/* AUTS to provide to AUC.
|
||||||
* Only present and interpreted if re_synchronization == 1.
|
* Only present and interpreted if re_synchronization == 1.
|
||||||
*/
|
*/
|
||||||
uint8_t auts[AUTS_LENGTH];
|
uint8_t auts[AUTS_LENGTH];
|
||||||
} s6a_auth_info_req_t;
|
} s6a_auth_info_req_t;
|
||||||
|
|
||||||
typedef struct s6a_auth_info_ans_s {
|
typedef struct s6a_auth_info_ans_s {
|
||||||
char imsi[IMSI_DIGITS_MAX + 1];
|
char imsi[IMSI_DIGITS_MAX + 1];
|
||||||
uint8_t imsi_length;
|
uint8_t imsi_length;
|
||||||
|
|
||||||
/* Result of the authentication information procedure */
|
/* Result of the authentication information procedure */
|
||||||
s6a_result_t result;
|
s6a_result_t result;
|
||||||
/* Authentication info containing the vector(s) */
|
/* Authentication info containing the vector(s) */
|
||||||
authentication_info_t auth_info;
|
authentication_info_t auth_info;
|
||||||
} s6a_auth_info_ans_t;
|
} s6a_auth_info_ans_t;
|
||||||
|
|
||||||
#endif /* S6A_MESSAGES_TYPES_H_ */
|
#endif /* S6A_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -35,42 +35,42 @@
|
|||||||
#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association
|
#define SCTP_CLOSE_ASSOCIATION(mSGpTR) (mSGpTR)->ittiMsg.sctp_close_association
|
||||||
|
|
||||||
typedef struct sctp_data_req_s {
|
typedef struct sctp_data_req_s {
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
uint32_t bufLen;
|
uint32_t bufLen;
|
||||||
uint32_t assocId;
|
uint32_t assocId;
|
||||||
uint16_t stream;
|
uint16_t stream;
|
||||||
} sctp_data_req_t;
|
} sctp_data_req_t;
|
||||||
|
|
||||||
typedef struct sctp_data_ind_s {
|
typedef struct sctp_data_ind_s {
|
||||||
uint8_t *buffer; ///< SCTP buffer
|
uint8_t *buffer; ///< SCTP buffer
|
||||||
uint32_t buf_length; ///< SCTP buffer length
|
uint32_t buf_length; ///< SCTP buffer length
|
||||||
int32_t assoc_id; ///< SCTP physical association ID
|
int32_t assoc_id; ///< SCTP physical association ID
|
||||||
uint8_t stream; ///< Stream number on which data had been received
|
uint8_t stream; ///< Stream number on which data had been received
|
||||||
uint16_t instreams; ///< Number of input streams for the SCTP connection between peers
|
uint16_t instreams; ///< Number of input streams for the SCTP connection between peers
|
||||||
uint16_t outstreams; ///< Number of output streams for the SCTP connection between peers
|
uint16_t outstreams; ///< Number of output streams for the SCTP connection between peers
|
||||||
} sctp_data_ind_t;
|
} sctp_data_ind_t;
|
||||||
|
|
||||||
typedef struct sctp_init_s {
|
typedef struct sctp_init_s {
|
||||||
/* Request usage of ipv4 */
|
/* Request usage of ipv4 */
|
||||||
unsigned ipv4:1;
|
unsigned ipv4:1;
|
||||||
/* Request usage of ipv6 */
|
/* Request usage of ipv6 */
|
||||||
unsigned ipv6:1;
|
unsigned ipv6:1;
|
||||||
uint8_t nb_ipv4_addr;
|
uint8_t nb_ipv4_addr;
|
||||||
uint32_t ipv4_address[10];
|
uint32_t ipv4_address[10];
|
||||||
uint8_t nb_ipv6_addr;
|
uint8_t nb_ipv6_addr;
|
||||||
char *ipv6_address[10];
|
char *ipv6_address[10];
|
||||||
uint16_t port;
|
uint16_t port;
|
||||||
uint32_t ppid;
|
uint32_t ppid;
|
||||||
} SctpInit;
|
} SctpInit;
|
||||||
|
|
||||||
typedef struct sctp_close_association_s {
|
typedef struct sctp_close_association_s {
|
||||||
uint32_t assoc_id;
|
uint32_t assoc_id;
|
||||||
} sctp_close_association_t;
|
} sctp_close_association_t;
|
||||||
|
|
||||||
typedef struct sctp_new_peer_s {
|
typedef struct sctp_new_peer_s {
|
||||||
uint32_t instreams;
|
uint32_t instreams;
|
||||||
uint32_t outstreams;
|
uint32_t outstreams;
|
||||||
uint32_t assoc_id;
|
uint32_t assoc_id;
|
||||||
} sctp_new_peer_t;
|
} sctp_new_peer_t;
|
||||||
|
|
||||||
#endif /* SCTP_MESSAGES_TYPES_H_ */
|
#endif /* SCTP_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -92,8 +92,8 @@ do { \
|
|||||||
|
|
||||||
/* RES amd XRES can have a variable length of 4-16 octets */
|
/* RES amd XRES can have a variable length of 4-16 octets */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t size;
|
uint8_t size;
|
||||||
uint8_t data[XRES_LENGTH_MAX];
|
uint8_t data[XRES_LENGTH_MAX];
|
||||||
} res_t;
|
} res_t;
|
||||||
|
|
||||||
#define FORMAT_128BITS "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x"
|
#define FORMAT_128BITS "%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x,%02x"
|
||||||
@@ -116,14 +116,14 @@ bUFFER[24], bUFFER[25], bUFFER[26], bUFFER[27], bUFFER[28], bUFFER[29], bUFFER[3
|
|||||||
|
|
||||||
/* Holds an E-UTRAN authentication vector */
|
/* Holds an E-UTRAN authentication vector */
|
||||||
typedef struct eutran_vector_s {
|
typedef struct eutran_vector_s {
|
||||||
uint8_t rand[RAND_LENGTH_OCTETS];
|
uint8_t rand[RAND_LENGTH_OCTETS];
|
||||||
res_t xres;
|
res_t xres;
|
||||||
uint8_t autn[AUTN_LENGTH_OCTETS];
|
uint8_t autn[AUTN_LENGTH_OCTETS];
|
||||||
uint8_t kasme[KASME_LENGTH_OCTETS];
|
uint8_t kasme[KASME_LENGTH_OCTETS];
|
||||||
|
|
||||||
/* one UE can have multiple vectors so use STAILQ lists for easy management */
|
/* one UE can have multiple vectors so use STAILQ lists for easy management */
|
||||||
#if 0
|
#if 0
|
||||||
STAILQ_ENTRY(eutran_vector_s) entries;
|
STAILQ_ENTRY(eutran_vector_s) entries;
|
||||||
#endif
|
#endif
|
||||||
} eutran_vector_t;
|
} eutran_vector_t;
|
||||||
|
|
||||||
@@ -143,12 +143,12 @@ typedef struct eutran_vector_s {
|
|||||||
#define FC_KASME_TO_CK (0x16)
|
#define FC_KASME_TO_CK (0x16)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
NAS_ENC_ALG = 0x01,
|
NAS_ENC_ALG = 0x01,
|
||||||
NAS_INT_ALG = 0x02,
|
NAS_INT_ALG = 0x02,
|
||||||
RRC_ENC_ALG = 0x03,
|
RRC_ENC_ALG = 0x03,
|
||||||
RRC_INT_ALG = 0x04,
|
RRC_INT_ALG = 0x04,
|
||||||
UP_ENC_ALG = 0x05,
|
UP_ENC_ALG = 0x05,
|
||||||
UP_INT_ALG = 0x06
|
UP_INT_ALG = 0x06
|
||||||
} algorithm_type_dist_t;
|
} algorithm_type_dist_t;
|
||||||
|
|
||||||
#endif /* SECURITY_TYPES_H_ */
|
#endif /* SECURITY_TYPES_H_ */
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -32,23 +32,23 @@
|
|||||||
#define UDP_INIT(mSGpTR) (mSGpTR)->ittiMsg.udp_init
|
#define UDP_INIT(mSGpTR) (mSGpTR)->ittiMsg.udp_init
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint32_t port;
|
uint32_t port;
|
||||||
char *address;
|
char *address;
|
||||||
} udp_init_t;
|
} udp_init_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
uint32_t buffer_length;
|
uint32_t buffer_length;
|
||||||
uint32_t buffer_offset;
|
uint32_t buffer_offset;
|
||||||
uint32_t peer_address;
|
uint32_t peer_address;
|
||||||
uint32_t peer_port;
|
uint32_t peer_port;
|
||||||
} udp_data_req_t;
|
} udp_data_req_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t *buffer;
|
uint8_t *buffer;
|
||||||
uint32_t buffer_length;
|
uint32_t buffer_length;
|
||||||
uint32_t peer_address;
|
uint32_t peer_address;
|
||||||
uint32_t peer_port;
|
uint32_t peer_port;
|
||||||
} udp_data_ind_t;
|
} udp_data_ind_t;
|
||||||
|
|
||||||
#endif /* UDP_MESSAGES_TYPES_H_ */
|
#endif /* UDP_MESSAGES_TYPES_H_ */
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#define XT_GTPUAH_VERSION IPTABLES_VERSION_STRING
|
#define XT_GTPUAH_VERSION IPTABLES_VERSION_STRING
|
||||||
#define gtpuah_strtoui(s,v,m,M) !string_to_number(s,m,M,v)
|
#define gtpuah_strtoui(s,v,m,M) !string_to_number(s,m,M,v)
|
||||||
#define gtpuah_exit_error exit_error
|
#define gtpuah_exit_error exit_error
|
||||||
#elif (IPTVERSION > 135) && (IPTVERSION <= 141)
|
#elif (IPTVERSION > 135) && (IPTVERSION <= 141)
|
||||||
#define GTPUAH_PARAM_BAD_VALUE P_BAD_VALUE
|
#define GTPUAH_PARAM_BAD_VALUE P_BAD_VALUE
|
||||||
#define GTPUAH_PARAM_ONLY_ONCE P_ONLY_ONCE
|
#define GTPUAH_PARAM_ONLY_ONCE P_ONLY_ONCE
|
||||||
#define XT_GTPUAH_VERSION XTABLES_VERSION
|
#define XT_GTPUAH_VERSION XTABLES_VERSION
|
||||||
@@ -50,246 +50,246 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PARAM_LADDR = 1 << 0,
|
PARAM_LADDR = 1 << 0,
|
||||||
PARAM_LTUN = 1 << 1,
|
PARAM_LTUN = 1 << 1,
|
||||||
PARAM_RADDR = 1 << 2,
|
PARAM_RADDR = 1 << 2,
|
||||||
PARAM_RTUN = 1 << 3,
|
PARAM_RTUN = 1 << 3,
|
||||||
PARAM_ACTION = 1 << 4,
|
PARAM_ACTION = 1 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void GTPUAH_help(void)
|
static void GTPUAH_help(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"GTPUAH target options\n"
|
"GTPUAH target options\n"
|
||||||
" --action value Set action <value: add>\n"
|
" --action value Set action <value: add>\n"
|
||||||
" --own-ip value Set own IP address\n"
|
" --own-ip value Set own IP address\n"
|
||||||
" --own-tun value Set own tunnel id <value: 1-2^31>\n"
|
" --own-tun value Set own tunnel id <value: 1-2^31>\n"
|
||||||
" --peer-ip value Set peer IP address\n"
|
" --peer-ip value Set peer IP address\n"
|
||||||
" --peer-tun value Set peer tunnel id <value: 1-2^31>\n");
|
" --peer-tun value Set peer tunnel id <value: 1-2^31>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
/* Stolen from iptables v1.4.7 code */
|
/* Stolen from iptables v1.4.7 code */
|
||||||
void gtpuah_param_act(unsigned int status, const char *p1, ...)
|
void gtpuah_param_act(unsigned int status, const char *p1, ...)
|
||||||
{
|
{
|
||||||
const char *p2, *p3;
|
const char *p2, *p3;
|
||||||
va_list args;
|
va_list args;
|
||||||
int b;
|
int b;
|
||||||
|
|
||||||
va_start(args, p1);
|
va_start(args, p1);
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case GTPUAH_PARAM_ONLY_ONCE:
|
case GTPUAH_PARAM_ONLY_ONCE:
|
||||||
p2 = va_arg(args, const char *);
|
p2 = va_arg(args, const char *);
|
||||||
b = va_arg(args, unsigned int);
|
b = va_arg(args, unsigned int);
|
||||||
if (!b)
|
|
||||||
return;
|
|
||||||
exit_error(PARAMETER_PROBLEM,
|
|
||||||
"%s: \"%s\" option may only be specified once",
|
|
||||||
p1, p2);
|
|
||||||
break;
|
|
||||||
case GTPUAH_PARAM_BAD_VALUE:
|
|
||||||
p2 = va_arg(args, const char *);
|
|
||||||
p3 = va_arg(args, const char *);
|
|
||||||
exit_error(PARAMETER_PROBLEM,
|
|
||||||
"%s: Bad value for \"%s\" option: \"%s\"",
|
|
||||||
p1, p2, p3);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
exit_error(status, "%s", "Unknown error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(args);
|
if (!b)
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_error(PARAMETER_PROBLEM,
|
||||||
|
"%s: \"%s\" option may only be specified once",
|
||||||
|
p1, p2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GTPUAH_PARAM_BAD_VALUE:
|
||||||
|
p2 = va_arg(args, const char *);
|
||||||
|
p3 = va_arg(args, const char *);
|
||||||
|
exit_error(PARAMETER_PROBLEM,
|
||||||
|
"%s: Bad value for \"%s\" option: \"%s\"",
|
||||||
|
p1, p2, p3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
exit_error(status, "%s", "Unknown error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void parse_gtpuah_addr(const char *s, struct xt_gtpuah_target_info *info, int flag)
|
static void parse_gtpuah_addr(const char *s, struct xt_gtpuah_target_info *info, int flag)
|
||||||
{
|
{
|
||||||
in_addr_t addr;
|
in_addr_t addr;
|
||||||
|
|
||||||
if ((addr = inet_addr(s)) == -1)
|
if ((addr = inet_addr(s)) == -1) {
|
||||||
{
|
switch (flag) {
|
||||||
switch (flag)
|
case PARAM_LADDR:
|
||||||
{
|
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--own-ip", s);
|
||||||
case PARAM_LADDR:
|
break;
|
||||||
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--own-ip", s);
|
|
||||||
break;
|
case PARAM_RADDR:
|
||||||
case PARAM_RADDR:
|
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--peer-ip", s);
|
||||||
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--peer-ip", s);
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flag)
|
|
||||||
{
|
|
||||||
case PARAM_LADDR:
|
|
||||||
info->laddr = addr;
|
|
||||||
break;
|
|
||||||
case PARAM_RADDR:
|
|
||||||
info->raddr = addr;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case PARAM_LADDR:
|
||||||
|
info->laddr = addr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_RADDR:
|
||||||
|
info->raddr = addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_gtpuah_tunid(char *s, struct xt_gtpuah_target_info *info, int flag)
|
static void parse_gtpuah_tunid(char *s, struct xt_gtpuah_target_info *info, int flag)
|
||||||
{
|
{
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
|
|
||||||
if (!gtpuah_strtoui(s, &value, 0, UINT32_MAX))
|
if (!gtpuah_strtoui(s, &value, 0, UINT32_MAX)) {
|
||||||
{
|
switch (flag) {
|
||||||
switch (flag)
|
case PARAM_LTUN:
|
||||||
{
|
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--own-tun", s);
|
||||||
case PARAM_LTUN:
|
break;
|
||||||
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--own-tun", s);
|
|
||||||
break;
|
|
||||||
case PARAM_RTUN:
|
|
||||||
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--peer-tun", s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (flag)
|
case PARAM_RTUN:
|
||||||
{
|
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--peer-tun", s);
|
||||||
case PARAM_LTUN:
|
break;
|
||||||
info->ltun = value;
|
|
||||||
break;
|
|
||||||
case PARAM_RTUN:
|
|
||||||
info->rtun = value;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case PARAM_LTUN:
|
||||||
|
info->ltun = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_RTUN:
|
||||||
|
info->rtun = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_gtpuah_action(char *s, struct xt_gtpuah_target_info *info, unsigned int *flags)
|
static void parse_gtpuah_action(char *s, struct xt_gtpuah_target_info *info, unsigned int *flags)
|
||||||
{
|
{
|
||||||
if (!strcmp(s, "add"))
|
if (!strcmp(s, "add")) {
|
||||||
{
|
info->action = PARAM_GTPUAH_ACTION_ADD;
|
||||||
info->action = PARAM_GTPUAH_ACTION_ADD;
|
*flags |= PARAM_GTPUAH_ACTION_ADD;
|
||||||
*flags |= PARAM_GTPUAH_ACTION_ADD;
|
} else {
|
||||||
}
|
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--action", s);
|
||||||
else
|
}
|
||||||
{
|
|
||||||
gtpuah_param_act(GTPUAH_PARAM_BAD_VALUE, "GTPUAH", "--action", s);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
static int
|
static int
|
||||||
GTPUAH_parse(int c, char **argv, int invert, unsigned int *flags,
|
GTPUAH_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
const struct ipt_entry *entry,
|
const struct ipt_entry *entry,
|
||||||
struct ipt_entry_target **target)
|
struct ipt_entry_target **target)
|
||||||
#else
|
#else
|
||||||
static int
|
static int
|
||||||
GTPUAH_parse(int c, char **argv, int invert, unsigned int *flags,
|
GTPUAH_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
const void *entry, struct xt_entry_target **target)
|
const void *entry, struct xt_entry_target **target)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
struct xt_gtpuah_target_info *info = (struct xt_gtpuah_target_info *) (*target)->data;
|
struct xt_gtpuah_target_info *info = (struct xt_gtpuah_target_info *) (*target)->data;
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '1':
|
|
||||||
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--own-ip", *flags & PARAM_LADDR);
|
|
||||||
parse_gtpuah_addr(optarg, info, PARAM_LADDR);
|
|
||||||
*flags |= PARAM_LADDR;
|
|
||||||
return 1;
|
|
||||||
case '2':
|
|
||||||
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--own-tun", *flags & PARAM_LTUN);
|
|
||||||
parse_gtpuah_tunid(optarg, info, PARAM_LTUN);
|
|
||||||
*flags |= PARAM_LTUN;
|
|
||||||
return 1;
|
|
||||||
case '3':
|
|
||||||
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--peer-ip", *flags & PARAM_RADDR);
|
|
||||||
parse_gtpuah_addr(optarg, info, PARAM_RADDR);
|
|
||||||
*flags |= PARAM_RADDR;
|
|
||||||
return 1;
|
|
||||||
case '4':
|
|
||||||
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--peer-tun", *flags & PARAM_RTUN);
|
|
||||||
parse_gtpuah_tunid(optarg, info, PARAM_RTUN);
|
|
||||||
*flags |= PARAM_RTUN;
|
|
||||||
return 1;
|
|
||||||
case '5':
|
|
||||||
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--action", *flags & PARAM_ACTION);
|
|
||||||
parse_gtpuah_action(optarg, info, flags);
|
|
||||||
*flags |= PARAM_ACTION;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case '1':
|
||||||
|
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--own-ip", *flags & PARAM_LADDR);
|
||||||
|
parse_gtpuah_addr(optarg, info, PARAM_LADDR);
|
||||||
|
*flags |= PARAM_LADDR;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case '2':
|
||||||
|
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--own-tun", *flags & PARAM_LTUN);
|
||||||
|
parse_gtpuah_tunid(optarg, info, PARAM_LTUN);
|
||||||
|
*flags |= PARAM_LTUN;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case '3':
|
||||||
|
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--peer-ip", *flags & PARAM_RADDR);
|
||||||
|
parse_gtpuah_addr(optarg, info, PARAM_RADDR);
|
||||||
|
*flags |= PARAM_RADDR;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case '4':
|
||||||
|
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--peer-tun", *flags & PARAM_RTUN);
|
||||||
|
parse_gtpuah_tunid(optarg, info, PARAM_RTUN);
|
||||||
|
*flags |= PARAM_RTUN;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case '5':
|
||||||
|
gtpuah_param_act(GTPUAH_PARAM_ONLY_ONCE, "GTPUAH", "--action", *flags & PARAM_ACTION);
|
||||||
|
parse_gtpuah_action(optarg, info, flags);
|
||||||
|
*flags |= PARAM_ACTION;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GTPUAH_check(unsigned int flags)
|
static void GTPUAH_check(unsigned int flags)
|
||||||
{
|
{
|
||||||
if (!(flags & PARAM_ACTION))
|
if (!(flags & PARAM_ACTION)) {
|
||||||
{
|
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify action");
|
||||||
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify action");
|
}
|
||||||
}
|
|
||||||
|
if (!(flags & PARAM_LADDR)) {
|
||||||
if (!(flags & PARAM_LADDR))
|
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify local addr");
|
||||||
{
|
}
|
||||||
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify local addr");
|
|
||||||
}
|
if (!(flags & PARAM_LTUN)) {
|
||||||
if (!(flags & PARAM_LTUN))
|
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify local tunnel id");
|
||||||
{
|
}
|
||||||
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify local tunnel id");
|
|
||||||
}
|
if (!(flags & PARAM_RADDR)) {
|
||||||
if (!(flags & PARAM_RADDR))
|
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify remote addr");
|
||||||
{
|
}
|
||||||
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify remote addr");
|
|
||||||
}
|
if (!(flags & PARAM_RTUN)) {
|
||||||
if (!(flags & PARAM_RTUN))
|
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify remote tunnel id");
|
||||||
{
|
}
|
||||||
gtpuah_exit_error(PARAMETER_PROBLEM, "GTPUAH: You must specify remote tunnel id");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convert_action_to_string(int action, char *actionstr)
|
static void convert_action_to_string(int action, char *actionstr)
|
||||||
{
|
{
|
||||||
switch(action)
|
switch(action) {
|
||||||
{
|
case PARAM_GTPUAH_ACTION_ADD:
|
||||||
case PARAM_GTPUAH_ACTION_ADD:
|
sprintf (actionstr, "add");
|
||||||
sprintf (actionstr, "add");
|
break;
|
||||||
break;
|
|
||||||
default :
|
default :
|
||||||
sprintf (actionstr, "unspecified!!!");
|
sprintf (actionstr, "unspecified!!!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
static void
|
static void
|
||||||
GTPUAH_print(const struct ipt_ip *ip,
|
GTPUAH_print(const struct ipt_ip *ip,
|
||||||
const struct ipt_entry_target *target,
|
const struct ipt_entry_target *target,
|
||||||
int numeric)
|
int numeric)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static void
|
static void
|
||||||
GTPUAH_print(const void *ip,
|
GTPUAH_print(const void *ip,
|
||||||
const struct xt_entry_target *target,
|
const struct xt_entry_target *target,
|
||||||
int numeric)
|
int numeric)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const struct xt_gtpuah_target_info *info =
|
const struct xt_gtpuah_target_info *info =
|
||||||
(struct xt_gtpuah_target_info *) target->data;
|
(struct xt_gtpuah_target_info *) target->data;
|
||||||
|
|
||||||
char laddr[64], raddr[64], actionstr[32];
|
char laddr[64], raddr[64], actionstr[32];
|
||||||
|
|
||||||
convert_action_to_string(info->action, actionstr);
|
convert_action_to_string(info->action, actionstr);
|
||||||
|
|
||||||
sprintf (laddr, "%s", inet_ntoa(*(struct in_addr*)&info->laddr));
|
sprintf (laddr, "%s", inet_ntoa(*(struct in_addr*)&info->laddr));
|
||||||
sprintf (raddr, "%s", inet_ntoa(*(struct in_addr*)&info->raddr));
|
sprintf (raddr, "%s", inet_ntoa(*(struct in_addr*)&info->raddr));
|
||||||
printf("GTPUAH self: %s tunnel: 0x%x / peer: %s tunnel: 0x%x / action: %s",
|
printf("GTPUAH self: %s tunnel: 0x%x / peer: %s tunnel: 0x%x / action: %s",
|
||||||
laddr, info->ltun, raddr, info->rtun, actionstr);
|
laddr, info->ltun, raddr, info->rtun, actionstr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct option GTPUAH_opts[] = {
|
static struct option GTPUAH_opts[] = {
|
||||||
{ "own-ip", 1, NULL, '1' },
|
{ "own-ip", 1, NULL, '1' },
|
||||||
{ "own-tun", 1, NULL, '2' },
|
{ "own-tun", 1, NULL, '2' },
|
||||||
{ "peer-ip", 1, NULL, '3' },
|
{ "peer-ip", 1, NULL, '3' },
|
||||||
{ "peer-tun", 1, NULL, '4' },
|
{ "peer-tun", 1, NULL, '4' },
|
||||||
{ "action", 1, NULL, '5' },
|
{ "action", 1, NULL, '5' },
|
||||||
{ .name = NULL }
|
{ .name = NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
@@ -297,26 +297,26 @@ static struct iptables_target gtpuah_tg_reg = {
|
|||||||
#else
|
#else
|
||||||
static struct xtables_target gtpuah_tg_reg = {
|
static struct xtables_target gtpuah_tg_reg = {
|
||||||
#endif
|
#endif
|
||||||
.name = "GTPUAH",
|
.name = "GTPUAH",
|
||||||
.version = XT_GTPUAH_VERSION,
|
.version = XT_GTPUAH_VERSION,
|
||||||
#if (IPTVERSION > 135)
|
#if (IPTVERSION > 135)
|
||||||
.family = NFPROTO_IPV4,
|
.family = NFPROTO_IPV4,
|
||||||
#endif
|
#endif
|
||||||
.size = XT_ALIGN(sizeof(struct xt_gtpuah_target_info)),
|
.size = XT_ALIGN(sizeof(struct xt_gtpuah_target_info)),
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_gtpuah_target_info)),
|
.userspacesize = XT_ALIGN(sizeof(struct xt_gtpuah_target_info)),
|
||||||
.help = GTPUAH_help,
|
.help = GTPUAH_help,
|
||||||
.parse = GTPUAH_parse,
|
.parse = GTPUAH_parse,
|
||||||
.final_check = GTPUAH_check,
|
.final_check = GTPUAH_check,
|
||||||
.print = GTPUAH_print,
|
.print = GTPUAH_print,
|
||||||
.extra_opts = GTPUAH_opts,
|
.extra_opts = GTPUAH_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
void _init(void)
|
void _init(void)
|
||||||
{
|
{
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
register_target(>puah_tg_reg);
|
register_target(>puah_tg_reg);
|
||||||
#else
|
#else
|
||||||
xtables_register_target(>puah_tg_reg);
|
xtables_register_target(>puah_tg_reg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,13 @@
|
|||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
#include <linux/route.h>
|
#include <linux/route.h>
|
||||||
#include <linux/time.h>
|
#include <linux/time.h>
|
||||||
#include <net/checksum.h>
|
#include <net/checksum.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/udp.h>
|
#include <net/udp.h>
|
||||||
#include <net/inet_sock.h>
|
#include <net/inet_sock.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
#include <net/addrconf.h>
|
#include <net/addrconf.h>
|
||||||
#include <net/ip6_checksum.h>
|
#include <net/ip6_checksum.h>
|
||||||
#include <net/ip6_route.h>
|
#include <net/ip6_route.h>
|
||||||
@@ -57,37 +57,37 @@ static int __init gtpuah_tg_init(void);
|
|||||||
static void __exit gtpuah_tg_exit(void);
|
static void __exit gtpuah_tg_exit(void);
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static struct xt_target gtpuah_tg_reg[] __read_mostly = {
|
static struct xt_target gtpuah_tg_reg[] __read_mostly = {
|
||||||
{
|
{
|
||||||
.name = "GTPUAH",
|
.name = "GTPUAH",
|
||||||
.revision = 0,
|
.revision = 0,
|
||||||
.family = NFPROTO_IPV4,
|
.family = NFPROTO_IPV4,
|
||||||
.hooks = (1 << NF_INET_POST_ROUTING) |
|
.hooks = (1 << NF_INET_POST_ROUTING) |
|
||||||
(1 << NF_INET_LOCAL_IN),
|
(1 << NF_INET_LOCAL_IN),
|
||||||
.table = "mangle",
|
.table = "mangle",
|
||||||
.target = gtpuah_tg4,
|
.target = gtpuah_tg4,
|
||||||
.targetsize = sizeof(struct xt_gtpuah_target_info),
|
.targetsize = sizeof(struct xt_gtpuah_target_info),
|
||||||
.me = THIS_MODULE,
|
.me = THIS_MODULE,
|
||||||
},
|
},
|
||||||
#ifdef WITH_IPV6
|
#ifdef WITH_IPV6
|
||||||
{
|
{
|
||||||
.name = "GTPUAH",
|
.name = "GTPUAH",
|
||||||
.revision = 0,
|
.revision = 0,
|
||||||
.family = NFPROTO_IPV6,
|
.family = NFPROTO_IPV6,
|
||||||
.hooks = (1 << NF_INET_POST_ROUTING) |
|
.hooks = (1 << NF_INET_POST_ROUTING) |
|
||||||
(1 << NF_INET_LOCAL_IN),
|
(1 << NF_INET_LOCAL_IN),
|
||||||
.table = "mangle",
|
.table = "mangle",
|
||||||
.target = gtpuah_tg6,
|
.target = gtpuah_tg6,
|
||||||
.targetsize = sizeof(struct xt_gtpuah_target_info),
|
.targetsize = sizeof(struct xt_gtpuah_target_info),
|
||||||
.me = THIS_MODULE,
|
.me = THIS_MODULE,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gtpuhdr {
|
struct gtpuhdr {
|
||||||
char flags;
|
char flags;
|
||||||
char msgtype;
|
char msgtype;
|
||||||
u_int16_t length;
|
u_int16_t length;
|
||||||
u_int32_t tunid;
|
u_int32_t tunid;
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -116,21 +116,39 @@ INT_MODULE_PARM(mtu, 1564);
|
|||||||
MODULE_PARM_DESC(mtu, "MTU of the S1U IP interface");
|
MODULE_PARM_DESC(mtu, "MTU of the S1U IP interface");
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static char*
|
static char*
|
||||||
_gtpuah_nf_inet_hook_2_string(int nf_inet_hookP) {
|
_gtpuah_nf_inet_hook_2_string(int nf_inet_hookP)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
switch (nf_inet_hookP) {
|
//-----------------------------------------------------------------------------
|
||||||
case NF_INET_PRE_ROUTING: return "NF_INET_PRE_ROUTING";break;
|
switch (nf_inet_hookP) {
|
||||||
case NF_INET_LOCAL_IN: return "NF_INET_LOCAL_IN";break;
|
case NF_INET_PRE_ROUTING:
|
||||||
case NF_INET_FORWARD: return "NF_INET_FORWARD";break;
|
return "NF_INET_PRE_ROUTING";
|
||||||
case NF_INET_LOCAL_OUT: return "NF_INET_LOCAL_OUT";break;
|
break;
|
||||||
case NF_INET_POST_ROUTING: return "NF_INET_POST_ROUTING";break;
|
|
||||||
default: return "NF_INET_UNKNOWN";
|
case NF_INET_LOCAL_IN:
|
||||||
}
|
return "NF_INET_LOCAL_IN";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NF_INET_FORWARD:
|
||||||
|
return "NF_INET_FORWARD";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NF_INET_LOCAL_OUT:
|
||||||
|
return "NF_INET_LOCAL_OUT";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NF_INET_POST_ROUTING:
|
||||||
|
return "NF_INET_POST_ROUTING";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "NF_INET_UNKNOWN";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
_gtpuah_print_hex_octets(unsigned char* data_pP, unsigned short sizeP) {
|
_gtpuah_print_hex_octets(unsigned char* data_pP, unsigned short sizeP)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
unsigned long octet_index = 0;
|
unsigned long octet_index = 0;
|
||||||
unsigned long buffer_marker = 0;
|
unsigned long buffer_marker = 0;
|
||||||
@@ -142,8 +160,9 @@ _gtpuah_print_hex_octets(unsigned char* data_pP, unsigned short sizeP) {
|
|||||||
if (data_pP == NULL) {
|
if (data_pP == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sizeP > 2000) {
|
if (sizeP > 2000) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_gettimeofday(&tv);
|
do_gettimeofday(&tv);
|
||||||
@@ -155,15 +174,20 @@ _gtpuah_print_hex_octets(unsigned char* data_pP, unsigned short sizeP) {
|
|||||||
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday);
|
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday);
|
||||||
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker,"%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday);
|
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker,"%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday);
|
||||||
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday);
|
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday);
|
||||||
pr_info("%s",_gtpuah_print_buffer);buffer_marker = 0;
|
pr_info("%s",_gtpuah_print_buffer);
|
||||||
|
buffer_marker = 0;
|
||||||
|
|
||||||
for (octet_index = 0; octet_index < sizeP; octet_index++) {
|
for (octet_index = 0; octet_index < sizeP; octet_index++) {
|
||||||
if ((octet_index % 16) == 0){
|
if ((octet_index % 16) == 0) {
|
||||||
if (octet_index != 0) {
|
if (octet_index != 0) {
|
||||||
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
||||||
pr_info("%s",_gtpuah_print_buffer);buffer_marker = 0;
|
pr_info("%s",_gtpuah_print_buffer);
|
||||||
|
buffer_marker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker, "%s %04ld |",timeofday, octet_index);
|
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker, "%s %04ld |",timeofday, octet_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print every single octet in hexadecimal form
|
* Print every single octet in hexadecimal form
|
||||||
*/
|
*/
|
||||||
@@ -178,7 +202,8 @@ _gtpuah_print_hex_octets(unsigned char* data_pP, unsigned short sizeP) {
|
|||||||
*/
|
*/
|
||||||
for (aindex = octet_index; aindex < 16; ++aindex)
|
for (aindex = octet_index; aindex < 16; ++aindex)
|
||||||
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker, " ");
|
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker, " ");
|
||||||
//SGI_IF_DEBUG(" ");
|
|
||||||
|
//SGI_IF_DEBUG(" ");
|
||||||
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
buffer_marker+=snprintf(&_gtpuah_print_buffer[buffer_marker], GTPUAH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
||||||
pr_info("%s",_gtpuah_print_buffer);
|
pr_info("%s",_gtpuah_print_buffer);
|
||||||
}
|
}
|
||||||
@@ -186,275 +211,302 @@ _gtpuah_print_hex_octets(unsigned char* data_pP, unsigned short sizeP) {
|
|||||||
#ifdef WITH_IPV6
|
#ifdef WITH_IPV6
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void
|
static void
|
||||||
_gtpuah_tg6_add(struct sk_buff *old_skb_pP, const struct xt_action_param *par_pP) {
|
_gtpuah_tg6_add(struct sk_buff *old_skb_pP, const struct xt_action_param *par_pP)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void
|
static void
|
||||||
_gtpuah_tg4_add(struct sk_buff *old_skb_pP, const struct xt_action_param *par_pP) {
|
_gtpuah_tg4_add(struct sk_buff *old_skb_pP, const struct xt_action_param *par_pP)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
struct rtable *rt = NULL;
|
//-----------------------------------------------------------------------------
|
||||||
struct ethhdr *ethhdr_p = NULL;
|
struct rtable *rt = NULL;
|
||||||
struct iphdr *old_iph_p = ip_hdr(old_skb_pP);
|
struct ethhdr *ethhdr_p = NULL;
|
||||||
struct iphdr *new_iph_p = NULL;
|
struct iphdr *old_iph_p = ip_hdr(old_skb_pP);
|
||||||
struct iphdr *tmp_iph_p = NULL;
|
struct iphdr *new_iph_p = NULL;
|
||||||
struct udphdr *udph_p = NULL;
|
struct iphdr *tmp_iph_p = NULL;
|
||||||
struct gtpuhdr *gtpuh_p = NULL;
|
struct udphdr *udph_p = NULL;
|
||||||
struct sk_buff *new_skb_p = NULL;
|
struct gtpuhdr *gtpuh_p = NULL;
|
||||||
const uint16_t headroom_reqd = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct gtpuhdr);
|
struct sk_buff *new_skb_p = NULL;
|
||||||
uint16_t orig_iplen = 0, udp_len = 0, ip_len = 0;
|
const uint16_t headroom_reqd = ETH_HLEN + sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct gtpuhdr);
|
||||||
int flags = 0, offset = 0;
|
uint16_t orig_iplen = 0, udp_len = 0, ip_len = 0;
|
||||||
unsigned int addr_type = RTN_UNSPEC;
|
int flags = 0, offset = 0;
|
||||||
|
unsigned int addr_type = RTN_UNSPEC;
|
||||||
|
|
||||||
|
|
||||||
if (ip_is_fragment(ip_hdr(old_skb_pP))) {
|
if (ip_is_fragment(ip_hdr(old_skb_pP))) {
|
||||||
pr_info("GTPUAH: IP fragment, dropped\n");
|
pr_info("GTPUAH: IP fragment, dropped\n");
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skb_linearize(old_skb_pP) < 0) {
|
||||||
|
pr_info("GTPUAH: skb no linearize\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (old_skb_pP->mark == 0) {
|
||||||
|
pr_info("GTPUAH: _gtpuah_target_add force info_pP mark %u to skb_pP mark %u\n",
|
||||||
|
old_skb_pP->mark,
|
||||||
|
((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->rtun);
|
||||||
|
old_skb_pP->mark = ((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->rtun;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Keep the length of the source IP packet */
|
||||||
|
orig_iplen = ntohs(old_iph_p->tot_len);
|
||||||
|
offset = ntohs(old_iph_p->frag_off);
|
||||||
|
flags = offset & ~IP_OFFSET;
|
||||||
|
|
||||||
|
|
||||||
|
/* Create a new copy of the original skb...can't avoid :-( */
|
||||||
|
if ((orig_iplen + headroom_reqd) <= mtu) {
|
||||||
|
|
||||||
|
new_skb_p = alloc_skb(headroom_reqd + orig_iplen, GFP_ATOMIC);
|
||||||
|
|
||||||
|
if (new_skb_p == NULL) {
|
||||||
|
pr_info("GTPUAH: alloc_skb returned NULL\n");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (skb_linearize(old_skb_pP) < 0) {
|
|
||||||
pr_info("GTPUAH: skb no linearize\n");
|
if (skb_linearize(new_skb_p) < 0) {
|
||||||
return;
|
pr_info("GTPUAH: skb no linearize\n");
|
||||||
|
goto free_new_skb;
|
||||||
}
|
}
|
||||||
if (old_skb_pP->mark == 0) {
|
|
||||||
pr_info("GTPUAH: _gtpuah_target_add force info_pP mark %u to skb_pP mark %u\n",
|
|
||||||
old_skb_pP->mark,
|
|
||||||
((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->rtun);
|
|
||||||
old_skb_pP->mark = ((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->rtun;
|
|
||||||
}
|
|
||||||
/* Keep the length of the source IP packet */
|
|
||||||
orig_iplen = ntohs(old_iph_p->tot_len);
|
|
||||||
offset = ntohs(old_iph_p->frag_off);
|
|
||||||
flags = offset & ~IP_OFFSET;
|
|
||||||
|
|
||||||
|
skb_reserve(new_skb_p, headroom_reqd + orig_iplen);
|
||||||
|
tmp_iph_p = (void *)skb_push(new_skb_p, orig_iplen);
|
||||||
|
memcpy(tmp_iph_p, old_iph_p, orig_iplen);
|
||||||
|
|
||||||
/* Create a new copy of the original skb...can't avoid :-( */
|
/* Add GTPu header */
|
||||||
if ((orig_iplen + headroom_reqd) <= mtu) {
|
gtpuh_p = (struct gtpuhdr*)skb_push(new_skb_p, sizeof(struct gtpuhdr));
|
||||||
|
gtpuh_p->flags = 0x30; /* v1 and Protocol-type=GTP */
|
||||||
|
gtpuh_p->msgtype = 0xff; /* T-PDU */
|
||||||
|
gtpuh_p->length = htons(orig_iplen);
|
||||||
|
gtpuh_p->tunid = htonl(old_skb_pP->mark);
|
||||||
|
|
||||||
new_skb_p = alloc_skb(headroom_reqd + orig_iplen, GFP_ATOMIC);
|
/* Add UDP header */
|
||||||
if (new_skb_p == NULL) {
|
udp_len = sizeof(struct udphdr) + sizeof(struct gtpuhdr) + orig_iplen;
|
||||||
pr_info("GTPUAH: alloc_skb returned NULL\n");
|
udph_p = (struct udphdr*)skb_push(new_skb_p, sizeof(struct udphdr));
|
||||||
return;
|
udph_p->source = htons(gtpu_port);
|
||||||
}
|
udph_p->dest = htons(gtpu_port);
|
||||||
if (skb_linearize(new_skb_p) < 0) {
|
udph_p->len = htons(udp_len);
|
||||||
pr_info("GTPUAH: skb no linearize\n");
|
udph_p->check = 0;
|
||||||
goto free_new_skb;
|
udph_p->check = csum_tcpudp_magic(((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->laddr,
|
||||||
}
|
((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->raddr,
|
||||||
skb_reserve(new_skb_p, headroom_reqd + orig_iplen);
|
udp_len,
|
||||||
tmp_iph_p = (void *)skb_push(new_skb_p, orig_iplen);
|
IPPROTO_UDP,
|
||||||
memcpy(tmp_iph_p, old_iph_p, orig_iplen);
|
csum_partial((char*)udph_p, udp_len, 0));
|
||||||
|
skb_set_transport_header(new_skb_p, 0);
|
||||||
|
|
||||||
/* Add GTPu header */
|
/* Add IP header */
|
||||||
gtpuh_p = (struct gtpuhdr*)skb_push(new_skb_p, sizeof(struct gtpuhdr));
|
ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct gtpuhdr) + orig_iplen;
|
||||||
gtpuh_p->flags = 0x30; /* v1 and Protocol-type=GTP */
|
new_iph_p = (struct iphdr*)skb_push(new_skb_p, sizeof(struct iphdr));
|
||||||
gtpuh_p->msgtype = 0xff; /* T-PDU */
|
new_iph_p->ihl = 5;
|
||||||
gtpuh_p->length = htons(orig_iplen);
|
new_iph_p->version = 4;
|
||||||
gtpuh_p->tunid = htonl(old_skb_pP->mark);
|
new_iph_p->tos = 0;
|
||||||
|
new_iph_p->tot_len = htons(ip_len);
|
||||||
|
new_iph_p->id = (uint16_t)(((uint64_t)new_skb_p) >> 8);
|
||||||
|
new_iph_p->frag_off = 0;
|
||||||
|
new_iph_p->ttl = 64;
|
||||||
|
new_iph_p->protocol = IPPROTO_UDP;
|
||||||
|
new_iph_p->saddr = ((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->laddr;
|
||||||
|
// !!!!!!!! LG TEST !!!!!!!!!!
|
||||||
|
//new_iph_p->saddr = old_iph_p->saddr;
|
||||||
|
new_iph_p->daddr = ((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->raddr;
|
||||||
|
new_iph_p->check = 0;
|
||||||
|
new_iph_p->check = ip_fast_csum((unsigned char *)new_iph_p, new_iph_p->ihl);
|
||||||
|
skb_set_network_header(new_skb_p, 0);
|
||||||
|
|
||||||
/* Add UDP header */
|
skb_set_inner_network_header(new_skb_p, -ETH_HLEN);
|
||||||
udp_len = sizeof(struct udphdr) + sizeof(struct gtpuhdr) + orig_iplen;
|
skb_set_inner_transport_header(new_skb_p, -ETH_HLEN);
|
||||||
udph_p = (struct udphdr*)skb_push(new_skb_p, sizeof(struct udphdr));
|
|
||||||
udph_p->source = htons(gtpu_port);
|
|
||||||
udph_p->dest = htons(gtpu_port);
|
|
||||||
udph_p->len = htons(udp_len);
|
|
||||||
udph_p->check = 0;
|
|
||||||
udph_p->check = csum_tcpudp_magic(((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->laddr,
|
|
||||||
((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->raddr,
|
|
||||||
udp_len,
|
|
||||||
IPPROTO_UDP,
|
|
||||||
csum_partial((char*)udph_p, udp_len, 0));
|
|
||||||
skb_set_transport_header(new_skb_p, 0);
|
|
||||||
|
|
||||||
/* Add IP header */
|
|
||||||
ip_len = sizeof(struct iphdr) + sizeof(struct udphdr) + sizeof(struct gtpuhdr) + orig_iplen;
|
|
||||||
new_iph_p = (struct iphdr*)skb_push(new_skb_p, sizeof(struct iphdr));
|
|
||||||
new_iph_p->ihl = 5;
|
|
||||||
new_iph_p->version = 4;
|
|
||||||
new_iph_p->tos = 0;
|
|
||||||
new_iph_p->tot_len = htons(ip_len);
|
|
||||||
new_iph_p->id = (uint16_t)(((uint64_t)new_skb_p) >> 8);
|
|
||||||
new_iph_p->frag_off = 0;
|
|
||||||
new_iph_p->ttl = 64;
|
|
||||||
new_iph_p->protocol = IPPROTO_UDP;
|
|
||||||
new_iph_p->saddr = ((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->laddr;
|
|
||||||
// !!!!!!!! LG TEST !!!!!!!!!!
|
|
||||||
//new_iph_p->saddr = old_iph_p->saddr;
|
|
||||||
new_iph_p->daddr = ((const struct xt_gtpuah_target_info *)(par_pP->targinfo))->raddr;
|
|
||||||
new_iph_p->check = 0;
|
|
||||||
new_iph_p->check = ip_fast_csum((unsigned char *)new_iph_p, new_iph_p->ihl);
|
|
||||||
skb_set_network_header(new_skb_p, 0);
|
|
||||||
|
|
||||||
skb_set_inner_network_header(new_skb_p, -ETH_HLEN);
|
|
||||||
skb_set_inner_transport_header(new_skb_p, -ETH_HLEN);
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// CHECKSUM_NONE, CHECKSUM_UNNECESSARY, CHECKSUM_COMPLETE, CHECKSUM_PARTIAL
|
// CHECKSUM_NONE, CHECKSUM_UNNECESSARY, CHECKSUM_COMPLETE, CHECKSUM_PARTIAL
|
||||||
new_skb_p->ip_summed = CHECKSUM_NONE;
|
new_skb_p->ip_summed = CHECKSUM_NONE;
|
||||||
new_skb_p->mark = old_skb_pP->mark;
|
new_skb_p->mark = old_skb_pP->mark;
|
||||||
|
|
||||||
switch (par_pP->hooknum) {
|
switch (par_pP->hooknum) {
|
||||||
case NF_INET_POST_ROUTING: {
|
case NF_INET_POST_ROUTING: {
|
||||||
new_skb_p->pkt_type = PACKET_OTHERHOST; // PACKET_OUTGOING
|
new_skb_p->pkt_type = PACKET_OTHERHOST; // PACKET_OUTGOING
|
||||||
#ifdef CONFIG_BRIDGE_NETFILTER
|
#ifdef CONFIG_BRIDGE_NETFILTER
|
||||||
if (new_skb_p->nf_bridge != NULL && new_skb_p->nf_bridge->mask & BRNF_BRIDGED) {
|
|
||||||
addr_type = RTN_LOCAL;
|
if (new_skb_p->nf_bridge != NULL && new_skb_p->nf_bridge->mask & BRNF_BRIDGED) {
|
||||||
new_skb_p->pkt_type =PACKET_HOST;
|
addr_type = RTN_LOCAL;
|
||||||
}
|
new_skb_p->pkt_type =PACKET_HOST;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
if (tunnel_local == 0) {
|
|
||||||
struct flowi fl = {
|
|
||||||
.u = {
|
|
||||||
.ip4 = {
|
|
||||||
.daddr = new_iph_p->daddr,
|
|
||||||
.flowi4_tos = RT_TOS(new_iph_p->tos),
|
|
||||||
.flowi4_scope = RT_SCOPE_UNIVERSE,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
if (tunnel_local == 0) {
|
||||||
rt = ip_route_output_key(&init_net, &fl.u.ip4);
|
struct flowi fl = {
|
||||||
if (rt == NULL) {
|
.u = {
|
||||||
pr_info("GTPURH: Failed to route packet to dst 0x%x.\n", fl.u.ip4.daddr);
|
.ip4 = {
|
||||||
goto free_new_skb;
|
.daddr = new_iph_p->daddr,
|
||||||
}
|
.flowi4_tos = RT_TOS(new_iph_p->tos),
|
||||||
new_skb_p->priority = rt_tos2priority(new_iph_p->tos);
|
.flowi4_scope = RT_SCOPE_UNIVERSE,
|
||||||
skb_dst_drop(new_skb_p);
|
|
||||||
if (rt->dst.dev) {
|
|
||||||
pr_info("GTPUAH: dst dev name %s\n", rt->dst.dev->name);
|
|
||||||
skb_dst_set(new_skb_p, dst_clone(&rt->dst));
|
|
||||||
new_skb_p->dev = skb_dst(new_skb_p)->dev;
|
|
||||||
if (new_skb_p->len > dst_mtu(skb_dst(new_skb_p))) {
|
|
||||||
goto free_new_skb;
|
|
||||||
}
|
|
||||||
nf_ct_attach(new_skb_p, old_skb_pP);
|
|
||||||
|
|
||||||
pr_info("GTPUAH: PACKET -> NF_HOOK NF_INET_POST_ROUTING/%s mark %u encap src: %u.%u.%u.%u dst: %u.%u.%u.%u in src: %u.%u.%u.%u dst: %u.%u.%u.%u\n",
|
|
||||||
gtpuah_tg_reg[0].table,
|
|
||||||
new_skb_p->mark,
|
|
||||||
NIPADDR(old_iph_p->saddr),
|
|
||||||
NIPADDR(old_iph_p->daddr),
|
|
||||||
NIPADDR(new_iph_p->saddr),
|
|
||||||
NIPADDR(new_iph_p->daddr));
|
|
||||||
|
|
||||||
_gtpuah_print_hex_octets(
|
|
||||||
ip_hdr(new_skb_p),
|
|
||||||
headroom_reqd);
|
|
||||||
|
|
||||||
ip_local_out(new_skb_p);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
pr_info("GTPURH: rt->dst.dev == NULL\n");
|
|
||||||
goto free_new_skb;
|
|
||||||
}
|
|
||||||
} else { // (tunnel_local)
|
|
||||||
|
|
||||||
new_skb_p->pkt_type = PACKET_HOST;
|
|
||||||
new_skb_p->priority = rt_tos2priority(new_iph_p->tos);
|
|
||||||
new_skb_p->protocol = htons(ETH_P_IP);
|
|
||||||
|
|
||||||
// fake mac header
|
|
||||||
ethhdr_p = (struct ethhdr*)skb_push(new_skb_p, ETH_HLEN);
|
|
||||||
skb_set_mac_header(new_skb_p, 0);
|
|
||||||
memset(ethhdr_p, 0, ETH_HLEN);
|
|
||||||
ethhdr_p->h_proto = ntohs(ETH_P_IP);
|
|
||||||
|
|
||||||
//_gtpuah_print_hex_octets(new_iph_p, ip_len);
|
|
||||||
//ip_local_deliver_fn_ptr(new_skb_p);
|
|
||||||
|
|
||||||
new_skb_p->ip_summed = CHECKSUM_NONE;
|
|
||||||
skb_dst_drop(new_skb_p);
|
|
||||||
nf_reset(new_skb_p);
|
|
||||||
/*pr_info("GTPUAH(tun): PACKET -> NF_HOOK NF_INET_POST_ROUTING/%s encapsulated src: %u.%u.%u.%u dst: %u.%u.%u.%u\n",
|
|
||||||
gtpuah_tg_reg[0].table,
|
|
||||||
NIPADDR(old_iph_p->saddr),
|
|
||||||
NIPADDR(old_iph_p->daddr));*/
|
|
||||||
if ( dev_forward_skb(old_skb_pP->dev, new_skb_p) != NET_RX_SUCCESS) {
|
|
||||||
pr_info("GTPUAH(tun): dev_forward_skb failed!!!\n");
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
|
};
|
||||||
|
|
||||||
default:
|
|
||||||
pr_info("GTPUAH: NF_HOOK %u not processed\n", par_pP->hooknum);
|
rt = ip_route_output_key(&init_net, &fl.u.ip4);
|
||||||
goto free_new_skb;
|
|
||||||
|
if (rt == NULL) {
|
||||||
|
pr_info("GTPURH: Failed to route packet to dst 0x%x.\n", fl.u.ip4.daddr);
|
||||||
|
goto free_new_skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
new_skb_p->priority = rt_tos2priority(new_iph_p->tos);
|
||||||
|
skb_dst_drop(new_skb_p);
|
||||||
|
|
||||||
|
if (rt->dst.dev) {
|
||||||
|
pr_info("GTPUAH: dst dev name %s\n", rt->dst.dev->name);
|
||||||
|
skb_dst_set(new_skb_p, dst_clone(&rt->dst));
|
||||||
|
new_skb_p->dev = skb_dst(new_skb_p)->dev;
|
||||||
|
|
||||||
|
if (new_skb_p->len > dst_mtu(skb_dst(new_skb_p))) {
|
||||||
|
goto free_new_skb;
|
||||||
|
}
|
||||||
|
|
||||||
|
nf_ct_attach(new_skb_p, old_skb_pP);
|
||||||
|
|
||||||
|
pr_info("GTPUAH: PACKET -> NF_HOOK NF_INET_POST_ROUTING/%s mark %u encap src: %u.%u.%u.%u dst: %u.%u.%u.%u in src: %u.%u.%u.%u dst: %u.%u.%u.%u\n",
|
||||||
|
gtpuah_tg_reg[0].table,
|
||||||
|
new_skb_p->mark,
|
||||||
|
NIPADDR(old_iph_p->saddr),
|
||||||
|
NIPADDR(old_iph_p->daddr),
|
||||||
|
NIPADDR(new_iph_p->saddr),
|
||||||
|
NIPADDR(new_iph_p->daddr));
|
||||||
|
|
||||||
|
_gtpuah_print_hex_octets(
|
||||||
|
ip_hdr(new_skb_p),
|
||||||
|
headroom_reqd);
|
||||||
|
|
||||||
|
ip_local_out(new_skb_p);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
pr_info("GTPURH: rt->dst.dev == NULL\n");
|
||||||
|
goto free_new_skb;
|
||||||
|
}
|
||||||
|
} else { // (tunnel_local)
|
||||||
|
|
||||||
|
new_skb_p->pkt_type = PACKET_HOST;
|
||||||
|
new_skb_p->priority = rt_tos2priority(new_iph_p->tos);
|
||||||
|
new_skb_p->protocol = htons(ETH_P_IP);
|
||||||
|
|
||||||
|
// fake mac header
|
||||||
|
ethhdr_p = (struct ethhdr*)skb_push(new_skb_p, ETH_HLEN);
|
||||||
|
skb_set_mac_header(new_skb_p, 0);
|
||||||
|
memset(ethhdr_p, 0, ETH_HLEN);
|
||||||
|
ethhdr_p->h_proto = ntohs(ETH_P_IP);
|
||||||
|
|
||||||
|
//_gtpuah_print_hex_octets(new_iph_p, ip_len);
|
||||||
|
//ip_local_deliver_fn_ptr(new_skb_p);
|
||||||
|
|
||||||
|
new_skb_p->ip_summed = CHECKSUM_NONE;
|
||||||
|
skb_dst_drop(new_skb_p);
|
||||||
|
nf_reset(new_skb_p);
|
||||||
|
|
||||||
|
/*pr_info("GTPUAH(tun): PACKET -> NF_HOOK NF_INET_POST_ROUTING/%s encapsulated src: %u.%u.%u.%u dst: %u.%u.%u.%u\n",
|
||||||
|
gtpuah_tg_reg[0].table,
|
||||||
|
NIPADDR(old_iph_p->saddr),
|
||||||
|
NIPADDR(old_iph_p->daddr));*/
|
||||||
|
if ( dev_forward_skb(old_skb_pP->dev, new_skb_p) != NET_RX_SUCCESS) {
|
||||||
|
pr_info("GTPUAH(tun): dev_forward_skb failed!!!\n");
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
pr_info("GTPUAH: PACKET DROPPED because of mtu %u < (%u + %u)\n",
|
|
||||||
mtu, orig_iplen, headroom_reqd);
|
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
pr_info("GTPUAH: NF_HOOK %u not processed\n", par_pP->hooknum);
|
||||||
|
goto free_new_skb;
|
||||||
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
pr_info("GTPUAH: PACKET DROPPED because of mtu %u < (%u + %u)\n",
|
||||||
|
mtu, orig_iplen, headroom_reqd);
|
||||||
|
}
|
||||||
|
|
||||||
free_new_skb:
|
free_new_skb:
|
||||||
pr_info("GTPUAH: PACKET DROPPED\n");
|
pr_info("GTPUAH: PACKET DROPPED\n");
|
||||||
kfree_skb(new_skb_p);
|
kfree_skb(new_skb_p);
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WITH_IPV6
|
#ifdef WITH_IPV6
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static unsigned int
|
static unsigned int
|
||||||
gtpuah_tg6(struct sk_buff *skb_pP, const struct xt_action_param *par_pP) {
|
gtpuah_tg6(struct sk_buff *skb_pP, const struct xt_action_param *par_pP)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
const struct xt_gtpuah_target_info *tgi_p = par_pP->targinfo;
|
const struct xt_gtpuah_target_info *tgi_p = par_pP->targinfo;
|
||||||
|
|
||||||
if (tgi_p == NULL) {
|
if (tgi_p == NULL) {
|
||||||
return NF_ACCEPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tgi_p->action == PARAM_GTPUAH_ACTION_ADD) {
|
|
||||||
_gtpuah_tg6_add(skb_pP, par_pP);
|
|
||||||
return NF_DROP; // TODO
|
|
||||||
}
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgi_p->action == PARAM_GTPUAH_ACTION_ADD) {
|
||||||
|
_gtpuah_tg6_add(skb_pP, par_pP);
|
||||||
|
return NF_DROP; // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
return NF_ACCEPT;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static unsigned int
|
static unsigned int
|
||||||
gtpuah_tg4(struct sk_buff *skb_pP, const struct xt_action_param *par_pP) {
|
gtpuah_tg4(struct sk_buff *skb_pP, const struct xt_action_param *par_pP)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
const struct iphdr *iph_p = ip_hdr(skb_pP);
|
//-----------------------------------------------------------------------------
|
||||||
const struct xt_gtpuah_target_info *tgi_p = par_pP->targinfo;
|
const struct iphdr *iph_p = ip_hdr(skb_pP);
|
||||||
if (tgi_p == NULL) {
|
const struct xt_gtpuah_target_info *tgi_p = par_pP->targinfo;
|
||||||
return NF_ACCEPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tgi_p->action == PARAM_GTPUAH_ACTION_ADD) {
|
if (tgi_p == NULL) {
|
||||||
_gtpuah_tg4_add(skb_pP, par_pP);
|
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgi_p->action == PARAM_GTPUAH_ACTION_ADD) {
|
||||||
|
_gtpuah_tg4_add(skb_pP, par_pP);
|
||||||
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NF_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static int
|
static int
|
||||||
__init gtpuah_tg_init(void) {
|
__init gtpuah_tg_init(void)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
pr_info("GTPUAH: Initializing module (KVersion: %d)\n", KVERSION);
|
//-----------------------------------------------------------------------------
|
||||||
pr_info("GTPUAH: Copyright Polaris Networks 2010-2011\n");
|
pr_info("GTPUAH: Initializing module (KVersion: %d)\n", KVERSION);
|
||||||
pr_info("GTPUAH: Modified by EURECOM Lionel GAUTHIER 2014\n");
|
pr_info("GTPUAH: Copyright Polaris Networks 2010-2011\n");
|
||||||
#ifndef CMAKER
|
pr_info("GTPUAH: Modified by EURECOM Lionel GAUTHIER 2014\n");
|
||||||
pr_info("GTPUAH: Compiled %s at time %s\n",__DATE__,__TIME__);
|
#ifndef CMAKER
|
||||||
#endif
|
pr_info("GTPUAH: Compiled %s at time %s\n",__DATE__,__TIME__);
|
||||||
#if defined(WITH_IPV6)
|
|
||||||
pr_info("GTPURH: IPv4/IPv6 enabled\n");
|
|
||||||
#else
|
|
||||||
pr_info("GTPURH: IPv4 only enabled\n");
|
|
||||||
#endif
|
#endif
|
||||||
return xt_register_targets(gtpuah_tg_reg, ARRAY_SIZE(gtpuah_tg_reg));
|
#if defined(WITH_IPV6)
|
||||||
|
pr_info("GTPURH: IPv4/IPv6 enabled\n");
|
||||||
|
#else
|
||||||
|
pr_info("GTPURH: IPv4 only enabled\n");
|
||||||
|
#endif
|
||||||
|
return xt_register_targets(gtpuah_tg_reg, ARRAY_SIZE(gtpuah_tg_reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void
|
static void
|
||||||
__exit gtpuah_tg_exit(void) {
|
__exit gtpuah_tg_exit(void)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
xt_unregister_targets(gtpuah_tg_reg, ARRAY_SIZE(gtpuah_tg_reg));
|
//-----------------------------------------------------------------------------
|
||||||
pr_info("GTPUAH: Unloading module\n");
|
xt_unregister_targets(gtpuah_tg_reg, ARRAY_SIZE(gtpuah_tg_reg));
|
||||||
|
pr_info("GTPUAH: Unloading module\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,17 +9,15 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum xt_gtpuah_mode_
|
enum xt_gtpuah_mode_ {
|
||||||
{
|
PARAM_GTPUAH_ACTION_ADD = 1 << 8,
|
||||||
PARAM_GTPUAH_ACTION_ADD = 1 << 8,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xt_gtpuah_target_info
|
struct xt_gtpuah_target_info {
|
||||||
{
|
u_int32_t laddr __attribute__((aligned(8)));
|
||||||
u_int32_t laddr __attribute__((aligned(8)));
|
u_int32_t raddr __attribute__((aligned(8)));
|
||||||
u_int32_t raddr __attribute__((aligned(8)));
|
u_int32_t ltun __attribute__((aligned(8)));
|
||||||
u_int32_t ltun __attribute__((aligned(8)));
|
u_int32_t rtun __attribute__((aligned(8)));
|
||||||
u_int32_t rtun __attribute__((aligned(8)));
|
u_int32_t action __attribute__((aligned(8)));
|
||||||
u_int32_t action __attribute__((aligned(8)));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
#define XT_GTPURH_VERSION IPTABLES_VERSION_STRING
|
#define XT_GTPURH_VERSION IPTABLES_VERSION_STRING
|
||||||
#define gtpurh_strtoui(s,v,m,M) !string_to_number(s,m,M,v)
|
#define gtpurh_strtoui(s,v,m,M) !string_to_number(s,m,M,v)
|
||||||
#define gtpurh_exit_error exit_error
|
#define gtpurh_exit_error exit_error
|
||||||
#elif (IPTVERSION > 135) && (IPTVERSION <= 141)
|
#elif (IPTVERSION > 135) && (IPTVERSION <= 141)
|
||||||
#define GTPURH_PARAM_BAD_VALUE P_BAD_VALUE
|
#define GTPURH_PARAM_BAD_VALUE P_BAD_VALUE
|
||||||
#define GTPURH_PARAM_ONLY_ONCE P_ONLY_ONCE
|
#define GTPURH_PARAM_ONLY_ONCE P_ONLY_ONCE
|
||||||
#define XT_GTPURH_VERSION XTABLES_VERSION
|
#define XT_GTPURH_VERSION XTABLES_VERSION
|
||||||
@@ -50,238 +50,247 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
PARAM_LADDR = 1 << 0,
|
PARAM_LADDR = 1 << 0,
|
||||||
PARAM_LTUN = 1 << 1,
|
PARAM_LTUN = 1 << 1,
|
||||||
PARAM_RADDR = 1 << 2,
|
PARAM_RADDR = 1 << 2,
|
||||||
PARAM_RTUN = 1 << 3,
|
PARAM_RTUN = 1 << 3,
|
||||||
PARAM_ACTION = 1 << 4,
|
PARAM_ACTION = 1 << 4,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void GTPURH_help(void)
|
static void GTPURH_help(void)
|
||||||
{
|
{
|
||||||
printf(
|
printf(
|
||||||
"GTPUAH target options\n"
|
"GTPUAH target options\n"
|
||||||
" --action value Set action <value: remove>\n"
|
" --action value Set action <value: remove>\n"
|
||||||
" --own-ip value Set own IP address\n"
|
" --own-ip value Set own IP address\n"
|
||||||
" --own-tun value Set own tunnel id <value: 1-2^31>\n"
|
" --own-tun value Set own tunnel id <value: 1-2^31>\n"
|
||||||
" --peer-ip value Set peer IP address\n"
|
" --peer-ip value Set peer IP address\n"
|
||||||
" --peer-tun value Set peer tunnel id <value: 1-2^31>\n");
|
" --peer-tun value Set peer tunnel id <value: 1-2^31>\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
/* Stolen from iptables v1.4.7 code */
|
/* Stolen from iptables v1.4.7 code */
|
||||||
void gtpurh_param_act(unsigned int status, const char *p1, ...)
|
void gtpurh_param_act(unsigned int status, const char *p1, ...)
|
||||||
{
|
{
|
||||||
const char *p2, *p3;
|
const char *p2, *p3;
|
||||||
va_list args;
|
va_list args;
|
||||||
int b;
|
int b;
|
||||||
|
|
||||||
va_start(args, p1);
|
va_start(args, p1);
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case GTPURH_PARAM_ONLY_ONCE:
|
case GTPURH_PARAM_ONLY_ONCE:
|
||||||
p2 = va_arg(args, const char *);
|
p2 = va_arg(args, const char *);
|
||||||
b = va_arg(args, unsigned int);
|
b = va_arg(args, unsigned int);
|
||||||
if (!b)
|
|
||||||
return;
|
|
||||||
exit_error(PARAMETER_PROBLEM,
|
|
||||||
"%s: \"%s\" option may only be specified once",
|
|
||||||
p1, p2);
|
|
||||||
break;
|
|
||||||
case GTPURH_PARAM_BAD_VALUE:
|
|
||||||
p2 = va_arg(args, const char *);
|
|
||||||
p3 = va_arg(args, const char *);
|
|
||||||
exit_error(PARAMETER_PROBLEM,
|
|
||||||
"%s: Bad value for \"%s\" option: \"%s\"",
|
|
||||||
p1, p2, p3);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
exit_error(status, "%s", "Unknown error");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
va_end(args);
|
if (!b)
|
||||||
|
return;
|
||||||
|
|
||||||
|
exit_error(PARAMETER_PROBLEM,
|
||||||
|
"%s: \"%s\" option may only be specified once",
|
||||||
|
p1, p2);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GTPURH_PARAM_BAD_VALUE:
|
||||||
|
p2 = va_arg(args, const char *);
|
||||||
|
p3 = va_arg(args, const char *);
|
||||||
|
exit_error(PARAMETER_PROBLEM,
|
||||||
|
"%s: Bad value for \"%s\" option: \"%s\"",
|
||||||
|
p1, p2, p3);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
exit_error(status, "%s", "Unknown error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
va_end(args);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static void parse_gtpurh_addr(const char *s, struct xt_gtpurh_target_info *info, int flag)
|
static void parse_gtpurh_addr(const char *s, struct xt_gtpurh_target_info *info, int flag)
|
||||||
{
|
{
|
||||||
in_addr_t addr;
|
in_addr_t addr;
|
||||||
|
|
||||||
if ((addr = inet_addr(s)) == -1) {
|
|
||||||
switch (flag) {
|
|
||||||
case PARAM_LADDR:
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--own-ip", s);
|
|
||||||
break;
|
|
||||||
case PARAM_RADDR:
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--peer-ip", s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if ((addr = inet_addr(s)) == -1) {
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case PARAM_LADDR:
|
case PARAM_LADDR:
|
||||||
info->laddr = addr;
|
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--own-ip", s);
|
||||||
break;
|
break;
|
||||||
case PARAM_RADDR:
|
|
||||||
info->raddr = addr;
|
case PARAM_RADDR:
|
||||||
break;
|
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--peer-ip", s);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case PARAM_LADDR:
|
||||||
|
info->laddr = addr;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_RADDR:
|
||||||
|
info->raddr = addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void parse_gtpurh_tunid(char *s, struct xt_gtpurh_target_info *info, int flag)
|
static void parse_gtpurh_tunid(char *s, struct xt_gtpurh_target_info *info, int flag)
|
||||||
{
|
{
|
||||||
unsigned int value;
|
unsigned int value;
|
||||||
|
|
||||||
if (!gtpurh_strtoui(s, &value, 0, UINT32_MAX)) {
|
|
||||||
switch (flag) {
|
|
||||||
case PARAM_LTUN:
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--own-tun", s);
|
|
||||||
break;
|
|
||||||
case PARAM_RTUN:
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--peer-tun", s);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!gtpurh_strtoui(s, &value, 0, UINT32_MAX)) {
|
||||||
switch (flag) {
|
switch (flag) {
|
||||||
case PARAM_LTUN:
|
case PARAM_LTUN:
|
||||||
info->ltun = value;
|
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--own-tun", s);
|
||||||
break;
|
break;
|
||||||
case PARAM_RTUN:
|
|
||||||
info->rtun = value;
|
case PARAM_RTUN:
|
||||||
break;
|
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--peer-tun", s);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (flag) {
|
||||||
|
case PARAM_LTUN:
|
||||||
|
info->ltun = value;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PARAM_RTUN:
|
||||||
|
info->rtun = value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void parse_gtpurh_action(char *s, struct xt_gtpurh_target_info *info, unsigned int *flags)
|
static void parse_gtpurh_action(char *s, struct xt_gtpurh_target_info *info, unsigned int *flags)
|
||||||
{
|
{
|
||||||
if (!strcmp(s, "remove")) {
|
if (!strcmp(s, "remove")) {
|
||||||
info->action = PARAM_GTPURH_ACTION_REM;
|
info->action = PARAM_GTPURH_ACTION_REM;
|
||||||
*flags |= PARAM_GTPURH_ACTION_REM;
|
*flags |= PARAM_GTPURH_ACTION_REM;
|
||||||
} else {
|
} else {
|
||||||
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--action", s);
|
gtpurh_param_act(GTPURH_PARAM_BAD_VALUE, "GTPURH", "--action", s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
static int
|
static int
|
||||||
GTPURH_parse(int c, char **argv, int invert, unsigned int *flags,
|
GTPURH_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
const struct ipt_entry *entry,
|
const struct ipt_entry *entry,
|
||||||
struct ipt_entry_target **target)
|
struct ipt_entry_target **target)
|
||||||
#else
|
#else
|
||||||
static int
|
static int
|
||||||
GTPURH_parse(int c, char **argv, int invert, unsigned int *flags,
|
GTPURH_parse(int c, char **argv, int invert, unsigned int *flags,
|
||||||
const void *entry, struct xt_entry_target **target)
|
const void *entry, struct xt_entry_target **target)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
struct xt_gtpurh_target_info *info = (struct xt_gtpurh_target_info *) (*target)->data;
|
struct xt_gtpurh_target_info *info = (struct xt_gtpurh_target_info *) (*target)->data;
|
||||||
|
|
||||||
switch (c)
|
|
||||||
{
|
|
||||||
case '1':
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--own-ip", *flags & PARAM_LADDR);
|
|
||||||
parse_gtpurh_addr(optarg, info, PARAM_LADDR);
|
|
||||||
*flags |= PARAM_LADDR;
|
|
||||||
return 1;
|
|
||||||
case '2':
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--own-tun", *flags & PARAM_LTUN);
|
|
||||||
parse_gtpurh_tunid(optarg, info, PARAM_LTUN);
|
|
||||||
*flags |= PARAM_LTUN;
|
|
||||||
return 1;
|
|
||||||
case '3':
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--peer-ip", *flags & PARAM_RADDR);
|
|
||||||
parse_gtpurh_addr(optarg, info, PARAM_RADDR);
|
|
||||||
*flags |= PARAM_RADDR;
|
|
||||||
return 1;
|
|
||||||
case '4':
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--peer-tun", *flags & PARAM_RTUN);
|
|
||||||
parse_gtpurh_tunid(optarg, info, PARAM_RTUN);
|
|
||||||
*flags |= PARAM_RTUN;
|
|
||||||
return 1;
|
|
||||||
case '5':
|
|
||||||
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--action", *flags & PARAM_ACTION);
|
|
||||||
parse_gtpurh_action(optarg, info, flags);
|
|
||||||
*flags |= PARAM_ACTION;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case '1':
|
||||||
|
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--own-ip", *flags & PARAM_LADDR);
|
||||||
|
parse_gtpurh_addr(optarg, info, PARAM_LADDR);
|
||||||
|
*flags |= PARAM_LADDR;
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
case '2':
|
||||||
|
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--own-tun", *flags & PARAM_LTUN);
|
||||||
|
parse_gtpurh_tunid(optarg, info, PARAM_LTUN);
|
||||||
|
*flags |= PARAM_LTUN;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case '3':
|
||||||
|
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--peer-ip", *flags & PARAM_RADDR);
|
||||||
|
parse_gtpurh_addr(optarg, info, PARAM_RADDR);
|
||||||
|
*flags |= PARAM_RADDR;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case '4':
|
||||||
|
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--peer-tun", *flags & PARAM_RTUN);
|
||||||
|
parse_gtpurh_tunid(optarg, info, PARAM_RTUN);
|
||||||
|
*flags |= PARAM_RTUN;
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case '5':
|
||||||
|
gtpurh_param_act(GTPURH_PARAM_ONLY_ONCE, "GTPURH", "--action", *flags & PARAM_ACTION);
|
||||||
|
parse_gtpurh_action(optarg, info, flags);
|
||||||
|
*flags |= PARAM_ACTION;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void GTPURH_check(unsigned int flags)
|
static void GTPURH_check(unsigned int flags)
|
||||||
{
|
{
|
||||||
if (!(flags & PARAM_ACTION))
|
if (!(flags & PARAM_ACTION)) {
|
||||||
{
|
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify action");
|
||||||
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify action");
|
}
|
||||||
}
|
|
||||||
if (!(flags & PARAM_LADDR))
|
if (!(flags & PARAM_LADDR)) {
|
||||||
{
|
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify local addr");
|
||||||
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify local addr");
|
}
|
||||||
}
|
|
||||||
if (!(flags & PARAM_LTUN))
|
if (!(flags & PARAM_LTUN)) {
|
||||||
{
|
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify local tunnel id");
|
||||||
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify local tunnel id");
|
}
|
||||||
}
|
|
||||||
if (!(flags & PARAM_RADDR))
|
if (!(flags & PARAM_RADDR)) {
|
||||||
{
|
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify remote addr");
|
||||||
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify remote addr");
|
}
|
||||||
}
|
|
||||||
if (!(flags & PARAM_RTUN))
|
if (!(flags & PARAM_RTUN)) {
|
||||||
{
|
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify remote tunnel id");
|
||||||
gtpurh_exit_error(PARAMETER_PROBLEM, "GTPURH: You must specify remote tunnel id");
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void convert_action_to_string(int action, char *actionstr)
|
static void convert_action_to_string(int action, char *actionstr)
|
||||||
{
|
{
|
||||||
switch(action)
|
switch(action) {
|
||||||
{
|
case PARAM_GTPURH_ACTION_REM:
|
||||||
case PARAM_GTPURH_ACTION_REM:
|
sprintf (actionstr, "remove");
|
||||||
sprintf (actionstr, "remove");
|
break;
|
||||||
break;
|
|
||||||
default :
|
default :
|
||||||
sprintf (actionstr, "unspecified!!!");
|
sprintf (actionstr, "unspecified!!!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
static void
|
static void
|
||||||
GTPURH_print(const struct ipt_ip *ip,
|
GTPURH_print(const struct ipt_ip *ip,
|
||||||
const struct ipt_entry_target *target,
|
const struct ipt_entry_target *target,
|
||||||
int numeric)
|
int numeric)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static void
|
static void
|
||||||
GTPURH_print(const void *ip,
|
GTPURH_print(const void *ip,
|
||||||
const struct xt_entry_target *target,
|
const struct xt_entry_target *target,
|
||||||
int numeric)
|
int numeric)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
const struct xt_gtpurh_target_info *info =
|
const struct xt_gtpurh_target_info *info =
|
||||||
(struct xt_gtpurh_target_info *) target->data;
|
(struct xt_gtpurh_target_info *) target->data;
|
||||||
|
|
||||||
char laddr[64], raddr[64], actionstr[32];
|
char laddr[64], raddr[64], actionstr[32];
|
||||||
|
|
||||||
convert_action_to_string(info->action, actionstr);
|
convert_action_to_string(info->action, actionstr);
|
||||||
|
|
||||||
if (info->action == PARAM_GTPURH_ACTION_REM)
|
if (info->action == PARAM_GTPURH_ACTION_REM) {
|
||||||
{
|
printf("GTPURH action: %s", actionstr);
|
||||||
printf("GTPURH action: %s", actionstr);
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct option GTPURH_opts[] = {
|
static struct option GTPURH_opts[] = {
|
||||||
{ "own-ip", 1, NULL, '1' },
|
{ "own-ip", 1, NULL, '1' },
|
||||||
{ "own-tun", 1, NULL, '2' },
|
{ "own-tun", 1, NULL, '2' },
|
||||||
{ "peer-ip", 1, NULL, '3' },
|
{ "peer-ip", 1, NULL, '3' },
|
||||||
{ "peer-tun", 1, NULL, '4' },
|
{ "peer-tun", 1, NULL, '4' },
|
||||||
{ "action", 1, NULL, '5' },
|
{ "action", 1, NULL, '5' },
|
||||||
{ .name = NULL }
|
{ .name = NULL }
|
||||||
};
|
};
|
||||||
|
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
@@ -289,26 +298,26 @@ static struct iptables_target gtpurh_tg_reg = {
|
|||||||
#else
|
#else
|
||||||
static struct xtables_target gtpurh_tg_reg = {
|
static struct xtables_target gtpurh_tg_reg = {
|
||||||
#endif
|
#endif
|
||||||
.name = "GTPURH",
|
.name = "GTPURH",
|
||||||
.version = XT_GTPURH_VERSION,
|
.version = XT_GTPURH_VERSION,
|
||||||
#if (IPTVERSION > 135)
|
#if (IPTVERSION > 135)
|
||||||
.family = NFPROTO_IPV4,
|
.family = NFPROTO_IPV4,
|
||||||
#endif
|
#endif
|
||||||
.size = XT_ALIGN(sizeof(struct xt_gtpurh_target_info)),
|
.size = XT_ALIGN(sizeof(struct xt_gtpurh_target_info)),
|
||||||
.userspacesize = XT_ALIGN(sizeof(struct xt_gtpurh_target_info)),
|
.userspacesize = XT_ALIGN(sizeof(struct xt_gtpurh_target_info)),
|
||||||
.help = GTPURH_help,
|
.help = GTPURH_help,
|
||||||
.parse = GTPURH_parse,
|
.parse = GTPURH_parse,
|
||||||
.final_check = GTPURH_check,
|
.final_check = GTPURH_check,
|
||||||
.print = GTPURH_print,
|
.print = GTPURH_print,
|
||||||
.extra_opts = GTPURH_opts,
|
.extra_opts = GTPURH_opts,
|
||||||
};
|
};
|
||||||
|
|
||||||
void _init(void)
|
void _init(void)
|
||||||
{
|
{
|
||||||
#if (IPTVERSION <= 135)
|
#if (IPTVERSION <= 135)
|
||||||
register_target(>purh_tg_reg);
|
register_target(>purh_tg_reg);
|
||||||
#else
|
#else
|
||||||
xtables_register_target(>purh_tg_reg);
|
xtables_register_target(>purh_tg_reg);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
#include <linux/skbuff.h>
|
#include <linux/skbuff.h>
|
||||||
#include <linux/ip.h>
|
#include <linux/ip.h>
|
||||||
#include <linux/if_ether.h>
|
#include <linux/if_ether.h>
|
||||||
#include <linux/route.h>
|
#include <linux/route.h>
|
||||||
#include <net/checksum.h>
|
#include <net/checksum.h>
|
||||||
#include <net/ip.h>
|
#include <net/ip.h>
|
||||||
#include <net/udp.h>
|
#include <net/udp.h>
|
||||||
#include <net/inet_sock.h>
|
#include <net/inet_sock.h>
|
||||||
#include <net/route.h>
|
#include <net/route.h>
|
||||||
#include <linux/netfilter/x_tables.h>
|
#include <linux/netfilter/x_tables.h>
|
||||||
#include <linux/netfilter_ipv4/ip_tables.h>
|
#include <linux/netfilter_ipv4/ip_tables.h>
|
||||||
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
#if defined(CONFIG_IP6_NF_IPTABLES) || defined(CONFIG_IP6_NF_IPTABLES_MODULE)
|
||||||
@@ -65,58 +65,75 @@ static unsigned int gtpurh_tg4(struct sk_buff *skb_pP, const struct xt_action_p
|
|||||||
static char _gtpurh_print_buffer[GTPURH_2_PRINT_BUFFER_LEN];
|
static char _gtpurh_print_buffer[GTPURH_2_PRINT_BUFFER_LEN];
|
||||||
|
|
||||||
static struct xt_target gtpurh_tg_reg[] __read_mostly = {
|
static struct xt_target gtpurh_tg_reg[] __read_mostly = {
|
||||||
{
|
{
|
||||||
.name = "GTPURH",
|
.name = "GTPURH",
|
||||||
.revision = 0,
|
.revision = 0,
|
||||||
.family = NFPROTO_IPV4,
|
.family = NFPROTO_IPV4,
|
||||||
.hooks = (1 << NF_INET_PRE_ROUTING) |
|
.hooks = (1 << NF_INET_PRE_ROUTING) |
|
||||||
(1 << NF_INET_LOCAL_OUT),
|
(1 << NF_INET_LOCAL_OUT),
|
||||||
.proto = IPPROTO_UDP,
|
.proto = IPPROTO_UDP,
|
||||||
.table = "raw",
|
.table = "raw",
|
||||||
.target = gtpurh_tg4,
|
.target = gtpurh_tg4,
|
||||||
.targetsize = sizeof(struct xt_gtpurh_target_info),
|
.targetsize = sizeof(struct xt_gtpurh_target_info),
|
||||||
.me = THIS_MODULE,
|
.me = THIS_MODULE,
|
||||||
},
|
},
|
||||||
#if defined(WITH_IPV6)
|
#if defined(WITH_IPV6)
|
||||||
{
|
{
|
||||||
.name = "GTPURH",
|
.name = "GTPURH",
|
||||||
.revision = 0,
|
.revision = 0,
|
||||||
.family = NFPROTO_IPV6,
|
.family = NFPROTO_IPV6,
|
||||||
.proto = IPPROTO_UDP,
|
.proto = IPPROTO_UDP,
|
||||||
.table = "raw",
|
.table = "raw",
|
||||||
.target = gtpurh_tg6,
|
.target = gtpurh_tg6,
|
||||||
.me = THIS_MODULE,
|
.me = THIS_MODULE,
|
||||||
},
|
},
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct gtpuhdr
|
struct gtpuhdr {
|
||||||
{
|
char flags;
|
||||||
char flags;
|
char msgtype;
|
||||||
char msgtype;
|
u_int16_t length;
|
||||||
u_int16_t length;
|
u_int32_t tunid;
|
||||||
u_int32_t tunid;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static char*
|
static char*
|
||||||
_gtpurh_nf_inet_hook_2_string(int nf_inet_hookP) {
|
_gtpurh_nf_inet_hook_2_string(int nf_inet_hookP)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
switch (nf_inet_hookP) {
|
//-----------------------------------------------------------------------------
|
||||||
case NF_INET_PRE_ROUTING: return "NF_INET_PRE_ROUTING";break;
|
switch (nf_inet_hookP) {
|
||||||
case NF_INET_LOCAL_IN: return "NF_INET_LOCAL_IN";break;
|
case NF_INET_PRE_ROUTING:
|
||||||
case NF_INET_FORWARD: return "NF_INET_FORWARD";break;
|
return "NF_INET_PRE_ROUTING";
|
||||||
case NF_INET_LOCAL_OUT: return "NF_INET_LOCAL_OUT";break;
|
break;
|
||||||
case NF_INET_POST_ROUTING: return "NF_INET_POST_ROUTING";break;
|
|
||||||
default: return "NF_INET_UNKNOWN";
|
case NF_INET_LOCAL_IN:
|
||||||
}
|
return "NF_INET_LOCAL_IN";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NF_INET_FORWARD:
|
||||||
|
return "NF_INET_FORWARD";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NF_INET_LOCAL_OUT:
|
||||||
|
return "NF_INET_LOCAL_OUT";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NF_INET_POST_ROUTING:
|
||||||
|
return "NF_INET_POST_ROUTING";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return "NF_INET_UNKNOWN";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static inline bool
|
static inline bool
|
||||||
_gtpurh_ip_is_fragment(const struct iphdr *iph_p) {
|
_gtpurh_ip_is_fragment(const struct iphdr *iph_p)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
return (iph_p->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
|
//-----------------------------------------------------------------------------
|
||||||
|
return (iph_p->frag_off & htons(IP_MF | IP_OFFSET)) != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -133,8 +150,9 @@ void _gtpurh_print_hex_octets(unsigned char* data_pP, unsigned short sizeP)
|
|||||||
if (data_pP == NULL) {
|
if (data_pP == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sizeP > 2000) {
|
if (sizeP > 2000) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
do_gettimeofday(&tv);
|
do_gettimeofday(&tv);
|
||||||
@@ -146,15 +164,20 @@ void _gtpurh_print_hex_octets(unsigned char* data_pP, unsigned short sizeP)
|
|||||||
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday);
|
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday);
|
||||||
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday);
|
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday);
|
||||||
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday);
|
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker,"%s------+-------------------------------------------------+\n",timeofday);
|
||||||
pr_info("%s",_gtpurh_print_buffer);buffer_marker = 0;
|
pr_info("%s",_gtpurh_print_buffer);
|
||||||
|
buffer_marker = 0;
|
||||||
|
|
||||||
for (octet_index = 0; octet_index < sizeP; octet_index++) {
|
for (octet_index = 0; octet_index < sizeP; octet_index++) {
|
||||||
if ((octet_index % 16) == 0){
|
if ((octet_index % 16) == 0) {
|
||||||
if (octet_index != 0) {
|
if (octet_index != 0) {
|
||||||
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
||||||
pr_info("%s",_gtpurh_print_buffer);buffer_marker = 0;
|
pr_info("%s",_gtpurh_print_buffer);
|
||||||
|
buffer_marker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, "%s %04ld |",timeofday, octet_index);
|
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, "%s %04ld |",timeofday, octet_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print every single octet in hexadecimal form
|
* Print every single octet in hexadecimal form
|
||||||
*/
|
*/
|
||||||
@@ -169,7 +192,8 @@ void _gtpurh_print_hex_octets(unsigned char* data_pP, unsigned short sizeP)
|
|||||||
*/
|
*/
|
||||||
for (aindex = octet_index; aindex < 16; ++aindex)
|
for (aindex = octet_index; aindex < 16; ++aindex)
|
||||||
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " ");
|
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " ");
|
||||||
//SGI_IF_DEBUG(" ");
|
|
||||||
|
//SGI_IF_DEBUG(" ");
|
||||||
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
buffer_marker+=snprintf(&_gtpurh_print_buffer[buffer_marker], GTPURH_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
||||||
pr_info("%s",_gtpurh_print_buffer);
|
pr_info("%s",_gtpurh_print_buffer);
|
||||||
}
|
}
|
||||||
@@ -180,284 +204,302 @@ void _gtpurh_print_hex_octets(unsigned char* data_pP, unsigned short sizeP)
|
|||||||
static bool _gtpurh_route_packet(struct sk_buff *skb_pP, const struct xt_gtpurh_target_info *info_pP)
|
static bool _gtpurh_route_packet(struct sk_buff *skb_pP, const struct xt_gtpurh_target_info *info_pP)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
int err = 0;
|
int err = 0;
|
||||||
struct rtable *rt = NULL;
|
struct rtable *rt = NULL;
|
||||||
struct iphdr *iph_p = ip_hdr(skb_pP);
|
struct iphdr *iph_p = ip_hdr(skb_pP);
|
||||||
int daddr = iph_p->daddr;
|
int daddr = iph_p->daddr;
|
||||||
struct flowi fl = {
|
struct flowi fl = {
|
||||||
.u = {
|
.u = {
|
||||||
.ip4 = {
|
.ip4 = {
|
||||||
.daddr = daddr,
|
.daddr = daddr,
|
||||||
.flowi4_tos = RT_TOS(iph_p->tos),
|
.flowi4_tos = RT_TOS(iph_p->tos),
|
||||||
.flowi4_scope = RT_SCOPE_UNIVERSE,
|
.flowi4_scope = RT_SCOPE_UNIVERSE,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
//skb_pP->pkt_type = PACKET_OTHERHOST;
|
//skb_pP->pkt_type = PACKET_OTHERHOST;
|
||||||
skb_pP->pkt_type = PACKET_OUTGOING;
|
skb_pP->pkt_type = PACKET_OUTGOING;
|
||||||
#if 0
|
#if 0
|
||||||
pr_info("GTPURH(%d): Routing packet: %d.%d.%d.%d --> %d.%d.%d.%d Proto: %d, Len: %d Mark: %u Packet type: %u\n",
|
pr_info("GTPURH(%d): Routing packet: %d.%d.%d.%d --> %d.%d.%d.%d Proto: %d, Len: %d Mark: %u Packet type: %u\n",
|
||||||
info_pP->action,
|
info_pP->action,
|
||||||
iph_p->saddr & 0xFF,
|
iph_p->saddr & 0xFF,
|
||||||
(iph_p->saddr & 0x0000FF00) >> 8,
|
(iph_p->saddr & 0x0000FF00) >> 8,
|
||||||
(iph_p->saddr & 0x00FF0000) >> 16,
|
(iph_p->saddr & 0x00FF0000) >> 16,
|
||||||
iph_p->saddr >> 24,
|
iph_p->saddr >> 24,
|
||||||
iph_p->daddr & 0xFF,
|
iph_p->daddr & 0xFF,
|
||||||
(iph_p->daddr & 0x0000FF00) >> 8,
|
(iph_p->daddr & 0x0000FF00) >> 8,
|
||||||
(iph_p->daddr & 0x00FF0000) >> 16,
|
(iph_p->daddr & 0x00FF0000) >> 16,
|
||||||
iph_p->daddr >> 24,
|
iph_p->daddr >> 24,
|
||||||
iph_p->protocol,
|
iph_p->protocol,
|
||||||
ntohs(iph_p->tot_len),
|
ntohs(iph_p->tot_len),
|
||||||
skb_pP->mark,
|
skb_pP->mark,
|
||||||
skb_pP->pkt_type);
|
skb_pP->pkt_type);
|
||||||
#endif
|
#endif
|
||||||
rt = ip_route_output_key(&init_net, &fl.u.ip4);
|
rt = ip_route_output_key(&init_net, &fl.u.ip4);
|
||||||
if (rt == null) {
|
|
||||||
pr_info("GTPURH: Failed to route packet to dst 0x%x. Error: (%d)\n", fl.u.ip4.daddr, err);
|
if (rt == null) {
|
||||||
return GTPURH_FAILURE;
|
pr_info("GTPURH: Failed to route packet to dst 0x%x. Error: (%d)\n", fl.u.ip4.daddr, err);
|
||||||
}
|
return GTPURH_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
if (rt->dst.dev) {
|
|
||||||
pr_info("GTPURH: dst dev name %s\n", rt->dst.dev->name);
|
if (rt->dst.dev) {
|
||||||
} else {
|
pr_info("GTPURH: dst dev name %s\n", rt->dst.dev->name);
|
||||||
pr_info("GTPURH: dst dev NULL\n");
|
} else {
|
||||||
}
|
pr_info("GTPURH: dst dev NULL\n");
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
skb_pP->priority = rt_tos2priority(iph_p->tos);
|
skb_pP->priority = rt_tos2priority(iph_p->tos);
|
||||||
skb_dst_drop(skb_pP);
|
skb_dst_drop(skb_pP);
|
||||||
skb_dst_set(skb_pP, &rt->dst);
|
skb_dst_set(skb_pP, &rt->dst);
|
||||||
skb_pP->dev = skb_dst(skb_pP)->dev;
|
skb_pP->dev = skb_dst(skb_pP)->dev;
|
||||||
|
|
||||||
// Send the GTPu message out
|
// Send the GTPu message out
|
||||||
ip_local_out(skb_pP);
|
ip_local_out(skb_pP);
|
||||||
|
|
||||||
if (err == 0) {
|
if (err == 0) {
|
||||||
return GTPURH_SUCCESS;
|
return GTPURH_SUCCESS;
|
||||||
} else {
|
} else {
|
||||||
return GTPURH_FAILURE;
|
return GTPURH_FAILURE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static unsigned int
|
static unsigned int
|
||||||
_gtpurh_tg4_rem(struct sk_buff *orig_skb_pP, const struct xt_action_param *par_pP) {
|
_gtpurh_tg4_rem(struct sk_buff *orig_skb_pP, const struct xt_action_param *par_pP)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct iphdr *iph_p = ip_hdr(orig_skb_pP);
|
struct iphdr *iph_p = ip_hdr(orig_skb_pP);
|
||||||
struct iphdr *iph2_p = NULL;
|
struct iphdr *iph2_p = NULL;
|
||||||
struct udphdr *udph_p = NULL;
|
struct udphdr *udph_p = NULL;
|
||||||
struct gtpuhdr *gtpuh_p = NULL;
|
struct gtpuhdr *gtpuh_p = NULL;
|
||||||
struct sk_buff *skb_p = NULL;
|
struct sk_buff *skb_p = NULL;
|
||||||
#if defined(NEW_SKB)
|
#if defined(NEW_SKB)
|
||||||
struct sk_buff *new_skb_p = NULL;
|
struct sk_buff *new_skb_p = NULL;
|
||||||
struct iphdr *new_ip_p = NULL;
|
struct iphdr *new_ip_p = NULL;
|
||||||
#endif
|
#endif
|
||||||
uint16_t gtp_payload_size = 0;
|
uint16_t gtp_payload_size = 0;
|
||||||
|
|
||||||
/* Create a new copy of the original skb_p...can't avoid :-( LG: WHY???*/
|
/* Create a new copy of the original skb_p...can't avoid :-( LG: WHY???*/
|
||||||
#if defined(ROUTE_PACKET)
|
#if defined(ROUTE_PACKET)
|
||||||
skb_p = skb_copy(orig_skb_pP, GFP_ATOMIC);
|
skb_p = skb_copy(orig_skb_pP, GFP_ATOMIC);
|
||||||
if (skb_p == NULL) {
|
|
||||||
return NF_ACCEPT;
|
if (skb_p == NULL) {
|
||||||
}
|
return NF_ACCEPT;
|
||||||
skb_p->skb_iif = orig_skb_pP->skb_iif;
|
}
|
||||||
pr_info("GTPURH: skb protocol %04X\n", orig_skb_pP->protocol);
|
|
||||||
skb_p->protocol = orig_skb_pP->protocol;
|
skb_p->skb_iif = orig_skb_pP->skb_iif;
|
||||||
|
pr_info("GTPURH: skb protocol %04X\n", orig_skb_pP->protocol);
|
||||||
|
skb_p->protocol = orig_skb_pP->protocol;
|
||||||
#else
|
#else
|
||||||
skb_p = orig_skb_pP;
|
skb_p = orig_skb_pP;
|
||||||
if (skb_linearize(skb_p) < 0) {
|
|
||||||
pr_info("GTPURH: skb DROPPED (no linearize)\n");
|
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
//---------------------------
|
|
||||||
// check if is GTPU TUNNEL
|
|
||||||
if (iph_p->protocol != IPPROTO_UDP) {
|
|
||||||
pr_info("GTPURH: skb DROPPED Not GTPV1U packet (not UDP)\n");
|
|
||||||
return NF_ACCEPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
//---------------------------
|
if (skb_linearize(skb_p) < 0) {
|
||||||
// check if is fragment
|
pr_info("GTPURH: skb DROPPED (no linearize)\n");
|
||||||
// but should not happen since MTU should have been set bigger than 1500 + GTP encap.
|
|
||||||
// TO DO later segment, but did not succeed in getting in this target all framents of an ip packet!
|
|
||||||
if (_gtpurh_ip_is_fragment(iph_p)) {
|
|
||||||
pr_info("GTPURH: ip_is_fragment YES, FLAGS %04X & %04X = %04X\n",
|
|
||||||
iph_p->frag_off,
|
|
||||||
htons(IP_MF | IP_OFFSET),
|
|
||||||
iph_p->frag_off & htons(IP_MF | IP_OFFSET));
|
|
||||||
return NF_ACCEPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (skb_p->len <= sizeof (struct udphdr) + sizeof (struct gtpuhdr) + sizeof (struct iphdr)) {
|
|
||||||
pr_info("GTPURH: Thought was GTPV1U packet but too short length\n");
|
|
||||||
return NF_ACCEPT;
|
|
||||||
}
|
|
||||||
/* Remove IP header */
|
|
||||||
udph_p = (struct udphdr*)skb_pull(skb_p, (iph_p->ihl << 2));
|
|
||||||
|
|
||||||
if (udph_p->dest != htons(GTPURH_PORT)) {
|
|
||||||
pr_info("GTPURH: Not GTPV1U packet (bad UDP dest port)\n");
|
|
||||||
skb_push(skb_p, (iph_p->ihl << 2));
|
|
||||||
return NF_ACCEPT;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove UDP header */
|
|
||||||
gtpuh_p = (struct gtpuhdr*)skb_pull(skb_p, sizeof(struct udphdr));
|
|
||||||
gtp_payload_size = ntohs(gtpuh_p->length);
|
|
||||||
|
|
||||||
skb_p->mark = ntohl(gtpuh_p->tunid);
|
|
||||||
/* Remove GTPu header */
|
|
||||||
skb_pull(skb_p, sizeof(struct gtpuhdr));
|
|
||||||
|
|
||||||
/* If additional fields are present in header, remove them also */
|
|
||||||
if (gtpuh_p->flags & GTPURH_ANY_EXT_HDR_BIT)
|
|
||||||
{
|
|
||||||
pr_info("GTPURH: GTPURH_ANY_EXT_HDR_BIT found\n");
|
|
||||||
skb_pull(skb_p, sizeof(short) + sizeof(char) + sizeof(char)); /* #Seq, #N-PDU, #ExtHdr Type */
|
|
||||||
gtp_payload_size = gtp_payload_size - sizeof(short) - sizeof(char) - sizeof(char);
|
|
||||||
}
|
|
||||||
skb_set_network_header(skb_p, 0);
|
|
||||||
iph2_p = ip_hdr(skb_p);
|
|
||||||
skb_set_transport_header(skb_p, iph2_p->ihl << 2);
|
|
||||||
|
|
||||||
|
|
||||||
if ((iph2_p->version != 4 ) && (iph2_p->version != 6)) {
|
|
||||||
pr_info("\nGTPURH: Decapsulated packet dropped because not IPvx protocol see all GTPU packet here:\n");
|
|
||||||
_gtpurh_print_hex_octets((unsigned char*)iph_p, ntohs(iph_p->tot_len));
|
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
if ((skb_p->mark == 0) || (gtp_payload_size != ntohs(iph2_p->tot_len))) {
|
|
||||||
pr_info("\nGTPURH: Decapsulated packet: %d.%d.%d.%d --> %d.%d.%d.%d Proto: %d, Total Len (IP): %u mark %u Frag offset %u Flags 0x%0x\n",
|
|
||||||
iph2_p->saddr & 0xFF,
|
|
||||||
(iph2_p->saddr & 0x0000FF00) >> 8,
|
|
||||||
(iph2_p->saddr & 0x00FF0000) >> 16,
|
|
||||||
iph2_p->saddr >> 24,
|
|
||||||
iph2_p->daddr & 0xFF,
|
|
||||||
(iph2_p->daddr & 0x0000FF00) >> 8,
|
|
||||||
(iph2_p->daddr & 0x00FF0000) >> 16,
|
|
||||||
iph2_p->daddr >> 24,
|
|
||||||
iph2_p->protocol,
|
|
||||||
ntohs(iph2_p->tot_len),
|
|
||||||
skb_p->mark,
|
|
||||||
ntohs(iph_p->frag_off) & 0x1FFFFFFF,
|
|
||||||
ntohs(iph_p->frag_off) >> 13);
|
|
||||||
|
|
||||||
if (gtp_payload_size != ntohs(iph2_p->tot_len)) {
|
|
||||||
pr_info("GTPURH: Mismatch in lengths GTPU length: %u -> %u, IP length %u\n",
|
|
||||||
ntohs(gtpuh_p->length),
|
|
||||||
gtp_payload_size,
|
|
||||||
ntohs(iph2_p->tot_len));
|
|
||||||
|
|
||||||
_gtpurh_print_hex_octets((unsigned char*)iph_p, ntohs(iph_p->tot_len));
|
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Route the packet */
|
|
||||||
#if defined(ROUTE_PACKET)
|
|
||||||
_gtpurh_route_packet(skb_p, tgi_pP);
|
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
#else
|
}
|
||||||
{
|
|
||||||
int err = 0;
|
|
||||||
struct rtable *rt = NULL;
|
|
||||||
int daddr = iph2_p->daddr;
|
|
||||||
struct flowi fl = {
|
|
||||||
.u = {
|
|
||||||
.ip4 = {
|
|
||||||
.daddr = daddr,
|
|
||||||
.flowi4_tos = RT_TOS(iph2_p->tos),
|
|
||||||
.flowi4_scope = RT_SCOPE_UNIVERSE,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
rt = ip_route_output_key(&init_net, &fl.u.ip4);
|
|
||||||
if (rt == NULL) {
|
|
||||||
pr_info("GTPURH: Failed to route packet to dst 0x%x. Error: (%d)\n", fl.u.ip4.daddr, err);
|
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
#if 0
|
|
||||||
if (rt->dst.dev) {
|
|
||||||
pr_info("GTPURH: dst dev name %s\n", rt->dst.dev->name);
|
|
||||||
} else {
|
|
||||||
pr_info("GTPURH: dst dev NULL\n");
|
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
skb_p->priority = rt_tos2priority(iph2_p->tos);
|
|
||||||
skb_p->pkt_type = PACKET_OTHERHOST;
|
//---------------------------
|
||||||
skb_dst_drop(skb_p);
|
// check if is GTPU TUNNEL
|
||||||
skb_dst_set(skb_p, dst_clone(&rt->dst));
|
if (iph_p->protocol != IPPROTO_UDP) {
|
||||||
skb_p->dev = skb_dst(skb_p)->dev;
|
pr_info("GTPURH: skb DROPPED Not GTPV1U packet (not UDP)\n");
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
//---------------------------
|
||||||
|
// check if is fragment
|
||||||
|
// but should not happen since MTU should have been set bigger than 1500 + GTP encap.
|
||||||
|
// TO DO later segment, but did not succeed in getting in this target all framents of an ip packet!
|
||||||
|
if (_gtpurh_ip_is_fragment(iph_p)) {
|
||||||
|
pr_info("GTPURH: ip_is_fragment YES, FLAGS %04X & %04X = %04X\n",
|
||||||
|
iph_p->frag_off,
|
||||||
|
htons(IP_MF | IP_OFFSET),
|
||||||
|
iph_p->frag_off & htons(IP_MF | IP_OFFSET));
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (skb_p->len <= sizeof (struct udphdr) + sizeof (struct gtpuhdr) + sizeof (struct iphdr)) {
|
||||||
|
pr_info("GTPURH: Thought was GTPV1U packet but too short length\n");
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove IP header */
|
||||||
|
udph_p = (struct udphdr*)skb_pull(skb_p, (iph_p->ihl << 2));
|
||||||
|
|
||||||
|
if (udph_p->dest != htons(GTPURH_PORT)) {
|
||||||
|
pr_info("GTPURH: Not GTPV1U packet (bad UDP dest port)\n");
|
||||||
|
skb_push(skb_p, (iph_p->ihl << 2));
|
||||||
|
return NF_ACCEPT;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove UDP header */
|
||||||
|
gtpuh_p = (struct gtpuhdr*)skb_pull(skb_p, sizeof(struct udphdr));
|
||||||
|
gtp_payload_size = ntohs(gtpuh_p->length);
|
||||||
|
|
||||||
|
skb_p->mark = ntohl(gtpuh_p->tunid);
|
||||||
|
/* Remove GTPu header */
|
||||||
|
skb_pull(skb_p, sizeof(struct gtpuhdr));
|
||||||
|
|
||||||
|
/* If additional fields are present in header, remove them also */
|
||||||
|
if (gtpuh_p->flags & GTPURH_ANY_EXT_HDR_BIT) {
|
||||||
|
pr_info("GTPURH: GTPURH_ANY_EXT_HDR_BIT found\n");
|
||||||
|
skb_pull(skb_p, sizeof(short) + sizeof(char) + sizeof(char)); /* #Seq, #N-PDU, #ExtHdr Type */
|
||||||
|
gtp_payload_size = gtp_payload_size - sizeof(short) - sizeof(char) - sizeof(char);
|
||||||
|
}
|
||||||
|
|
||||||
|
skb_set_network_header(skb_p, 0);
|
||||||
|
iph2_p = ip_hdr(skb_p);
|
||||||
|
skb_set_transport_header(skb_p, iph2_p->ihl << 2);
|
||||||
|
|
||||||
|
|
||||||
|
if ((iph2_p->version != 4 ) && (iph2_p->version != 6)) {
|
||||||
|
pr_info("\nGTPURH: Decapsulated packet dropped because not IPvx protocol see all GTPU packet here:\n");
|
||||||
|
_gtpurh_print_hex_octets((unsigned char*)iph_p, ntohs(iph_p->tot_len));
|
||||||
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
if ((skb_p->mark == 0) || (gtp_payload_size != ntohs(iph2_p->tot_len))) {
|
||||||
|
pr_info("\nGTPURH: Decapsulated packet: %d.%d.%d.%d --> %d.%d.%d.%d Proto: %d, Total Len (IP): %u mark %u Frag offset %u Flags 0x%0x\n",
|
||||||
|
iph2_p->saddr & 0xFF,
|
||||||
|
(iph2_p->saddr & 0x0000FF00) >> 8,
|
||||||
|
(iph2_p->saddr & 0x00FF0000) >> 16,
|
||||||
|
iph2_p->saddr >> 24,
|
||||||
|
iph2_p->daddr & 0xFF,
|
||||||
|
(iph2_p->daddr & 0x0000FF00) >> 8,
|
||||||
|
(iph2_p->daddr & 0x00FF0000) >> 16,
|
||||||
|
iph2_p->daddr >> 24,
|
||||||
|
iph2_p->protocol,
|
||||||
|
ntohs(iph2_p->tot_len),
|
||||||
|
skb_p->mark,
|
||||||
|
ntohs(iph_p->frag_off) & 0x1FFFFFFF,
|
||||||
|
ntohs(iph_p->frag_off) >> 13);
|
||||||
|
|
||||||
|
if (gtp_payload_size != ntohs(iph2_p->tot_len)) {
|
||||||
|
pr_info("GTPURH: Mismatch in lengths GTPU length: %u -> %u, IP length %u\n",
|
||||||
|
ntohs(gtpuh_p->length),
|
||||||
|
gtp_payload_size,
|
||||||
|
ntohs(iph2_p->tot_len));
|
||||||
|
|
||||||
|
_gtpurh_print_hex_octets((unsigned char*)iph_p, ntohs(iph_p->tot_len));
|
||||||
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Route the packet */
|
||||||
|
#if defined(ROUTE_PACKET)
|
||||||
|
_gtpurh_route_packet(skb_p, tgi_pP);
|
||||||
|
return NF_DROP;
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
int err = 0;
|
||||||
|
struct rtable *rt = NULL;
|
||||||
|
int daddr = iph2_p->daddr;
|
||||||
|
struct flowi fl = {
|
||||||
|
.u = {
|
||||||
|
.ip4 = {
|
||||||
|
.daddr = daddr,
|
||||||
|
.flowi4_tos = RT_TOS(iph2_p->tos),
|
||||||
|
.flowi4_scope = RT_SCOPE_UNIVERSE,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
rt = ip_route_output_key(&init_net, &fl.u.ip4);
|
||||||
|
|
||||||
|
if (rt == NULL) {
|
||||||
|
pr_info("GTPURH: Failed to route packet to dst 0x%x. Error: (%d)\n", fl.u.ip4.daddr, err);
|
||||||
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
|
||||||
|
if (rt->dst.dev) {
|
||||||
|
pr_info("GTPURH: dst dev name %s\n", rt->dst.dev->name);
|
||||||
|
} else {
|
||||||
|
pr_info("GTPURH: dst dev NULL\n");
|
||||||
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
skb_p->priority = rt_tos2priority(iph2_p->tos);
|
||||||
|
skb_p->pkt_type = PACKET_OTHERHOST;
|
||||||
|
skb_dst_drop(skb_p);
|
||||||
|
skb_dst_set(skb_p, dst_clone(&rt->dst));
|
||||||
|
skb_p->dev = skb_dst(skb_p)->dev;
|
||||||
|
|
||||||
#if defined(NEW_SKB)
|
#if defined(NEW_SKB)
|
||||||
new_skb_p = alloc_skb(LL_MAX_HEADER + ntohs(iph2_p->tot_len), GFP_ATOMIC);
|
new_skb_p = alloc_skb(LL_MAX_HEADER + ntohs(iph2_p->tot_len), GFP_ATOMIC);
|
||||||
if (new_skb_p == NULL) {
|
|
||||||
return NF_DROP;
|
if (new_skb_p == NULL) {
|
||||||
}
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
skb_reserve(new_skb_p, LL_MAX_HEADER + ntohs(iph2_p->tot_len));
|
skb_reserve(new_skb_p, LL_MAX_HEADER + ntohs(iph2_p->tot_len));
|
||||||
new_skb_p->protocol = skb_p->protocol;
|
new_skb_p->protocol = skb_p->protocol;
|
||||||
|
|
||||||
new_ip_p = (void *)skb_push(new_skb_p, ntohs(iph2_p->tot_len) - (iph2_p->ihl << 2));
|
new_ip_p = (void *)skb_push(new_skb_p, ntohs(iph2_p->tot_len) - (iph2_p->ihl << 2));
|
||||||
skb_reset_transport_header(new_skb_p);
|
skb_reset_transport_header(new_skb_p);
|
||||||
new_ip_p = (void *)skb_push(new_skb_p, iph2_p->ihl << 2);
|
new_ip_p = (void *)skb_push(new_skb_p, iph2_p->ihl << 2);
|
||||||
memcpy(new_ip_p, iph2_p, ntohs(iph2_p->tot_len));
|
memcpy(new_ip_p, iph2_p, ntohs(iph2_p->tot_len));
|
||||||
skb_reset_network_header(new_skb_p);
|
skb_reset_network_header(new_skb_p);
|
||||||
skb_reset_inner_network_header(new_skb_p);
|
skb_reset_inner_network_header(new_skb_p);
|
||||||
skb_reset_inner_transport_header(new_skb_p);
|
skb_reset_inner_transport_header(new_skb_p);
|
||||||
|
|
||||||
new_skb_p->mark = ntohl(gtpuh_p->tunid);
|
new_skb_p->mark = ntohl(gtpuh_p->tunid);
|
||||||
//new_skb_p->mark = skb_p->mark;
|
//new_skb_p->mark = skb_p->mark;
|
||||||
|
|
||||||
/* ip_route_me_harder expects skb->dst to be set */
|
/* ip_route_me_harder expects skb->dst to be set */
|
||||||
skb_dst_set(new_skb_p, dst_clone(skb_dst(skb_p)));
|
skb_dst_set(new_skb_p, dst_clone(skb_dst(skb_p)));
|
||||||
|
|
||||||
/*if (ip_route_me_harder(new_skb_p, RTN_UNSPEC) < 0) {
|
/*if (ip_route_me_harder(new_skb_p, RTN_UNSPEC) < 0) {
|
||||||
pr_info("GTPURH: cannot route harder dest 0x%x\n", daddr);
|
pr_info("GTPURH: cannot route harder dest 0x%x\n", daddr);
|
||||||
goto free_skb;
|
goto free_skb;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
new_ip_p->ttl = new_ip_p->ttl -1; // ip4_dst_hoplimit(skb_dst(new_skb_p));
|
new_ip_p->ttl = new_ip_p->ttl -1; // ip4_dst_hoplimit(skb_dst(new_skb_p));
|
||||||
new_skb_p->ip_summed = CHECKSUM_NONE;
|
new_skb_p->ip_summed = CHECKSUM_NONE;
|
||||||
|
|
||||||
if (new_skb_p->len > dst_mtu(skb_dst(new_skb_p))) {
|
if (new_skb_p->len > dst_mtu(skb_dst(new_skb_p))) {
|
||||||
pr_info("GTPURH: bad length\n");
|
pr_info("GTPURH: bad length\n");
|
||||||
goto free_skb;
|
goto free_skb;
|
||||||
}
|
}
|
||||||
|
|
||||||
nf_ct_attach(new_skb_p, skb_p);
|
nf_ct_attach(new_skb_p, skb_p);
|
||||||
/*pr_info("GTPURH: ip_local_out %s/%s dev %s src %u.%u.%u.%u dst %u.%u.%u.%u\n",
|
/*pr_info("GTPURH: ip_local_out %s/%s dev %s src %u.%u.%u.%u dst %u.%u.%u.%u\n",
|
||||||
_gtpurh_nf_inet_hook_2_string(par_pP->hooknum),
|
_gtpurh_nf_inet_hook_2_string(par_pP->hooknum),
|
||||||
gtpurh_tg_reg[0].table,
|
gtpurh_tg_reg[0].table,
|
||||||
(new_skb_p->dev == NULL) ? "NULL" : new_skb_p->dev->name,
|
(new_skb_p->dev == NULL) ? "NULL" : new_skb_p->dev->name,
|
||||||
NIPADDR(new_ip_p->saddr),
|
NIPADDR(new_ip_p->saddr),
|
||||||
NIPADDR(new_ip_p->daddr));*/
|
NIPADDR(new_ip_p->daddr));*/
|
||||||
ip_local_out(new_skb_p);
|
ip_local_out(new_skb_p);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
free_skb:
|
free_skb:
|
||||||
pr_info("GTPURH: Dropped skb ip_local_out %s/%s\n",
|
pr_info("GTPURH: Dropped skb ip_local_out %s/%s\n",
|
||||||
_gtpurh_nf_inet_hook_2_string(par_pP->hooknum),
|
_gtpurh_nf_inet_hook_2_string(par_pP->hooknum),
|
||||||
gtpurh_tg_reg[0].table);
|
gtpurh_tg_reg[0].table);
|
||||||
kfree_skb(new_skb_p);
|
kfree_skb(new_skb_p);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
free_skb:
|
free_skb:
|
||||||
pr_info("GTPURH: Dropped skb\n");
|
pr_info("GTPURH: Dropped skb\n");
|
||||||
kfree_skb(skb_p);
|
kfree_skb(skb_p);
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,17 +510,18 @@ static unsigned int
|
|||||||
gtpurh_tg6(struct sk_buff *skb_pP, const struct xt_action_param *par_pP)
|
gtpurh_tg6(struct sk_buff *skb_pP, const struct xt_action_param *par_pP)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
const struct xt_gtpurh_target_info *tgi_p = par_pP->targinfo;
|
const struct xt_gtpurh_target_info *tgi_p = par_pP->targinfo;
|
||||||
int result = NF_DROP;
|
int result = NF_DROP;
|
||||||
|
|
||||||
if (tgi_p == NULL) {
|
if (tgi_p == NULL) {
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tgi_p->action == PARAM_GTPURH_ACTION_REM) {
|
|
||||||
result = NF_DROP; // TO DO
|
|
||||||
}
|
|
||||||
return result;
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgi_p->action == PARAM_GTPURH_ACTION_REM) {
|
||||||
|
result = NF_DROP; // TO DO
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -487,67 +530,70 @@ static unsigned int
|
|||||||
gtpurh_tg4(struct sk_buff *skb_pP, const struct xt_action_param *par_pP)
|
gtpurh_tg4(struct sk_buff *skb_pP, const struct xt_action_param *par_pP)
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
{
|
{
|
||||||
const struct iphdr *iph_p = ip_hdr(skb_pP);
|
const struct iphdr *iph_p = ip_hdr(skb_pP);
|
||||||
const struct rtable *rt_p = skb_rtable(skb_pP);
|
const struct rtable *rt_p = skb_rtable(skb_pP);
|
||||||
const struct xt_gtpurh_target_info *tgi_p = par_pP->targinfo;
|
const struct xt_gtpurh_target_info *tgi_p = par_pP->targinfo;
|
||||||
|
|
||||||
if (tgi_p == NULL) {
|
if (tgi_p == NULL) {
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tgi_p->raddr != iph_p->saddr) || (tgi_p->laddr != iph_p->daddr)) {
|
if ((tgi_p->raddr != iph_p->saddr) || (tgi_p->laddr != iph_p->daddr)) {
|
||||||
pr_info("GTPURH: Not processed because of not matching saddr %d.%d.%d.%d raddr %d.%d.%d.%d laddr %d.%d.%d.%d daddr %d.%d.%d.%d\n",
|
pr_info("GTPURH: Not processed because of not matching saddr %d.%d.%d.%d raddr %d.%d.%d.%d laddr %d.%d.%d.%d daddr %d.%d.%d.%d\n",
|
||||||
NIPADDR(tgi_p->raddr),
|
NIPADDR(tgi_p->raddr),
|
||||||
NIPADDR(iph_p->saddr),
|
NIPADDR(iph_p->saddr),
|
||||||
NIPADDR(tgi_p->laddr),
|
NIPADDR(tgi_p->laddr),
|
||||||
NIPADDR(iph_p->daddr));
|
NIPADDR(iph_p->daddr));
|
||||||
return NF_ACCEPT;
|
return NF_ACCEPT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ip_hdrlen(skb_pP) != sizeof(struct iphdr)) {
|
if (ip_hdrlen(skb_pP) != sizeof(struct iphdr)) {
|
||||||
pr_info("GTPURH: Dropped because IP options\n");
|
pr_info("GTPURH: Dropped because IP options\n");
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Drop fragments
|
|
||||||
if (iph_p->frag_off & htons(IP_OFFSET)) {
|
|
||||||
pr_info("GTPURH: Dropped because is fragment\n");
|
|
||||||
return NF_DROP;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tgi_p->action == PARAM_GTPURH_ACTION_REM) {
|
|
||||||
return _gtpurh_tg4_rem(skb_pP, par_pP);
|
|
||||||
}
|
|
||||||
return NF_DROP;
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Drop fragments
|
||||||
|
if (iph_p->frag_off & htons(IP_OFFSET)) {
|
||||||
|
pr_info("GTPURH: Dropped because is fragment\n");
|
||||||
|
return NF_DROP;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tgi_p->action == PARAM_GTPURH_ACTION_REM) {
|
||||||
|
return _gtpurh_tg4_rem(skb_pP, par_pP);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NF_DROP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static int
|
static int
|
||||||
__init gtpurh_tg_init(void) {
|
__init gtpurh_tg_init(void)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
pr_info("GTPURH: Initializing module (KVersion: %d)\n", KVERSION);
|
pr_info("GTPURH: Initializing module (KVersion: %d)\n", KVERSION);
|
||||||
pr_info("GTPURH: Copyright Polaris Networks 2010-2011\n");
|
pr_info("GTPURH: Copyright Polaris Networks 2010-2011\n");
|
||||||
pr_info("GTPURH: Modified by EURECOM Lionel GAUTHIER 2014\n");
|
pr_info("GTPURH: Modified by EURECOM Lionel GAUTHIER 2014\n");
|
||||||
#ifndef CMAKER
|
#ifndef CMAKER
|
||||||
pr_info("GTPURH: Compiled %s at time %s\n",__DATE__,__TIME__);
|
pr_info("GTPURH: Compiled %s at time %s\n",__DATE__,__TIME__);
|
||||||
#endif
|
|
||||||
#if defined(WITH_IPV6)
|
|
||||||
pr_info("GTPURH: IPv4/IPv6 enabled\n");
|
|
||||||
#else
|
|
||||||
pr_info("GTPURH: IPv4 only enabled\n");
|
|
||||||
#endif
|
#endif
|
||||||
return xt_register_targets(gtpurh_tg_reg, ARRAY_SIZE(gtpurh_tg_reg));
|
#if defined(WITH_IPV6)
|
||||||
|
pr_info("GTPURH: IPv4/IPv6 enabled\n");
|
||||||
|
#else
|
||||||
|
pr_info("GTPURH: IPv4 only enabled\n");
|
||||||
|
#endif
|
||||||
|
return xt_register_targets(gtpurh_tg_reg, ARRAY_SIZE(gtpurh_tg_reg));
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
static void
|
static void
|
||||||
__exit gtpurh_tg_exit(void) {
|
__exit gtpurh_tg_exit(void)
|
||||||
//-----------------------------------------------------------------------------
|
{
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
xt_unregister_targets(gtpurh_tg_reg, ARRAY_SIZE(gtpurh_tg_reg));
|
xt_unregister_targets(gtpurh_tg_reg, ARRAY_SIZE(gtpurh_tg_reg));
|
||||||
pr_info("GTPURH: Unloading module\n");
|
pr_info("GTPURH: Unloading module\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
module_init(gtpurh_tg_init);
|
module_init(gtpurh_tg_init);
|
||||||
|
|||||||
@@ -9,18 +9,16 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
enum xt_gtpurh_mode_
|
enum xt_gtpurh_mode_ {
|
||||||
{
|
PARAM_GTPURH_ACTION_REM = 1 << 9,
|
||||||
PARAM_GTPURH_ACTION_REM = 1 << 9,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct xt_gtpurh_target_info
|
struct xt_gtpurh_target_info {
|
||||||
{
|
u_int32_t laddr __attribute__((aligned(8)));
|
||||||
u_int32_t laddr __attribute__((aligned(8)));
|
u_int32_t raddr __attribute__((aligned(8)));
|
||||||
u_int32_t raddr __attribute__((aligned(8)));
|
u_int32_t ltun __attribute__((aligned(8)));
|
||||||
u_int32_t ltun __attribute__((aligned(8)));
|
u_int32_t rtun __attribute__((aligned(8)));
|
||||||
u_int32_t rtun __attribute__((aligned(8)));
|
u_int32_t action __attribute__((aligned(8)));
|
||||||
u_int32_t action __attribute__((aligned(8)));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+664
-626
File diff suppressed because it is too large
Load Diff
@@ -46,93 +46,93 @@
|
|||||||
#define GTPV1U_MAX_BEARERS_ID (max_val_DRB_Identity - GTPV1U_BEARER_OFFSET)
|
#define GTPV1U_MAX_BEARERS_ID (max_val_DRB_Identity - GTPV1U_BEARER_OFFSET)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BEARER_DOWN = 0,
|
BEARER_DOWN = 0,
|
||||||
BEARER_IN_CONFIG,
|
BEARER_IN_CONFIG,
|
||||||
BEARER_UP,
|
BEARER_UP,
|
||||||
BEARER_DL_HANDOVER,
|
BEARER_DL_HANDOVER,
|
||||||
BEARER_UL_HANDOVER,
|
BEARER_UL_HANDOVER,
|
||||||
BEARER_MAX,
|
BEARER_MAX,
|
||||||
} bearer_state_t;
|
} bearer_state_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct gtpv1u_teid_data_s {
|
typedef struct gtpv1u_teid_data_s {
|
||||||
/* UE identifier for oaisim stack */
|
/* UE identifier for oaisim stack */
|
||||||
module_id_t enb_id;
|
module_id_t enb_id;
|
||||||
module_id_t ue_id;
|
module_id_t ue_id;
|
||||||
ebi_t eps_bearer_id;
|
ebi_t eps_bearer_id;
|
||||||
} gtpv1u_teid_data_t;
|
} gtpv1u_teid_data_t;
|
||||||
|
|
||||||
|
|
||||||
typedef struct gtpv1u_bearer_s {
|
typedef struct gtpv1u_bearer_s {
|
||||||
/* TEID used in dl and ul */
|
/* TEID used in dl and ul */
|
||||||
teid_t teid_eNB; ///< eNB TEID
|
teid_t teid_eNB; ///< eNB TEID
|
||||||
teid_t teid_sgw; ///< Remote TEID
|
teid_t teid_sgw; ///< Remote TEID
|
||||||
in_addr_t sgw_ip_addr;
|
in_addr_t sgw_ip_addr;
|
||||||
struct in6_addr sgw_ip6_addr;
|
struct in6_addr sgw_ip6_addr;
|
||||||
tcp_udp_port_t port;
|
tcp_udp_port_t port;
|
||||||
//NwGtpv1uStackSessionHandleT stack_session;
|
//NwGtpv1uStackSessionHandleT stack_session;
|
||||||
bearer_state_t state;
|
bearer_state_t state;
|
||||||
} gtpv1u_bearer_t;
|
} gtpv1u_bearer_t;
|
||||||
|
|
||||||
typedef struct gtpv1u_ue_data_s {
|
typedef struct gtpv1u_ue_data_s {
|
||||||
/* UE identifier for oaisim stack */
|
/* UE identifier for oaisim stack */
|
||||||
module_id_t ue_id;
|
module_id_t ue_id;
|
||||||
|
|
||||||
/* Unique identifier used between PDCP and GTP-U to distinguish UEs */
|
/* Unique identifier used between PDCP and GTP-U to distinguish UEs */
|
||||||
uint32_t instance_id;
|
uint32_t instance_id;
|
||||||
int num_bearers;
|
int num_bearers;
|
||||||
/* Bearer related data.
|
/* Bearer related data.
|
||||||
* Note that the first LCID available for data is 3 and we fixed the maximum
|
* Note that the first LCID available for data is 3 and we fixed the maximum
|
||||||
* number of e-rab per UE to be (32 [id range]), max RB is 11. The real rb id will 3 + rab_id (3..32).
|
* number of e-rab per UE to be (32 [id range]), max RB is 11. The real rb id will 3 + rab_id (3..32).
|
||||||
*/
|
*/
|
||||||
gtpv1u_bearer_t bearers[GTPV1U_MAX_BEARERS_ID];
|
gtpv1u_bearer_t bearers[GTPV1U_MAX_BEARERS_ID];
|
||||||
|
|
||||||
//RB_ENTRY(gtpv1u_ue_data_s) gtpv1u_ue_node;
|
//RB_ENTRY(gtpv1u_ue_data_s) gtpv1u_ue_node;
|
||||||
} gtpv1u_ue_data_t;
|
} gtpv1u_ue_data_t;
|
||||||
|
|
||||||
typedef struct gtpv1u_data_s{
|
typedef struct gtpv1u_data_s {
|
||||||
/* nwgtpv1u stack internal data */
|
/* nwgtpv1u stack internal data */
|
||||||
NwGtpv1uStackHandleT gtpv1u_stack;
|
NwGtpv1uStackHandleT gtpv1u_stack;
|
||||||
|
|
||||||
/* RB tree of UEs */
|
/* RB tree of UEs */
|
||||||
hash_table_t *ue_mapping; // PDCP->GTPV1U
|
hash_table_t *ue_mapping; // PDCP->GTPV1U
|
||||||
hash_table_t *teid_mapping; // GTPV1U -> PDCP
|
hash_table_t *teid_mapping; // GTPV1U -> PDCP
|
||||||
|
|
||||||
//RB_HEAD(gtpv1u_ue_map, gtpv1u_ue_data_s) gtpv1u_ue_map_head;
|
//RB_HEAD(gtpv1u_ue_map, gtpv1u_ue_data_s) gtpv1u_ue_map_head;
|
||||||
/* Local IP address to use */
|
/* Local IP address to use */
|
||||||
in_addr_t enb_ip_address_for_S1u_S12_S4_up;
|
in_addr_t enb_ip_address_for_S1u_S12_S4_up;
|
||||||
char *ip_addr;
|
char *ip_addr;
|
||||||
tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
|
tcp_udp_port_t enb_port_for_S1u_S12_S4_up;
|
||||||
/* UDP internal data */
|
/* UDP internal data */
|
||||||
//udp_data_t udp_data;
|
//udp_data_t udp_data;
|
||||||
|
|
||||||
uint16_t seq_num;
|
uint16_t seq_num;
|
||||||
uint8_t restart_counter;
|
uint8_t restart_counter;
|
||||||
|
|
||||||
#ifdef GTPU_IN_KERNEL
|
#ifdef GTPU_IN_KERNEL
|
||||||
char *interface_name;
|
char *interface_name;
|
||||||
int interface_index;
|
int interface_index;
|
||||||
|
|
||||||
struct iovec *malloc_ring;
|
struct iovec *malloc_ring;
|
||||||
void *sock_mmap_ring[16];
|
void *sock_mmap_ring[16];
|
||||||
int sock_desc[16]; // indexed by marking
|
int sock_desc[16]; // indexed by marking
|
||||||
#endif
|
#endif
|
||||||
} gtpv1u_data_t;
|
} gtpv1u_data_t;
|
||||||
|
|
||||||
int
|
int
|
||||||
gtpv1u_new_data_req(
|
gtpv1u_new_data_req(
|
||||||
uint8_t enb_id,
|
uint8_t enb_id,
|
||||||
uint8_t ue_id,
|
uint8_t ue_id,
|
||||||
uint8_t rab_id,
|
uint8_t rab_id,
|
||||||
uint8_t *buffer,
|
uint8_t *buffer,
|
||||||
uint32_t buf_len,
|
uint32_t buf_len,
|
||||||
uint32_t buf_offset);
|
uint32_t buf_offset);
|
||||||
|
|
||||||
int
|
int
|
||||||
gtpv1u_initial_req(
|
gtpv1u_initial_req(
|
||||||
gtpv1u_data_t *gtpv1u_data_p,
|
gtpv1u_data_t *gtpv1u_data_p,
|
||||||
uint32_t teid,
|
uint32_t teid,
|
||||||
uint16_t port,
|
uint16_t port,
|
||||||
uint32_t address);
|
uint32_t address);
|
||||||
|
|
||||||
#endif /* GTPV1U_ENB_DEFS_H_ */
|
#endif /* GTPV1U_ENB_DEFS_H_ */
|
||||||
|
|||||||
@@ -38,11 +38,11 @@
|
|||||||
|
|
||||||
int
|
int
|
||||||
gtpv1u_new_data_req(
|
gtpv1u_new_data_req(
|
||||||
uint8_t enb_id,
|
uint8_t enb_id,
|
||||||
uint8_t ue_id,
|
uint8_t ue_id,
|
||||||
uint8_t rab_id,
|
uint8_t rab_id,
|
||||||
uint8_t *buffer,
|
uint8_t *buffer,
|
||||||
uint32_t buf_len);
|
uint32_t buf_len);
|
||||||
void *gtpv1u_eNB_task(void *args);
|
void *gtpv1u_eNB_task(void *args);
|
||||||
|
|
||||||
#endif /* GTPV1U_ENB_TASK_H_ */
|
#endif /* GTPV1U_ENB_TASK_H_ */
|
||||||
|
|||||||
@@ -40,12 +40,12 @@
|
|||||||
#define MAX_BEARERS_PER_UE (11)
|
#define MAX_BEARERS_PER_UE (11)
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
BEARER_DOWN = 0,
|
BEARER_DOWN = 0,
|
||||||
BEARER_IN_CONFIG,
|
BEARER_IN_CONFIG,
|
||||||
BEARER_UP,
|
BEARER_UP,
|
||||||
BEARER_DL_HANDOVER,
|
BEARER_DL_HANDOVER,
|
||||||
BEARER_UL_HANDOVER,
|
BEARER_UL_HANDOVER,
|
||||||
BEARER_MAX,
|
BEARER_MAX,
|
||||||
} bearer_state_t;
|
} bearer_state_t;
|
||||||
|
|
||||||
#define BUFFER_TO_NwU32T(buf, x) \
|
#define BUFFER_TO_NwU32T(buf, x) \
|
||||||
@@ -59,11 +59,11 @@ do { \
|
|||||||
|
|
||||||
|
|
||||||
typedef struct gtpv1u_teid2enb_info_s {
|
typedef struct gtpv1u_teid2enb_info_s {
|
||||||
/* TEID used in dl and ul */
|
/* TEID used in dl and ul */
|
||||||
uint32_t teid_enb; ///< Remote eNB TEID
|
uint32_t teid_enb; ///< Remote eNB TEID
|
||||||
ip_address_t enb_ip_addr;
|
ip_address_t enb_ip_addr;
|
||||||
bearer_state_t state;
|
bearer_state_t state;
|
||||||
uint16_t port; /// LG ???
|
uint16_t port; /// LG ???
|
||||||
} gtpv1u_teid2enb_info_t;
|
} gtpv1u_teid2enb_info_t;
|
||||||
|
|
||||||
/*struct gtpv1u_ue_data_s {
|
/*struct gtpv1u_ue_data_s {
|
||||||
@@ -83,18 +83,18 @@ typedef struct gtpv1u_teid2enb_info_s {
|
|||||||
};*/
|
};*/
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* nwgtpv1u stack internal data */
|
/* nwgtpv1u stack internal data */
|
||||||
NwGtpv1uStackHandleT gtpv1u_stack;
|
NwGtpv1uStackHandleT gtpv1u_stack;
|
||||||
/* RB tree of UEs */
|
/* RB tree of UEs */
|
||||||
//RB_HEAD(gtpv1u_ue_map, gtpv1u_ue_data_s) gtpv1u_ue_map_head;
|
//RB_HEAD(gtpv1u_ue_map, gtpv1u_ue_data_s) gtpv1u_ue_map_head;
|
||||||
/* Local IP address to use */
|
/* Local IP address to use */
|
||||||
uint32_t sgw_ip_address_for_S1u_S12_S4_up;
|
uint32_t sgw_ip_address_for_S1u_S12_S4_up;
|
||||||
char *ip_addr;
|
char *ip_addr;
|
||||||
|
|
||||||
uint16_t seq_num;
|
uint16_t seq_num;
|
||||||
uint8_t restart_counter;
|
uint8_t restart_counter;
|
||||||
//gtpv1u_teid2enb_info_t* teid2enb_mapping[];
|
//gtpv1u_teid2enb_info_t* teid2enb_mapping[];
|
||||||
hash_table_t *S1U_mapping;
|
hash_table_t *S1U_mapping;
|
||||||
|
|
||||||
} gtpv1u_data_t;
|
} gtpv1u_data_t;
|
||||||
|
|
||||||
|
|||||||
+436
-407
@@ -61,23 +61,23 @@ static int gtpv1u_update_s1u_tunnel(Gtpv1uUpdateTunnelReq *reqP);
|
|||||||
static void *gtpv1u_thread(void *args);
|
static void *gtpv1u_thread(void *args);
|
||||||
|
|
||||||
NwGtpv1uRcT gtpv1u_send_udp_msg(
|
NwGtpv1uRcT gtpv1u_send_udp_msg(
|
||||||
NwGtpv1uUdpHandleT udpHandle,
|
NwGtpv1uUdpHandleT udpHandle,
|
||||||
NwU8T *buffer,
|
NwU8T *buffer,
|
||||||
NwU32T buffer_len,
|
NwU32T buffer_len,
|
||||||
NwU32T buffer_offset,
|
NwU32T buffer_offset,
|
||||||
NwU32T peerIpAddr,
|
NwU32T peerIpAddr,
|
||||||
NwU32T peerPort);
|
NwU32T peerPort);
|
||||||
|
|
||||||
NwGtpv1uRcT gtpv1u_log_request(
|
NwGtpv1uRcT gtpv1u_log_request(
|
||||||
NwGtpv1uLogMgrHandleT hLogMgr,
|
NwGtpv1uLogMgrHandleT hLogMgr,
|
||||||
NwU32T logLevel,
|
NwU32T logLevel,
|
||||||
NwCharT *file,
|
NwCharT *file,
|
||||||
NwU32T line,
|
NwU32T line,
|
||||||
NwCharT *logStr);
|
NwCharT *logStr);
|
||||||
|
|
||||||
NwGtpv1uRcT gtpv1u_process_stack_req(
|
NwGtpv1uRcT gtpv1u_process_stack_req(
|
||||||
NwGtpv1uUlpHandleT hUlp,
|
NwGtpv1uUlpHandleT hUlp,
|
||||||
NwGtpv1uUlpApiT *pUlpApi);
|
NwGtpv1uUlpApiT *pUlpApi);
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
@@ -107,21 +107,25 @@ void gtpu_print_hex_octets(unsigned char* dataP, unsigned long sizeP)
|
|||||||
GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday);
|
GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday);
|
||||||
GTPU_DEBUG("%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday);
|
GTPU_DEBUG("%s | 0 1 2 3 4 5 6 7 8 9 a b c d e f |\n",timeofday);
|
||||||
GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday);
|
GTPU_DEBUG("%s------+-------------------------------------------------|\n",timeofday);
|
||||||
|
|
||||||
for (octet_index = 0; octet_index < sizeP; octet_index++) {
|
for (octet_index = 0; octet_index < sizeP; octet_index++) {
|
||||||
if (GTPU_2_PRINT_BUFFER_LEN < (buffer_marker + 32)) {
|
if (GTPU_2_PRINT_BUFFER_LEN < (buffer_marker + 32)) {
|
||||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker,
|
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker,
|
||||||
"... (print buffer overflow)");
|
"... (print buffer overflow)");
|
||||||
GTPU_DEBUG("%s%s",timeofday,gtpu_2_print_buffer);
|
GTPU_DEBUG("%s%s",timeofday,gtpu_2_print_buffer);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if ((octet_index % 16) == 0){
|
|
||||||
|
if ((octet_index % 16) == 0) {
|
||||||
if (octet_index != 0) {
|
if (octet_index != 0) {
|
||||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
||||||
GTPU_DEBUG("%s%s",timeofday, gtpu_2_print_buffer);
|
GTPU_DEBUG("%s%s",timeofday, gtpu_2_print_buffer);
|
||||||
buffer_marker = 0;
|
buffer_marker = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " %04ld |", octet_index);
|
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " %04ld |", octet_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Print every single octet in hexadecimal form
|
* Print every single octet in hexadecimal form
|
||||||
*/
|
*/
|
||||||
@@ -136,7 +140,8 @@ void gtpu_print_hex_octets(unsigned char* dataP, unsigned long sizeP)
|
|||||||
*/
|
*/
|
||||||
for (aindex = octet_index; aindex < 16; ++aindex)
|
for (aindex = octet_index; aindex < 16; ++aindex)
|
||||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " ");
|
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " ");
|
||||||
//GTPU_DEBUG(" ");
|
|
||||||
|
//GTPU_DEBUG(" ");
|
||||||
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
buffer_marker+=snprintf(>pu_2_print_buffer[buffer_marker], GTPU_2_PRINT_BUFFER_LEN - buffer_marker, " |\n");
|
||||||
GTPU_DEBUG("%s%s",timeofday,gtpu_2_print_buffer);
|
GTPU_DEBUG("%s%s",timeofday,gtpu_2_print_buffer);
|
||||||
}
|
}
|
||||||
@@ -144,23 +149,24 @@ void gtpu_print_hex_octets(unsigned char* dataP, unsigned long sizeP)
|
|||||||
|
|
||||||
static int gtpv1u_send_init_udp(uint16_t port_number)
|
static int gtpv1u_send_init_udp(uint16_t port_number)
|
||||||
{
|
{
|
||||||
// Create and alloc new message
|
// Create and alloc new message
|
||||||
MessageDef *message_p;
|
MessageDef *message_p;
|
||||||
struct in_addr addr;
|
struct in_addr addr;
|
||||||
|
|
||||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_INIT);
|
message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_INIT);
|
||||||
if (message_p == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
UDP_INIT(message_p).port = port_number;
|
if (message_p == NULL) {
|
||||||
//LG UDP_INIT(message_p).address = "0.0.0.0"; //ANY address
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
addr.s_addr = gtpv1u_sgw_data.sgw_ip_address_for_S1u_S12_S4_up;
|
UDP_INIT(message_p).port = port_number;
|
||||||
UDP_INIT(message_p).address = inet_ntoa(addr);
|
//LG UDP_INIT(message_p).address = "0.0.0.0"; //ANY address
|
||||||
GTPU_DEBUG("Tx UDP_INIT IP addr %s\n", UDP_INIT(message_p).address);
|
|
||||||
|
|
||||||
return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p);
|
addr.s_addr = gtpv1u_sgw_data.sgw_ip_address_for_S1u_S12_S4_up;
|
||||||
|
UDP_INIT(message_p).address = inet_ntoa(addr);
|
||||||
|
GTPU_DEBUG("Tx UDP_INIT IP addr %s\n", UDP_INIT(message_p).address);
|
||||||
|
|
||||||
|
return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT gtpv1u_log_request(NwGtpv1uLogMgrHandleT hLogMgr,
|
NwGtpv1uRcT gtpv1u_log_request(NwGtpv1uLogMgrHandleT hLogMgr,
|
||||||
@@ -169,471 +175,494 @@ NwGtpv1uRcT gtpv1u_log_request(NwGtpv1uLogMgrHandleT hLogMgr,
|
|||||||
NwU32T line,
|
NwU32T line,
|
||||||
NwCharT *logStr)
|
NwCharT *logStr)
|
||||||
{
|
{
|
||||||
GTPU_DEBUG("%s\n", logStr);
|
GTPU_DEBUG("%s\n", logStr);
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT gtpv1u_send_udp_msg(
|
NwGtpv1uRcT gtpv1u_send_udp_msg(
|
||||||
NwGtpv1uUdpHandleT udpHandle,
|
NwGtpv1uUdpHandleT udpHandle,
|
||||||
NwU8T *buffer,
|
NwU8T *buffer,
|
||||||
NwU32T buffer_len,
|
NwU32T buffer_len,
|
||||||
NwU32T buffer_offset,
|
NwU32T buffer_offset,
|
||||||
NwU32T peerIpAddr,
|
NwU32T peerIpAddr,
|
||||||
NwU32T peerPort)
|
NwU32T peerPort)
|
||||||
{
|
{
|
||||||
// Create and alloc new message
|
// Create and alloc new message
|
||||||
MessageDef *message_p;
|
MessageDef *message_p;
|
||||||
udp_data_req_t *udp_data_req_p;
|
udp_data_req_t *udp_data_req_p;
|
||||||
|
|
||||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_DATA_REQ);
|
message_p = itti_alloc_new_message(TASK_GTPV1_U, UDP_DATA_REQ);
|
||||||
|
|
||||||
udp_data_req_p = &message_p->ittiMsg.udp_data_req;
|
udp_data_req_p = &message_p->ittiMsg.udp_data_req;
|
||||||
|
|
||||||
udp_data_req_p->peer_address = peerIpAddr;
|
udp_data_req_p->peer_address = peerIpAddr;
|
||||||
udp_data_req_p->peer_port = peerPort;
|
udp_data_req_p->peer_port = peerPort;
|
||||||
udp_data_req_p->buffer = buffer;
|
udp_data_req_p->buffer = buffer;
|
||||||
udp_data_req_p->buffer_length = buffer_len;
|
udp_data_req_p->buffer_length = buffer_len;
|
||||||
udp_data_req_p->buffer_offset = buffer_offset;
|
udp_data_req_p->buffer_offset = buffer_offset;
|
||||||
|
|
||||||
return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p);
|
return itti_send_msg_to_task(TASK_UDP, INSTANCE_DEFAULT, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Callback called when a gtpv1u message arrived on UDP interface */
|
/* Callback called when a gtpv1u message arrived on UDP interface */
|
||||||
NwGtpv1uRcT gtpv1u_process_stack_req(
|
NwGtpv1uRcT gtpv1u_process_stack_req(
|
||||||
NwGtpv1uUlpHandleT hUlp,
|
NwGtpv1uUlpHandleT hUlp,
|
||||||
NwGtpv1uUlpApiT *pUlpApi)
|
NwGtpv1uUlpApiT *pUlpApi)
|
||||||
{
|
{
|
||||||
switch(pUlpApi->apiType) {
|
switch(pUlpApi->apiType) {
|
||||||
/* Here there are two type of messages handled:
|
/* Here there are two type of messages handled:
|
||||||
* - T-PDU
|
* - T-PDU
|
||||||
* - END-MARKER
|
* - END-MARKER
|
||||||
*/
|
*/
|
||||||
case NW_GTPV1U_ULP_API_RECV_TPDU: {
|
case NW_GTPV1U_ULP_API_RECV_TPDU: {
|
||||||
//uint8_t buffer[4096];
|
//uint8_t buffer[4096];
|
||||||
//uint32_t buffer_len;
|
//uint32_t buffer_len;
|
||||||
MessageDef *message_p = NULL;
|
MessageDef *message_p = NULL;
|
||||||
Gtpv1uTunnelDataInd *data_ind_p = NULL;
|
Gtpv1uTunnelDataInd *data_ind_p = NULL;
|
||||||
|
|
||||||
/* Nw-gptv1u stack has processed a PDU. we can forward it to IPV4
|
/* Nw-gptv1u stack has processed a PDU. we can forward it to IPV4
|
||||||
* task for transmission.
|
* task for transmission.
|
||||||
*/
|
*/
|
||||||
/*if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
|
/*if (NW_GTPV1U_OK != nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
|
||||||
buffer, (NwU32T *)&buffer_len)) {
|
buffer, (NwU32T *)&buffer_len)) {
|
||||||
GTPU_ERROR("Error while retrieving T-PDU\n");
|
GTPU_ERROR("Error while retrieving T-PDU\n");
|
||||||
}*/
|
}*/
|
||||||
GTPU_DEBUG("Received TPDU from gtpv1u stack %u with size %d\n",
|
GTPU_DEBUG("Received TPDU from gtpv1u stack %u with size %d\n",
|
||||||
pUlpApi->apiInfo.recvMsgInfo.teid,
|
pUlpApi->apiInfo.recvMsgInfo.teid,
|
||||||
((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen);
|
((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen);
|
||||||
|
|
||||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_TUNNEL_DATA_IND);
|
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_TUNNEL_DATA_IND);
|
||||||
if (message_p == NULL) {
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
data_ind_p = &message_p->ittiMsg.gtpv1uTunnelDataInd;
|
|
||||||
data_ind_p->buffer = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf;
|
|
||||||
data_ind_p->length = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen;
|
|
||||||
data_ind_p->offset = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufOffset;
|
|
||||||
data_ind_p->local_S1u_teid = pUlpApi->apiInfo.recvMsgInfo.teid;
|
|
||||||
if (data_ind_p->buffer == NULL) {
|
|
||||||
GTPU_ERROR("Failed to allocate new buffer\n");
|
|
||||||
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
|
||||||
message_p = NULL;
|
|
||||||
} else {
|
|
||||||
//memcpy(data_ind_p->buffer, buffer, buffer_len);
|
|
||||||
//data_ind_p->length = buffer_len;
|
|
||||||
if (itti_send_msg_to_task(TASK_FW_IP, INSTANCE_DEFAULT, message_p) < 0) {
|
|
||||||
GTPU_ERROR("Failed to send message to task\n");
|
|
||||||
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
|
||||||
message_p = NULL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT:{
|
if (message_p == NULL) {
|
||||||
}
|
return -1;
|
||||||
break;
|
|
||||||
|
|
||||||
default: {
|
|
||||||
GTPU_ERROR("Received undefined UlpApi (%02x) from gtpv1u stack!\n",
|
|
||||||
pUlpApi->apiType);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return NW_GTPV1U_OK;
|
|
||||||
|
data_ind_p = &message_p->ittiMsg.gtpv1uTunnelDataInd;
|
||||||
|
data_ind_p->buffer = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBuf;
|
||||||
|
data_ind_p->length = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufLen;
|
||||||
|
data_ind_p->offset = ((NwGtpv1uMsgT*)pUlpApi->apiInfo.recvMsgInfo.hMsg)->msgBufOffset;
|
||||||
|
data_ind_p->local_S1u_teid = pUlpApi->apiInfo.recvMsgInfo.teid;
|
||||||
|
|
||||||
|
if (data_ind_p->buffer == NULL) {
|
||||||
|
GTPU_ERROR("Failed to allocate new buffer\n");
|
||||||
|
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||||
|
message_p = NULL;
|
||||||
|
} else {
|
||||||
|
//memcpy(data_ind_p->buffer, buffer, buffer_len);
|
||||||
|
//data_ind_p->length = buffer_len;
|
||||||
|
if (itti_send_msg_to_task(TASK_FW_IP, INSTANCE_DEFAULT, message_p) < 0) {
|
||||||
|
GTPU_ERROR("Failed to send message to task\n");
|
||||||
|
itti_free(ITTI_MSG_ORIGIN_ID(message_p), message_p);
|
||||||
|
message_p = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT: {
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
GTPU_ERROR("Received undefined UlpApi (%02x) from gtpv1u stack!\n",
|
||||||
|
pUlpApi->apiType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int gtpv1u_create_s1u_tunnel(Gtpv1uCreateTunnelReq *create_tunnel_reqP)
|
static int gtpv1u_create_s1u_tunnel(Gtpv1uCreateTunnelReq *create_tunnel_reqP)
|
||||||
{
|
{
|
||||||
/* Create a new nw-gtpv1-u stack req using API */
|
/* Create a new nw-gtpv1-u stack req using API */
|
||||||
NwGtpv1uUlpApiT stack_req;
|
NwGtpv1uUlpApiT stack_req;
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
/* Local tunnel end-point identifier */
|
/* Local tunnel end-point identifier */
|
||||||
uint32_t s1u_teid = 0;
|
uint32_t s1u_teid = 0;
|
||||||
gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info = NULL;
|
gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info = NULL;
|
||||||
MessageDef *message_p = NULL;
|
MessageDef *message_p = NULL;
|
||||||
hashtable_rc_t hash_rc;
|
hashtable_rc_t hash_rc;
|
||||||
|
|
||||||
GTPU_DEBUG("Rx GTPV1U_CREATE_TUNNEL_REQ Context %d\n", create_tunnel_reqP->context_teid);
|
GTPU_DEBUG("Rx GTPV1U_CREATE_TUNNEL_REQ Context %d\n", create_tunnel_reqP->context_teid);
|
||||||
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
|
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
|
||||||
|
|
||||||
stack_req.apiType = NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT;
|
stack_req.apiType = NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
s1u_teid = gtpv1u_new_teid();
|
s1u_teid = gtpv1u_new_teid();
|
||||||
GTPU_DEBUG("gtpv1u_create_s1u_tunnel() %u\n", s1u_teid);
|
GTPU_DEBUG("gtpv1u_create_s1u_tunnel() %u\n", s1u_teid);
|
||||||
stack_req.apiInfo.createTunnelEndPointInfo.teid = s1u_teid;
|
stack_req.apiInfo.createTunnelEndPointInfo.teid = s1u_teid;
|
||||||
stack_req.apiInfo.createTunnelEndPointInfo.hUlpSession = 0;
|
stack_req.apiInfo.createTunnelEndPointInfo.hUlpSession = 0;
|
||||||
stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0;
|
stack_req.apiInfo.createTunnelEndPointInfo.hStackSession = 0;
|
||||||
|
|
||||||
rc = nwGtpv1uProcessUlpReq(gtpv1u_sgw_data.gtpv1u_stack, &stack_req);
|
rc = nwGtpv1uProcessUlpReq(gtpv1u_sgw_data.gtpv1u_stack, &stack_req);
|
||||||
GTPU_DEBUG(".\n");
|
GTPU_DEBUG(".\n");
|
||||||
} while (rc != NW_GTPV1U_OK);
|
} while (rc != NW_GTPV1U_OK);
|
||||||
|
|
||||||
gtpv1u_teid2enb_info = malloc (sizeof(gtpv1u_teid2enb_info_t));
|
gtpv1u_teid2enb_info = malloc (sizeof(gtpv1u_teid2enb_info_t));
|
||||||
memset(gtpv1u_teid2enb_info, 0, sizeof(gtpv1u_teid2enb_info_t));
|
memset(gtpv1u_teid2enb_info, 0, sizeof(gtpv1u_teid2enb_info_t));
|
||||||
gtpv1u_teid2enb_info->state = BEARER_IN_CONFIG;
|
gtpv1u_teid2enb_info->state = BEARER_IN_CONFIG;
|
||||||
|
|
||||||
//#warning !!! hack because missing modify session request, so force enb address
|
//#warning !!! hack because missing modify session request, so force enb address
|
||||||
// gtpv1u_teid2enb_info->enb_ip_addr.pdn_type = IPv4;
|
// gtpv1u_teid2enb_info->enb_ip_addr.pdn_type = IPv4;
|
||||||
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[0] = 192;
|
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[0] = 192;
|
||||||
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[1] = 168;
|
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[1] = 168;
|
||||||
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[2] = 1;
|
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[2] = 1;
|
||||||
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[3] = 2;
|
// gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address[3] = 2;
|
||||||
|
|
||||||
|
|
||||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_CREATE_TUNNEL_RESP);
|
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_CREATE_TUNNEL_RESP);
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.S1u_teid = s1u_teid;
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.S1u_teid = s1u_teid;
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.context_teid = create_tunnel_reqP->context_teid;
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.context_teid = create_tunnel_reqP->context_teid;
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.eps_bearer_id = create_tunnel_reqP->eps_bearer_id;
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.eps_bearer_id = create_tunnel_reqP->eps_bearer_id;
|
||||||
|
|
||||||
hash_rc = hashtable_is_key_exists(gtpv1u_sgw_data.S1U_mapping, s1u_teid);
|
hash_rc = hashtable_is_key_exists(gtpv1u_sgw_data.S1U_mapping, s1u_teid);
|
||||||
|
|
||||||
if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
|
if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
|
||||||
hash_rc = hashtable_insert(gtpv1u_sgw_data.S1U_mapping, s1u_teid, gtpv1u_teid2enb_info);
|
hash_rc = hashtable_insert(gtpv1u_sgw_data.S1U_mapping, s1u_teid, gtpv1u_teid2enb_info);
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.status = 0;
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.status = 0;
|
||||||
} else {
|
} else {
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.status = 0xFF;
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.status = 0xFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
GTPU_DEBUG("Tx GTPV1U_CREATE_TUNNEL_RESP Context %u teid %u eps bearer id %u status %d\n",
|
GTPU_DEBUG("Tx GTPV1U_CREATE_TUNNEL_RESP Context %u teid %u eps bearer id %u status %d\n",
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.context_teid,
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.context_teid,
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.S1u_teid,
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.S1u_teid,
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.eps_bearer_id,
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.eps_bearer_id,
|
||||||
message_p->ittiMsg.gtpv1uCreateTunnelResp.status);
|
message_p->ittiMsg.gtpv1uCreateTunnelResp.status);
|
||||||
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static int gtpv1u_delete_s1u_tunnel(Teid_t context_teidP, Teid_t S1U_teidP)
|
static int gtpv1u_delete_s1u_tunnel(Teid_t context_teidP, Teid_t S1U_teidP)
|
||||||
{
|
{
|
||||||
/* Local tunnel end-point identifier */
|
/* Local tunnel end-point identifier */
|
||||||
MessageDef *message_p;
|
MessageDef *message_p;
|
||||||
|
|
||||||
GTPU_DEBUG("Rx GTPV1U_DELETE_TUNNEL Context %u S1U teid %u\n", context_teidP, S1U_teidP);
|
GTPU_DEBUG("Rx GTPV1U_DELETE_TUNNEL Context %u S1U teid %u\n", context_teidP, S1U_teidP);
|
||||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_DELETE_TUNNEL_RESP);
|
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_DELETE_TUNNEL_RESP);
|
||||||
|
|
||||||
message_p->ittiMsg.gtpv1uDeleteTunnelResp.S1u_teid = S1U_teidP;
|
message_p->ittiMsg.gtpv1uDeleteTunnelResp.S1u_teid = S1U_teidP;
|
||||||
message_p->ittiMsg.gtpv1uDeleteTunnelResp.context_teid = context_teidP;
|
message_p->ittiMsg.gtpv1uDeleteTunnelResp.context_teid = context_teidP;
|
||||||
|
|
||||||
if (hashtable_remove(gtpv1u_sgw_data.S1U_mapping, S1U_teidP) == HASH_TABLE_OK ) {
|
if (hashtable_remove(gtpv1u_sgw_data.S1U_mapping, S1U_teidP) == HASH_TABLE_OK ) {
|
||||||
message_p->ittiMsg.gtpv1uDeleteTunnelResp.status = 0;
|
message_p->ittiMsg.gtpv1uDeleteTunnelResp.status = 0;
|
||||||
} else {
|
} else {
|
||||||
message_p->ittiMsg.gtpv1uDeleteTunnelResp.status = -1;
|
message_p->ittiMsg.gtpv1uDeleteTunnelResp.status = -1;
|
||||||
}
|
}
|
||||||
GTPU_DEBUG("Tx SGW_S1U_ENDPOINT_CREATED Context %u teid %u status %d\n", context_teidP, S1U_teidP, message_p->ittiMsg.gtpv1uDeleteTunnelResp.status);
|
|
||||||
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
GTPU_DEBUG("Tx SGW_S1U_ENDPOINT_CREATED Context %u teid %u status %d\n", context_teidP, S1U_teidP, message_p->ittiMsg.gtpv1uDeleteTunnelResp.status);
|
||||||
|
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int gtpv1u_update_s1u_tunnel(Gtpv1uUpdateTunnelReq *reqP)
|
static int gtpv1u_update_s1u_tunnel(Gtpv1uUpdateTunnelReq *reqP)
|
||||||
{
|
{
|
||||||
hashtable_rc_t hash_rc;
|
hashtable_rc_t hash_rc;
|
||||||
gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info;
|
gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info;
|
||||||
MessageDef *message_p;
|
MessageDef *message_p;
|
||||||
|
|
||||||
GTPU_DEBUG("Rx GTPV1U_UPDATE_TUNNEL_REQ Context %u, S-GW S1U teid %u, eNB S1U teid %u\n",
|
GTPU_DEBUG("Rx GTPV1U_UPDATE_TUNNEL_REQ Context %u, S-GW S1U teid %u, eNB S1U teid %u\n",
|
||||||
reqP->context_teid,
|
reqP->context_teid,
|
||||||
reqP->sgw_S1u_teid,
|
reqP->sgw_S1u_teid,
|
||||||
reqP->enb_S1u_teid);
|
reqP->enb_S1u_teid);
|
||||||
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_UPDATE_TUNNEL_RESP);
|
message_p = itti_alloc_new_message(TASK_GTPV1_U, GTPV1U_UPDATE_TUNNEL_RESP);
|
||||||
|
|
||||||
hash_rc = hashtable_get(gtpv1u_sgw_data.S1U_mapping, reqP->sgw_S1u_teid, (void**)>pv1u_teid2enb_info);
|
hash_rc = hashtable_get(gtpv1u_sgw_data.S1U_mapping, reqP->sgw_S1u_teid, (void**)>pv1u_teid2enb_info);
|
||||||
|
|
||||||
if (hash_rc == HASH_TABLE_OK) {
|
if (hash_rc == HASH_TABLE_OK) {
|
||||||
gtpv1u_teid2enb_info->teid_enb = reqP->enb_S1u_teid;
|
gtpv1u_teid2enb_info->teid_enb = reqP->enb_S1u_teid;
|
||||||
gtpv1u_teid2enb_info->enb_ip_addr = reqP->enb_ip_address_for_S1u;
|
gtpv1u_teid2enb_info->enb_ip_addr = reqP->enb_ip_address_for_S1u;
|
||||||
gtpv1u_teid2enb_info->state = BEARER_UP;
|
gtpv1u_teid2enb_info->state = BEARER_UP;
|
||||||
gtpv1u_teid2enb_info->port = GTPV1U_UDP_PORT;
|
gtpv1u_teid2enb_info->port = GTPV1U_UDP_PORT;
|
||||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.status = 0; ///< Status (Failed = 0xFF or Success = 0x0)
|
message_p->ittiMsg.gtpv1uUpdateTunnelResp.status = 0; ///< Status (Failed = 0xFF or Success = 0x0)
|
||||||
} else {
|
} else {
|
||||||
GTPU_ERROR("Mapping not found\n");
|
GTPU_ERROR("Mapping not found\n");
|
||||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.status = 0xFF; ///< Status (Failed = 0xFF or Success = 0x0)
|
message_p->ittiMsg.gtpv1uUpdateTunnelResp.status = 0xFF; ///< Status (Failed = 0xFF or Success = 0x0)
|
||||||
}
|
}
|
||||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.context_teid = reqP->context_teid;
|
|
||||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.sgw_S1u_teid = reqP->sgw_S1u_teid;
|
message_p->ittiMsg.gtpv1uUpdateTunnelResp.context_teid = reqP->context_teid;
|
||||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.enb_S1u_teid = reqP->enb_S1u_teid;
|
message_p->ittiMsg.gtpv1uUpdateTunnelResp.sgw_S1u_teid = reqP->sgw_S1u_teid;
|
||||||
message_p->ittiMsg.gtpv1uUpdateTunnelResp.eps_bearer_id = reqP->eps_bearer_id;
|
message_p->ittiMsg.gtpv1uUpdateTunnelResp.enb_S1u_teid = reqP->enb_S1u_teid;
|
||||||
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
message_p->ittiMsg.gtpv1uUpdateTunnelResp.eps_bearer_id = reqP->eps_bearer_id;
|
||||||
|
return itti_send_msg_to_task(TASK_SPGW_APP, INSTANCE_DEFAULT, message_p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static NwGtpv1uRcT gtpv1u_start_timer_wrapper(
|
static NwGtpv1uRcT gtpv1u_start_timer_wrapper(
|
||||||
NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||||
NwU32T timeoutSec,
|
NwU32T timeoutSec,
|
||||||
NwU32T timeoutUsec,
|
NwU32T timeoutUsec,
|
||||||
NwU32T tmrType,
|
NwU32T tmrType,
|
||||||
void *timeoutArg,
|
void *timeoutArg,
|
||||||
NwGtpv1uTimerHandleT *hTmr)
|
NwGtpv1uTimerHandleT *hTmr)
|
||||||
{
|
{
|
||||||
|
|
||||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||||
long timer_id;
|
long timer_id;
|
||||||
|
|
||||||
if (tmrType == NW_GTPV1U_TMR_TYPE_ONE_SHOT) {
|
if (tmrType == NW_GTPV1U_TMR_TYPE_ONE_SHOT) {
|
||||||
timer_setup(timeoutSec,
|
timer_setup(timeoutSec,
|
||||||
timeoutUsec,
|
timeoutUsec,
|
||||||
TASK_GTPV1_U,
|
TASK_GTPV1_U,
|
||||||
INSTANCE_DEFAULT,
|
INSTANCE_DEFAULT,
|
||||||
TIMER_ONE_SHOT,
|
TIMER_ONE_SHOT,
|
||||||
timeoutArg,
|
timeoutArg,
|
||||||
&timer_id);
|
&timer_id);
|
||||||
} else {
|
} else {
|
||||||
timer_setup(timeoutSec,
|
timer_setup(timeoutSec,
|
||||||
timeoutUsec,
|
timeoutUsec,
|
||||||
TASK_GTPV1_U,
|
TASK_GTPV1_U,
|
||||||
INSTANCE_DEFAULT,
|
INSTANCE_DEFAULT,
|
||||||
TIMER_PERIODIC,
|
TIMER_PERIODIC,
|
||||||
timeoutArg,
|
timeoutArg,
|
||||||
&timer_id);
|
&timer_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NwGtpv1uRcT gtpv1u_stop_timer_wrapper(
|
static NwGtpv1uRcT gtpv1u_stop_timer_wrapper(
|
||||||
NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||||
NwGtpv1uTimerHandleT hTmr)
|
NwGtpv1uTimerHandleT hTmr)
|
||||||
{
|
{
|
||||||
|
|
||||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *gtpv1u_thread(void *args)
|
static void *gtpv1u_thread(void *args)
|
||||||
{
|
{
|
||||||
itti_mark_task_ready(TASK_GTPV1_U);
|
itti_mark_task_ready(TASK_GTPV1_U);
|
||||||
while(1) {
|
|
||||||
/* Trying to fetch a message from the message queue.
|
while(1) {
|
||||||
* If the queue is empty, this function will block till a
|
/* Trying to fetch a message from the message queue.
|
||||||
* message is sent to the task.
|
* If the queue is empty, this function will block till a
|
||||||
*/
|
* message is sent to the task.
|
||||||
MessageDef *received_message_p = NULL;
|
*/
|
||||||
itti_receive_msg(TASK_GTPV1_U, &received_message_p);
|
MessageDef *received_message_p = NULL;
|
||||||
DevAssert(received_message_p != NULL);
|
itti_receive_msg(TASK_GTPV1_U, &received_message_p);
|
||||||
|
DevAssert(received_message_p != NULL);
|
||||||
|
|
||||||
#if !defined(ENABLE_USE_GTPU_IN_KERNEL)
|
#if !defined(ENABLE_USE_GTPU_IN_KERNEL)
|
||||||
switch (ITTI_MSG_ID(received_message_p))
|
|
||||||
{
|
|
||||||
case GTPV1U_CREATE_TUNNEL_REQ: {
|
|
||||||
gtpv1u_create_s1u_tunnel(&received_message_p->ittiMsg.gtpv1uCreateTunnelReq);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case GTPV1U_DELETE_TUNNEL_REQ: {
|
switch (ITTI_MSG_ID(received_message_p)) {
|
||||||
gtpv1u_delete_s1u_tunnel(received_message_p->ittiMsg.gtpv1uDeleteTunnelReq.context_teid, received_message_p->ittiMsg.gtpv1uDeleteTunnelReq.S1u_teid);
|
case GTPV1U_CREATE_TUNNEL_REQ: {
|
||||||
}
|
gtpv1u_create_s1u_tunnel(&received_message_p->ittiMsg.gtpv1uCreateTunnelReq);
|
||||||
break;
|
|
||||||
|
|
||||||
case GTPV1U_UPDATE_TUNNEL_REQ: {
|
|
||||||
gtpv1u_update_s1u_tunnel(&received_message_p->ittiMsg.gtpv1uUpdateTunnelReq);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DATA COMING FROM UDP
|
|
||||||
case UDP_DATA_IND: {
|
|
||||||
udp_data_ind_t *udp_data_ind_p;
|
|
||||||
udp_data_ind_p = &received_message_p->ittiMsg.udp_data_ind;
|
|
||||||
nwGtpv1uProcessUdpReq(gtpv1u_sgw_data.gtpv1u_stack,
|
|
||||||
udp_data_ind_p->buffer,
|
|
||||||
udp_data_ind_p->buffer_length,
|
|
||||||
udp_data_ind_p->peer_port,
|
|
||||||
udp_data_ind_p->peer_address);
|
|
||||||
//itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
// DATA TO BE SENT TO UDP
|
|
||||||
case GTPV1U_TUNNEL_DATA_REQ: {
|
|
||||||
Gtpv1uTunnelDataReq *data_req_p = NULL;
|
|
||||||
NwGtpv1uUlpApiT stack_req;
|
|
||||||
NwGtpv1uRcT rc;
|
|
||||||
hashtable_rc_t hash_rc;
|
|
||||||
gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info = NULL;
|
|
||||||
|
|
||||||
data_req_p = &received_message_p->ittiMsg.gtpv1uTunnelDataReq;
|
|
||||||
|
|
||||||
//GTPU_DEBUG("-- GTPV1U_TUNNEL_DATA_REQ -----------------------------------------------------\n%s :\n",
|
|
||||||
// __FUNCTION__);
|
|
||||||
//gtpu_print_hex_octets(data_req_p->buffer, data_req_p->length);
|
|
||||||
|
|
||||||
|
|
||||||
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
|
|
||||||
|
|
||||||
hash_rc = hashtable_get(gtpv1u_sgw_data.S1U_mapping, (uint64_t)data_req_p->local_S1u_teid, (void**)>pv1u_teid2enb_info);
|
|
||||||
|
|
||||||
if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
|
|
||||||
GTPU_ERROR("nwGtpv1uProcessUlpReq failed: while getting teid %u in hashtable S1U_mapping\n", data_req_p->local_S1u_teid);
|
|
||||||
} else {
|
|
||||||
stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU;
|
|
||||||
//stack_req.apiInfo.sendtoInfo.teid = data_req_p->local_S1u_teid;
|
|
||||||
stack_req.apiInfo.sendtoInfo.teid = gtpv1u_teid2enb_info->teid_enb;
|
|
||||||
BUFFER_TO_NwU32T(gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address, stack_req.apiInfo.sendtoInfo.ipAddr);
|
|
||||||
|
|
||||||
/*nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
|
||||||
NW_IN NwU32T teid,
|
|
||||||
NW_IN NwU8T seqNumFlag,
|
|
||||||
NW_IN NwU16T seqNum,
|
|
||||||
NW_IN NwU8T *tpdu,
|
|
||||||
NW_IN NwU16T tpduLength,
|
|
||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg)*/
|
|
||||||
GTPU_DEBUG("GTPV1U_TUNNEL_DATA_REQ seq num %d %d bytes\n",
|
|
||||||
gtpv1u_sgw_data.seq_num,
|
|
||||||
data_req_p->length);
|
|
||||||
rc = nwGtpv1uGpduMsgNew(gtpv1u_sgw_data.gtpv1u_stack,
|
|
||||||
00,// TO DO bearer_p->port, but not needed when looking at processing
|
|
||||||
NW_FALSE,
|
|
||||||
gtpv1u_sgw_data.seq_num++,
|
|
||||||
data_req_p->buffer,
|
|
||||||
data_req_p->length,
|
|
||||||
data_req_p->offset,
|
|
||||||
&(stack_req.apiInfo.sendtoInfo.hMsg));
|
|
||||||
|
|
||||||
if (rc != NW_GTPV1U_OK) {
|
|
||||||
GTPU_ERROR("nwGtpv1uGpduMsgNew failed: 0x%x\n", rc);
|
|
||||||
} else {
|
|
||||||
rc = nwGtpv1uProcessUlpReq(gtpv1u_sgw_data.gtpv1u_stack, &stack_req);
|
|
||||||
if (rc != NW_GTPV1U_OK) {
|
|
||||||
GTPU_ERROR("nwGtpv1uProcessUlpReq failed: 0x%x\n", rc);
|
|
||||||
}
|
|
||||||
rc = nwGtpv1uMsgDelete(gtpv1u_sgw_data.gtpv1u_stack,
|
|
||||||
stack_req.apiInfo.sendtoInfo.hMsg);
|
|
||||||
if (rc != NW_GTPV1U_OK) {
|
|
||||||
GTPU_ERROR("nwGtpv1uMsgDelete failed: 0x%x\n", rc);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* Buffer is still needed, do not free it */
|
|
||||||
//itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TERMINATE_MESSAGE: {
|
|
||||||
itti_exit_task();
|
|
||||||
} break;
|
|
||||||
case TIMER_HAS_EXPIRED:
|
|
||||||
nwGtpv1uProcessTimeout(&received_message_p->ittiMsg.timer_has_expired.arg);
|
|
||||||
break;
|
|
||||||
default: {
|
|
||||||
GTPU_ERROR("Unkwnon message ID %d:%s\n",
|
|
||||||
ITTI_MSG_ID(received_message_p),
|
|
||||||
ITTI_MSG_NAME(received_message_p));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p);
|
|
||||||
received_message_p = NULL;
|
|
||||||
}
|
}
|
||||||
return NULL;
|
break;
|
||||||
|
|
||||||
|
case GTPV1U_DELETE_TUNNEL_REQ: {
|
||||||
|
gtpv1u_delete_s1u_tunnel(received_message_p->ittiMsg.gtpv1uDeleteTunnelReq.context_teid, received_message_p->ittiMsg.gtpv1uDeleteTunnelReq.S1u_teid);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case GTPV1U_UPDATE_TUNNEL_REQ: {
|
||||||
|
gtpv1u_update_s1u_tunnel(&received_message_p->ittiMsg.gtpv1uUpdateTunnelReq);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DATA COMING FROM UDP
|
||||||
|
case UDP_DATA_IND: {
|
||||||
|
udp_data_ind_t *udp_data_ind_p;
|
||||||
|
udp_data_ind_p = &received_message_p->ittiMsg.udp_data_ind;
|
||||||
|
nwGtpv1uProcessUdpReq(gtpv1u_sgw_data.gtpv1u_stack,
|
||||||
|
udp_data_ind_p->buffer,
|
||||||
|
udp_data_ind_p->buffer_length,
|
||||||
|
udp_data_ind_p->peer_port,
|
||||||
|
udp_data_ind_p->peer_address);
|
||||||
|
//itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), udp_data_ind_p->buffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
// DATA TO BE SENT TO UDP
|
||||||
|
case GTPV1U_TUNNEL_DATA_REQ: {
|
||||||
|
Gtpv1uTunnelDataReq *data_req_p = NULL;
|
||||||
|
NwGtpv1uUlpApiT stack_req;
|
||||||
|
NwGtpv1uRcT rc;
|
||||||
|
hashtable_rc_t hash_rc;
|
||||||
|
gtpv1u_teid2enb_info_t *gtpv1u_teid2enb_info = NULL;
|
||||||
|
|
||||||
|
data_req_p = &received_message_p->ittiMsg.gtpv1uTunnelDataReq;
|
||||||
|
|
||||||
|
//GTPU_DEBUG("-- GTPV1U_TUNNEL_DATA_REQ -----------------------------------------------------\n%s :\n",
|
||||||
|
// __FUNCTION__);
|
||||||
|
//gtpu_print_hex_octets(data_req_p->buffer, data_req_p->length);
|
||||||
|
|
||||||
|
|
||||||
|
memset(&stack_req, 0, sizeof(NwGtpv1uUlpApiT));
|
||||||
|
|
||||||
|
hash_rc = hashtable_get(gtpv1u_sgw_data.S1U_mapping, (uint64_t)data_req_p->local_S1u_teid, (void**)>pv1u_teid2enb_info);
|
||||||
|
|
||||||
|
if (hash_rc == HASH_TABLE_KEY_NOT_EXISTS) {
|
||||||
|
GTPU_ERROR("nwGtpv1uProcessUlpReq failed: while getting teid %u in hashtable S1U_mapping\n", data_req_p->local_S1u_teid);
|
||||||
|
} else {
|
||||||
|
stack_req.apiType = NW_GTPV1U_ULP_API_SEND_TPDU;
|
||||||
|
//stack_req.apiInfo.sendtoInfo.teid = data_req_p->local_S1u_teid;
|
||||||
|
stack_req.apiInfo.sendtoInfo.teid = gtpv1u_teid2enb_info->teid_enb;
|
||||||
|
BUFFER_TO_NwU32T(gtpv1u_teid2enb_info->enb_ip_addr.address.ipv4_address, stack_req.apiInfo.sendtoInfo.ipAddr);
|
||||||
|
|
||||||
|
/*nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
||||||
|
NW_IN NwU32T teid,
|
||||||
|
NW_IN NwU8T seqNumFlag,
|
||||||
|
NW_IN NwU16T seqNum,
|
||||||
|
NW_IN NwU8T *tpdu,
|
||||||
|
NW_IN NwU16T tpduLength,
|
||||||
|
NW_OUT NwGtpv1uMsgHandleT *phMsg)*/
|
||||||
|
GTPU_DEBUG("GTPV1U_TUNNEL_DATA_REQ seq num %d %d bytes\n",
|
||||||
|
gtpv1u_sgw_data.seq_num,
|
||||||
|
data_req_p->length);
|
||||||
|
rc = nwGtpv1uGpduMsgNew(gtpv1u_sgw_data.gtpv1u_stack,
|
||||||
|
00,// TO DO bearer_p->port, but not needed when looking at processing
|
||||||
|
NW_FALSE,
|
||||||
|
gtpv1u_sgw_data.seq_num++,
|
||||||
|
data_req_p->buffer,
|
||||||
|
data_req_p->length,
|
||||||
|
data_req_p->offset,
|
||||||
|
&(stack_req.apiInfo.sendtoInfo.hMsg));
|
||||||
|
|
||||||
|
if (rc != NW_GTPV1U_OK) {
|
||||||
|
GTPU_ERROR("nwGtpv1uGpduMsgNew failed: 0x%x\n", rc);
|
||||||
|
} else {
|
||||||
|
rc = nwGtpv1uProcessUlpReq(gtpv1u_sgw_data.gtpv1u_stack, &stack_req);
|
||||||
|
|
||||||
|
if (rc != NW_GTPV1U_OK) {
|
||||||
|
GTPU_ERROR("nwGtpv1uProcessUlpReq failed: 0x%x\n", rc);
|
||||||
|
}
|
||||||
|
|
||||||
|
rc = nwGtpv1uMsgDelete(gtpv1u_sgw_data.gtpv1u_stack,
|
||||||
|
stack_req.apiInfo.sendtoInfo.hMsg);
|
||||||
|
|
||||||
|
if (rc != NW_GTPV1U_OK) {
|
||||||
|
GTPU_ERROR("nwGtpv1uMsgDelete failed: 0x%x\n", rc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Buffer is still needed, do not free it */
|
||||||
|
//itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), data_req_p->buffer);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TERMINATE_MESSAGE: {
|
||||||
|
itti_exit_task();
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case TIMER_HAS_EXPIRED:
|
||||||
|
nwGtpv1uProcessTimeout(&received_message_p->ittiMsg.timer_has_expired.arg);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
GTPU_ERROR("Unkwnon message ID %d:%s\n",
|
||||||
|
ITTI_MSG_ID(received_message_p),
|
||||||
|
ITTI_MSG_NAME(received_message_p));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
itti_free(ITTI_MSG_ORIGIN_ID(received_message_p), received_message_p);
|
||||||
|
received_message_p = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int gtpv1u_init(const mme_config_t *mme_config_p)
|
int gtpv1u_init(const mme_config_t *mme_config_p)
|
||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
NwGtpv1uRcT rc = 0;
|
NwGtpv1uRcT rc = 0;
|
||||||
NwGtpv1uUlpEntityT ulp;
|
NwGtpv1uUlpEntityT ulp;
|
||||||
NwGtpv1uUdpEntityT udp;
|
NwGtpv1uUdpEntityT udp;
|
||||||
NwGtpv1uLogMgrEntityT log;
|
NwGtpv1uLogMgrEntityT log;
|
||||||
NwGtpv1uTimerMgrEntityT tmr;
|
NwGtpv1uTimerMgrEntityT tmr;
|
||||||
|
|
||||||
GTPU_DEBUG("Initializing GTPV1U interface\n");
|
GTPU_DEBUG("Initializing GTPV1U interface\n");
|
||||||
|
|
||||||
memset(>pv1u_sgw_data, 0, sizeof(gtpv1u_sgw_data));
|
memset(>pv1u_sgw_data, 0, sizeof(gtpv1u_sgw_data));
|
||||||
|
|
||||||
gtpv1u_sgw_data.sgw_ip_address_for_S1u_S12_S4_up = mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up;
|
gtpv1u_sgw_data.sgw_ip_address_for_S1u_S12_S4_up = mme_config_p->ipv4.sgw_ip_address_for_S1u_S12_S4_up;
|
||||||
|
|
||||||
#if !defined(ENABLE_USE_GTPU_IN_KERNEL)
|
#if !defined(ENABLE_USE_GTPU_IN_KERNEL)
|
||||||
gtpv1u_sgw_data.S1U_mapping = hashtable_create (8192, NULL, NULL);
|
gtpv1u_sgw_data.S1U_mapping = hashtable_create (8192, NULL, NULL);
|
||||||
if (gtpv1u_sgw_data.S1U_mapping == NULL) {
|
|
||||||
perror("hashtable_create");
|
|
||||||
GTPU_ERROR("Initializing TASK_GTPV1_U task interface: ERROR\n");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initializing GTPv1-U stack */
|
if (gtpv1u_sgw_data.S1U_mapping == NULL) {
|
||||||
if ((rc = nwGtpv1uInitialize(>pv1u_sgw_data.gtpv1u_stack)) != NW_GTPV1U_OK) {
|
perror("hashtable_create");
|
||||||
GTPU_ERROR("Failed to setup nwGtpv1u stack %x\n", rc);
|
GTPU_ERROR("Initializing TASK_GTPV1_U task interface: ERROR\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((rc = nwGtpv1uSetLogLevel(gtpv1u_sgw_data.gtpv1u_stack,
|
/* Initializing GTPv1-U stack */
|
||||||
NW_LOG_LEVEL_DEBG)) != NW_GTPV1U_OK) {
|
if ((rc = nwGtpv1uInitialize(>pv1u_sgw_data.gtpv1u_stack)) != NW_GTPV1U_OK) {
|
||||||
GTPU_ERROR("Failed to setup loglevel for stack %x\n", rc);
|
GTPU_ERROR("Failed to setup nwGtpv1u stack %x\n", rc);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set the ULP API callback. Called once message have been processed by the
|
if ((rc = nwGtpv1uSetLogLevel(gtpv1u_sgw_data.gtpv1u_stack,
|
||||||
* nw-gtpv1u stack.
|
NW_LOG_LEVEL_DEBG)) != NW_GTPV1U_OK) {
|
||||||
*/
|
GTPU_ERROR("Failed to setup loglevel for stack %x\n", rc);
|
||||||
ulp.ulpReqCallback = gtpv1u_process_stack_req;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((rc = nwGtpv1uSetUlpEntity(gtpv1u_sgw_data.gtpv1u_stack, &ulp)) != NW_GTPV1U_OK) {
|
/* Set the ULP API callback. Called once message have been processed by the
|
||||||
GTPU_ERROR("nwGtpv1uSetUlpEntity: %x", rc);
|
* nw-gtpv1u stack.
|
||||||
return -1;
|
*/
|
||||||
}
|
ulp.ulpReqCallback = gtpv1u_process_stack_req;
|
||||||
|
|
||||||
/* nw-gtpv1u stack requires an udp callback to send data over UDP.
|
if ((rc = nwGtpv1uSetUlpEntity(gtpv1u_sgw_data.gtpv1u_stack, &ulp)) != NW_GTPV1U_OK) {
|
||||||
* We provide a wrapper to UDP task.
|
GTPU_ERROR("nwGtpv1uSetUlpEntity: %x", rc);
|
||||||
*/
|
return -1;
|
||||||
udp.udpDataReqCallback = gtpv1u_send_udp_msg;
|
}
|
||||||
|
|
||||||
if ((rc = nwGtpv1uSetUdpEntity(gtpv1u_sgw_data.gtpv1u_stack, &udp)) != NW_GTPV1U_OK) {
|
/* nw-gtpv1u stack requires an udp callback to send data over UDP.
|
||||||
GTPU_ERROR("nwGtpv1uSetUdpEntity: %x", rc);
|
* We provide a wrapper to UDP task.
|
||||||
return -1;
|
*/
|
||||||
}
|
udp.udpDataReqCallback = gtpv1u_send_udp_msg;
|
||||||
|
|
||||||
log.logReqCallback = gtpv1u_log_request;
|
if ((rc = nwGtpv1uSetUdpEntity(gtpv1u_sgw_data.gtpv1u_stack, &udp)) != NW_GTPV1U_OK) {
|
||||||
|
GTPU_ERROR("nwGtpv1uSetUdpEntity: %x", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((rc = nwGtpv1uSetLogMgrEntity(gtpv1u_sgw_data.gtpv1u_stack, &log)) != NW_GTPV1U_OK) {
|
log.logReqCallback = gtpv1u_log_request;
|
||||||
GTPU_ERROR("nwGtpv1uSetLogMgrEntity: %x", rc);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Timer interface is more complicated as both wrappers doesn't send a message
|
if ((rc = nwGtpv1uSetLogMgrEntity(gtpv1u_sgw_data.gtpv1u_stack, &log)) != NW_GTPV1U_OK) {
|
||||||
* to the timer task but call the timer API functions start/stop timer.
|
GTPU_ERROR("nwGtpv1uSetLogMgrEntity: %x", rc);
|
||||||
*/
|
return -1;
|
||||||
tmr.tmrMgrHandle = 0;
|
}
|
||||||
tmr.tmrStartCallback = gtpv1u_start_timer_wrapper;
|
|
||||||
tmr.tmrStopCallback = gtpv1u_stop_timer_wrapper;
|
/* Timer interface is more complicated as both wrappers doesn't send a message
|
||||||
|
* to the timer task but call the timer API functions start/stop timer.
|
||||||
|
*/
|
||||||
|
tmr.tmrMgrHandle = 0;
|
||||||
|
tmr.tmrStartCallback = gtpv1u_start_timer_wrapper;
|
||||||
|
tmr.tmrStopCallback = gtpv1u_stop_timer_wrapper;
|
||||||
|
|
||||||
|
if ((rc = nwGtpv1uSetTimerMgrEntity(gtpv1u_sgw_data.gtpv1u_stack, &tmr)) != NW_GTPV1U_OK) {
|
||||||
|
GTPU_ERROR("nwGtpv1uSetTimerMgrEntity: %x", rc);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if ((rc = nwGtpv1uSetTimerMgrEntity(gtpv1u_sgw_data.gtpv1u_stack, &tmr)) != NW_GTPV1U_OK) {
|
|
||||||
GTPU_ERROR("nwGtpv1uSetTimerMgrEntity: %x", rc);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
if (itti_create_task(TASK_GTPV1_U, >pv1u_thread, NULL) < 0) {
|
|
||||||
GTPU_ERROR("gtpv1u phtread_create: %s", strerror(errno));
|
if (itti_create_task(TASK_GTPV1_U, >pv1u_thread, NULL) < 0) {
|
||||||
return -1;
|
GTPU_ERROR("gtpv1u phtread_create: %s", strerror(errno));
|
||||||
}
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
#if !defined(ENABLE_USE_GTPU_IN_KERNEL)
|
#if !defined(ENABLE_USE_GTPU_IN_KERNEL)
|
||||||
|
|
||||||
ret = gtpv1u_send_init_udp(mme_config_p->gtpv1u_config.port_number);
|
ret = gtpv1u_send_init_udp(mme_config_p->gtpv1u_config.port_number);
|
||||||
if (ret < 0) {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
GTPU_DEBUG("Initializing GTPV1U interface: DONE\n");
|
|
||||||
|
|
||||||
|
if (ret < 0) {
|
||||||
return ret;
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
GTPU_DEBUG("Initializing GTPV1U interface: DONE\n");
|
||||||
|
|
||||||
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -46,9 +46,9 @@ static uint32_t g_gtpv1u_teid = 0;
|
|||||||
uint32_t gtpv1u_new_teid(void)
|
uint32_t gtpv1u_new_teid(void)
|
||||||
{
|
{
|
||||||
#ifdef GTPV1U_LINEAR_TEID_ALLOCATION
|
#ifdef GTPV1U_LINEAR_TEID_ALLOCATION
|
||||||
g_gtpv1u_teid = g_gtpv1u_teid + 1;
|
g_gtpv1u_teid = g_gtpv1u_teid + 1;
|
||||||
return g_gtpv1u_teid;
|
return g_gtpv1u_teid;
|
||||||
#else
|
#else
|
||||||
return random() + random() % (RAND_MAX - 1) + 1;
|
return random() + random() % (RAND_MAX - 1) + 1;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 u *
|
* n w - g t p v 2 u *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -37,8 +37,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "NwLog.h"
|
#include "NwLog.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv1uLog.h
|
* @file NwGtpv1uLog.h
|
||||||
* @brief This header contains logging related definitions.
|
* @brief This header contains logging related definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 u *
|
* n w - g t p v 2 u *
|
||||||
* n w - g t p v 2 u *
|
* n w - g t p v 2 u *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -44,9 +44,9 @@
|
|||||||
#include "NwGtpv1uMsg.h"
|
#include "NwGtpv1uMsg.h"
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv1uPrivate.h
|
* @file NwGtpv1uPrivate.h
|
||||||
* @brief This header file contains nw-gtpv1u private definitions not to be
|
* @brief This header file contains nw-gtpv1u private definitions not to be
|
||||||
* exposed to user application.
|
* exposed to user application.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -78,8 +78,7 @@ extern "C" {
|
|||||||
* gtpv1u stack class definition
|
* gtpv1u stack class definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv1uStack
|
typedef struct NwGtpv1uStack {
|
||||||
{
|
|
||||||
NwU32T id;
|
NwU32T id;
|
||||||
NwU32T seq;
|
NwU32T seq;
|
||||||
NwGtpv1uUlpEntityT ulp;
|
NwGtpv1uUlpEntityT ulp;
|
||||||
@@ -92,14 +91,13 @@ typedef struct NwGtpv1uStack
|
|||||||
RB_HEAD( NwGtpv1uOutstandingRxSeqNumTrxnMap, NwGtpv1uTrxn) outstandingRxSeqNumMap;
|
RB_HEAD( NwGtpv1uOutstandingRxSeqNumTrxnMap, NwGtpv1uTrxn) outstandingRxSeqNumMap;
|
||||||
RB_HEAD(NwGtpv1uTunnelEndPointTMap, NwGtpv1uTunnelEndPoint) sessionMap;
|
RB_HEAD(NwGtpv1uTunnelEndPointTMap, NwGtpv1uTunnelEndPoint) sessionMap;
|
||||||
RB_HEAD(NwGtpv1uTunnelEndPointIdentifierMap, NwGtpv1uTunnelEndPoint) teidMap;
|
RB_HEAD(NwGtpv1uTunnelEndPointIdentifierMap, NwGtpv1uTunnelEndPoint) teidMap;
|
||||||
} NwGtpv1uStackT;
|
} NwGtpv1uStackT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GTP Tunnel End Point class definition
|
* GTP Tunnel End Point class definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv1uTunnelEndPoint
|
typedef struct NwGtpv1uTunnelEndPoint {
|
||||||
{
|
|
||||||
NwU32T teid; /**< Gtpu Tunnel End Point Identifier */
|
NwU32T teid; /**< Gtpu Tunnel End Point Identifier */
|
||||||
NwU32T peerAddr; /**< Peer IP address for the session */
|
NwU32T peerAddr; /**< Peer IP address for the session */
|
||||||
NwGtpv1uStackT* pStack; /**< Pointer to the parent stack */
|
NwGtpv1uStackT* pStack; /**< Pointer to the parent stack */
|
||||||
@@ -110,15 +108,14 @@ typedef struct NwGtpv1uTunnelEndPoint
|
|||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* Timeout Info Type Definition
|
* Timeout Info Type Definition
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtpv1u timeout info
|
* gtpv1u timeout info
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv1uTimeoutInfo
|
typedef struct NwGtpv1uTimeoutInfo {
|
||||||
{
|
|
||||||
NwGtpv1uStackHandleT hStack;
|
NwGtpv1uStackHandleT hStack;
|
||||||
void* timeoutArg;
|
void* timeoutArg;
|
||||||
NwGtpv1uRcT (*timeoutCallbackFunc)(void*);
|
NwGtpv1uRcT (*timeoutCallbackFunc)(void*);
|
||||||
@@ -129,7 +126,7 @@ typedef struct NwGtpv1uTimeoutInfo
|
|||||||
*
|
*
|
||||||
* @param[in] thiz Pointer to stack instance
|
* @param[in] thiz Pointer to stack instance
|
||||||
* @param[in] timeoutArg Arg to timeout function.
|
* @param[in] timeoutArg Arg to timeout function.
|
||||||
* @param[out] phTmr Pointer to timer handle.
|
* @param[out] phTmr Pointer to timer handle.
|
||||||
* @return NW_GTPV1U_OK on success.
|
* @return NW_GTPV1U_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -140,7 +137,7 @@ nwGtpStartTrxnPeerRspTimer(NwGtpv1uStackT* thiz, NwGtpv1uTimeoutInfoT* timeoutIn
|
|||||||
* Stop a transaction response timer
|
* Stop a transaction response timer
|
||||||
*
|
*
|
||||||
* @param[in] thiz Pointer to stack instance
|
* @param[in] thiz Pointer to stack instance
|
||||||
* @param[out] phTmr Pointer to timer handle.
|
* @param[out] phTmr Pointer to timer handle.
|
||||||
* @return NW_GTPV1U_OK on success.
|
* @return NW_GTPV1U_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -153,8 +150,7 @@ nwGtpStopTrxnPeerRspTimer(NwGtpv1uStackT* thiz, NwGtpv1uTimerHandleT* phTmr);
|
|||||||
/**
|
/**
|
||||||
* NwGtpv1uMsgT holds gtpv1u messages to/from the peer.
|
* NwGtpv1uMsgT holds gtpv1u messages to/from the peer.
|
||||||
*/
|
*/
|
||||||
typedef struct NwGtpv1uMsg
|
typedef struct NwGtpv1uMsg {
|
||||||
{
|
|
||||||
NwU8T version;
|
NwU8T version;
|
||||||
NwU8T protocolType;
|
NwU8T protocolType;
|
||||||
NwU8T extHdrFlag;
|
NwU8T extHdrFlag;
|
||||||
@@ -164,7 +160,7 @@ typedef struct NwGtpv1uMsg
|
|||||||
NwU16T msgLen;
|
NwU16T msgLen;
|
||||||
NwU32T teid;
|
NwU32T teid;
|
||||||
NwU16T seqNum;
|
NwU16T seqNum;
|
||||||
NwU8T npduNum;
|
NwU8T npduNum;
|
||||||
NwU8T nextExtHdrType;
|
NwU8T nextExtHdrType;
|
||||||
NwU8T* msgBuf;
|
NwU8T* msgBuf;
|
||||||
NwU32T msgBufLen;
|
NwU32T msgBufLen;
|
||||||
@@ -174,15 +170,14 @@ typedef struct NwGtpv1uMsg
|
|||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* R6/R4 Transaction Context Type Definition
|
* R6/R4 Transaction Context Type Definition
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Transaction structure
|
* Transaction structure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv1uTrxn
|
typedef struct NwGtpv1uTrxn {
|
||||||
{
|
|
||||||
NwU32T seqNum;
|
NwU32T seqNum;
|
||||||
NwU32T peerIp;
|
NwU32T peerIp;
|
||||||
NwU32T peerPort;
|
NwU32T peerPort;
|
||||||
@@ -206,8 +201,7 @@ typedef struct NwGtpv1uTrxn
|
|||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
typedef struct NwGtpv1uMsgHeader
|
typedef struct NwGtpv1uMsgHeader {
|
||||||
{
|
|
||||||
NwU8T PN:1;
|
NwU8T PN:1;
|
||||||
NwU8T S:1;
|
NwU8T S:1;
|
||||||
NwU8T E:1;
|
NwU8T E:1;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 u *
|
* n w - g t p v 2 u *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -34,10 +34,10 @@
|
|||||||
/**
|
/**
|
||||||
* @file NwGtpv1uTrxn.h
|
* @file NwGtpv1uTrxn.h
|
||||||
* @author Amit Chawre
|
* @author Amit Chawre
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
* This header file contains required definitions and functions
|
* This header file contains required definitions and functions
|
||||||
* prototypes used by gtpv1u transactions.
|
* prototypes used by gtpv1u transactions.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 u *
|
* n w - g t p v 2 u *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 u *
|
* n w - g t p v 2 u *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -44,17 +44,17 @@
|
|||||||
/**
|
/**
|
||||||
* @file NwGtpv1u.h
|
* @file NwGtpv1u.h
|
||||||
* @author Amit Chawre
|
* @author Amit Chawre
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
* This header file contains all required definitions and functions
|
* This header file contains all required definitions and functions
|
||||||
* prototypes for using nw-gtpv1u library.
|
* prototypes for using nw-gtpv1u library.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#define NW_GTPU_VERSION (0x01)
|
#define NW_GTPU_VERSION (0x01)
|
||||||
#define NW_GTP_PROTOCOL_TYPE_GTP (0x01)
|
#define NW_GTP_PROTOCOL_TYPE_GTP (0x01)
|
||||||
#define NW_GTP_PROTOCOL_TYPE_GTP_PRIME (0x00)
|
#define NW_GTP_PROTOCOL_TYPE_GTP_PRIME (0x00)
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* S H A R E D A P I M A C R O S *
|
* S H A R E D A P I M A C R O S *
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
@@ -71,16 +71,15 @@
|
|||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
typedef NwPtrT NwGtpv1uStackHandleT; /**< Gtpv2 Stack Handle */
|
typedef NwPtrT NwGtpv1uStackHandleT; /**< Gtpv2 Stack Handle */
|
||||||
typedef NwPtrT NwGtpv1uUlpHandleT; /**< Gtpv2 Stack Ulp Entity Handle */
|
typedef NwPtrT NwGtpv1uUlpHandleT; /**< Gtpv2 Stack Ulp Entity Handle */
|
||||||
typedef NwPtrT NwGtpv1uUdpHandleT; /**< Gtpv2 Stack Udp Entity Handle */
|
typedef NwPtrT NwGtpv1uUdpHandleT; /**< Gtpv2 Stack Udp Entity Handle */
|
||||||
typedef NwPtrT NwGtpv1uMemMgrHandleT; /**< Gtpv2 Stack Mem Manager Handle */
|
typedef NwPtrT NwGtpv1uMemMgrHandleT; /**< Gtpv2 Stack Mem Manager Handle */
|
||||||
typedef NwPtrT NwGtpv1uTimerMgrHandleT; /**< Gtpv2 Stack Timer Manager Handle */
|
typedef NwPtrT NwGtpv1uTimerMgrHandleT; /**< Gtpv2 Stack Timer Manager Handle */
|
||||||
typedef NwPtrT NwGtpv1uLogMgrHandleT; /**< Gtpv2 Stack Log Mnagaer Handle */
|
typedef NwPtrT NwGtpv1uLogMgrHandleT; /**< Gtpv2 Stack Log Mnagaer Handle */
|
||||||
typedef NwPtrT NwGtpv1uTimerHandleT; /**< Gtpv2 Stack Timer Handle */
|
typedef NwPtrT NwGtpv1uTimerHandleT; /**< Gtpv2 Stack Timer Handle */
|
||||||
typedef NwPtrT NwGtpv1uMsgHandleT; /**< Gtpv2 Msg Handle */
|
typedef NwPtrT NwGtpv1uMsgHandleT; /**< Gtpv2 Msg Handle */
|
||||||
|
|
||||||
typedef struct NwGtpv1uStackConfig
|
typedef struct NwGtpv1uStackConfig {
|
||||||
{
|
|
||||||
NwU16T udpSrcPort;
|
NwU16T udpSrcPort;
|
||||||
} NwGtpv1uStackConfigT;
|
} NwGtpv1uStackConfigT;
|
||||||
|
|
||||||
@@ -92,12 +91,11 @@ typedef struct NwGtpv1uStackConfig
|
|||||||
* Gtpv2 Stack ULP API type definitions
|
* Gtpv2 Stack ULP API type definitions
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APIs types between ULP and Stack
|
* APIs types between ULP and Stack
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
/* APIs from ULP to stack */
|
/* APIs from ULP to stack */
|
||||||
|
|
||||||
NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT = 0x00000000, /**< Create a local teid context on stack */
|
NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT = 0x00000000, /**< Create a local teid context on stack */
|
||||||
@@ -128,35 +126,32 @@ typedef NwU32T NwGtpv1uTrxnHandleT; /**< Gtpv2 Transaction Handle */
|
|||||||
typedef NwU32T NwGtpv1uUlpTrxnHandleT; /**< Gtpv2 Ulp Transaction Handle */
|
typedef NwU32T NwGtpv1uUlpTrxnHandleT; /**< Gtpv2 Ulp Transaction Handle */
|
||||||
typedef NwU32T NwGtpv1uUlpSessionHandleT; /**< Gtpv2 Ulp session Handle */
|
typedef NwU32T NwGtpv1uUlpSessionHandleT; /**< Gtpv2 Ulp session Handle */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* creating a session.
|
* creating a session.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
NW_IN NwU32T teid;
|
||||||
NW_IN NwU32T teid;
|
NW_IN NwGtpv1uUlpSessionHandleT hUlpSession;
|
||||||
NW_IN NwGtpv1uUlpSessionHandleT hUlpSession;
|
NW_OUT NwGtpv1uStackSessionHandleT hStackSession;
|
||||||
NW_OUT NwGtpv1uStackSessionHandleT hStackSession;
|
|
||||||
} NwGtpv1uCreateTunnelEndPointT;
|
} NwGtpv1uCreateTunnelEndPointT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* destroying a session.
|
* destroying a session.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
NW_IN NwGtpv1uStackSessionHandleT hStackSessionHandle;
|
||||||
NW_IN NwGtpv1uStackSessionHandleT hStackSessionHandle;
|
|
||||||
} NwGtpv1uDestroyTunnelEndPointT;
|
} NwGtpv1uDestroyTunnelEndPointT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv1u initial message.
|
* sending a Gtpv1u initial message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
||||||
NW_IN NwU32T peerIp;
|
NW_IN NwU32T peerIp;
|
||||||
NW_IN NwU32T peerPort;
|
NW_IN NwU32T peerPort;
|
||||||
@@ -164,13 +159,12 @@ typedef struct
|
|||||||
NW_IN NwU32T teid;
|
NW_IN NwU32T teid;
|
||||||
} NwGtpv1uInitialReqInfoT;
|
} NwGtpv1uInitialReqInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv1u triggered response message.
|
* sending a Gtpv1u triggered response message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
||||||
NW_IN NwU32T peerIp;
|
NW_IN NwU32T peerIp;
|
||||||
NW_IN NwU32T peerPort;
|
NW_IN NwU32T peerPort;
|
||||||
@@ -180,13 +174,12 @@ typedef struct
|
|||||||
NW_IN NwGtpv1uMsgHandleT hMsg;
|
NW_IN NwGtpv1uMsgHandleT hMsg;
|
||||||
} NwGtpv1uTriggeredRspInfoT;
|
} NwGtpv1uTriggeredRspInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv1u triggered request message.
|
* sending a Gtpv1u triggered request message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
||||||
NW_IN NwU32T peerIp;
|
NW_IN NwU32T peerIp;
|
||||||
NW_IN NwU32T peerPort;
|
NW_IN NwU32T peerPort;
|
||||||
@@ -197,13 +190,12 @@ typedef struct
|
|||||||
} NwGtpv1uTriggeredReqInfoT;
|
} NwGtpv1uTriggeredReqInfoT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv2 message over a session.
|
* sending a Gtpv2 message over a session.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwU32T teid;
|
NW_IN NwU32T teid;
|
||||||
NW_IN NwU32T ipAddr;
|
NW_IN NwU32T ipAddr;
|
||||||
NW_IN NwU8T flags;
|
NW_IN NwU8T flags;
|
||||||
@@ -211,14 +203,13 @@ typedef struct
|
|||||||
} NwGtpv1uSendtoInfoT;
|
} NwGtpv1uSendtoInfoT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv2 message over a session.
|
* sending a Gtpv2 message over a session.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
NW_OUT NwGtpv1uStackSessionHandleT hStackSessionHandle;
|
||||||
NW_OUT NwGtpv1uStackSessionHandleT hStackSessionHandle;
|
|
||||||
NW_INOUT NwGtpv1uTrxnHandleT hTrxn;
|
NW_INOUT NwGtpv1uTrxnHandleT hTrxn;
|
||||||
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
||||||
NW_IN NwGtpv1uMsgTypeT msgType;
|
NW_IN NwGtpv1uMsgTypeT msgType;
|
||||||
@@ -226,14 +217,13 @@ typedef struct
|
|||||||
NW_IN NwGtpv1uMsgHandleT hMsg;
|
NW_IN NwGtpv1uMsgHandleT hMsg;
|
||||||
} NwGtpv1uSendMsgInfoT;
|
} NwGtpv1uSendMsgInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* receiving a Gtpv2 message over a session from stack.
|
* receiving a Gtpv2 message over a session from stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
NW_IN NwGtpv1uUlpSessionHandleT hUlpSession;
|
||||||
NW_IN NwGtpv1uUlpSessionHandleT hUlpSession;
|
|
||||||
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv1uUlpTrxnHandleT hUlpTrxn;
|
||||||
NW_IN NwU32T teid;
|
NW_IN NwU32T teid;
|
||||||
NW_IN NwU32T peerIp;
|
NW_IN NwU32T peerIp;
|
||||||
@@ -242,14 +232,13 @@ typedef struct
|
|||||||
NW_IN NwGtpv1uMsgHandleT hMsg; /**< Gtp Message handle */
|
NW_IN NwGtpv1uMsgHandleT hMsg; /**< Gtp Message handle */
|
||||||
} NwGtpv1uRecvMsgInfoT;
|
} NwGtpv1uRecvMsgInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* receiving a Gtpv2 message over a session from stack.
|
* receiving a Gtpv2 message over a session from stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
NW_IN NwGtpv1uUlpSessionHandleT hUlpSession;
|
||||||
NW_IN NwGtpv1uUlpSessionHandleT hUlpSession;
|
|
||||||
NW_IN NwGtpv1uTrxnHandleT hTrxn;
|
NW_IN NwGtpv1uTrxnHandleT hTrxn;
|
||||||
} NwGtpv1uNackInfoT;
|
} NwGtpv1uNackInfoT;
|
||||||
|
|
||||||
@@ -257,16 +246,14 @@ typedef struct
|
|||||||
* Gtpv2 Stack API structure definition
|
* Gtpv2 Stack API structure definition
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API structure between ULP and Stack
|
* API structure between ULP and Stack
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv1uUlpApiTypeT apiType;
|
NwGtpv1uUlpApiTypeT apiType;
|
||||||
NwGtpv1uMsgHandleT hMsg;
|
NwGtpv1uMsgHandleT hMsg;
|
||||||
union
|
union {
|
||||||
{
|
|
||||||
NwGtpv1uCreateTunnelEndPointT createTunnelEndPointInfo;
|
NwGtpv1uCreateTunnelEndPointT createTunnelEndPointInfo;
|
||||||
NwGtpv1uDestroyTunnelEndPointT destroyTunnelEndPointInfo;
|
NwGtpv1uDestroyTunnelEndPointT destroyTunnelEndPointInfo;
|
||||||
NwGtpv1uInitialReqInfoT initialReqInfo;
|
NwGtpv1uInitialReqInfoT initialReqInfo;
|
||||||
@@ -292,11 +279,10 @@ typedef struct
|
|||||||
* Gtpv2 ULP entity definition
|
* Gtpv2 ULP entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv1uUlpHandleT hUlp;
|
NwGtpv1uUlpHandleT hUlp;
|
||||||
NwGtpv1uRcT (*ulpReqCallback) ( NW_IN NwGtpv1uUlpHandleT hUlp,
|
NwGtpv1uRcT (*ulpReqCallback) ( NW_IN NwGtpv1uUlpHandleT hUlp,
|
||||||
NW_IN NwGtpv1uUlpApiT *pUlpApi);
|
NW_IN NwGtpv1uUlpApiT *pUlpApi);
|
||||||
} NwGtpv1uUlpEntityT;
|
} NwGtpv1uUlpEntityT;
|
||||||
|
|
||||||
|
|
||||||
@@ -308,33 +294,31 @@ typedef struct
|
|||||||
* Gtpv2 UDP entity definition
|
* Gtpv2 UDP entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv1uUdpHandleT hUdp;
|
NwGtpv1uUdpHandleT hUdp;
|
||||||
NwGtpv1uRcT (*udpDataReqCallback) ( NW_IN NwGtpv1uUdpHandleT udpHandle,
|
NwGtpv1uRcT (*udpDataReqCallback) ( NW_IN NwGtpv1uUdpHandleT udpHandle,
|
||||||
NW_IN NwU8T* dataBuf,
|
NW_IN NwU8T* dataBuf,
|
||||||
NW_IN NwU32T dataSize,
|
NW_IN NwU32T dataSize,
|
||||||
NW_IN NwU32T dataOffset,
|
NW_IN NwU32T dataOffset,
|
||||||
NW_IN NwU32T peerIP,
|
NW_IN NwU32T peerIP,
|
||||||
NW_IN NwU16T peerPort);
|
NW_IN NwU16T peerPort);
|
||||||
} NwGtpv1uUdpEntityT;
|
} NwGtpv1uUdpEntityT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gtpv1u Memory Manager entity definition
|
* Gtpv1u Memory Manager entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv1uMemMgrHandleT hMemMgr;
|
NwGtpv1uMemMgrHandleT hMemMgr;
|
||||||
void* (*memAlloc)( NW_IN NwGtpv1uMemMgrHandleT hMemMgr,
|
void* (*memAlloc)( NW_IN NwGtpv1uMemMgrHandleT hMemMgr,
|
||||||
NW_IN NwU32T memSize,
|
NW_IN NwU32T memSize,
|
||||||
NW_IN NwCharT* fileName,
|
NW_IN NwCharT* fileName,
|
||||||
NW_IN NwU32T lineNumber);
|
NW_IN NwU32T lineNumber);
|
||||||
|
|
||||||
void (*memFree) ( NW_IN NwGtpv1uMemMgrHandleT hMemMgr,
|
void (*memFree) ( NW_IN NwGtpv1uMemMgrHandleT hMemMgr,
|
||||||
NW_IN void* hMem,
|
NW_IN void* hMem,
|
||||||
NW_IN NwCharT* fileName,
|
NW_IN NwCharT* fileName,
|
||||||
NW_IN NwU32T lineNumber);
|
NW_IN NwU32T lineNumber);
|
||||||
} NwGtpv1uMemMgrEntityT;
|
} NwGtpv1uMemMgrEntityT;
|
||||||
|
|
||||||
|
|
||||||
@@ -349,18 +333,17 @@ typedef struct
|
|||||||
* Gtpv2 Timer Manager entity definition
|
* Gtpv2 Timer Manager entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv1uTimerMgrHandleT tmrMgrHandle;
|
NwGtpv1uTimerMgrHandleT tmrMgrHandle;
|
||||||
NwGtpv1uRcT (*tmrStartCallback)( NW_IN NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
NwGtpv1uRcT (*tmrStartCallback)( NW_IN NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||||
NW_IN NwU32T timeoutSecs,
|
NW_IN NwU32T timeoutSecs,
|
||||||
NW_IN NwU32T timeoutUsec,
|
NW_IN NwU32T timeoutUsec,
|
||||||
NW_IN NwU32T tmrType,
|
NW_IN NwU32T tmrType,
|
||||||
NW_IN void* tmrArg,
|
NW_IN void* tmrArg,
|
||||||
NW_OUT NwGtpv1uTimerHandleT* tmrHandle);
|
NW_OUT NwGtpv1uTimerHandleT* tmrHandle);
|
||||||
|
|
||||||
NwGtpv1uRcT (*tmrStopCallback) ( NW_IN NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
NwGtpv1uRcT (*tmrStopCallback) ( NW_IN NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||||
NW_IN NwGtpv1uTimerHandleT tmrHandle);
|
NW_IN NwGtpv1uTimerHandleT tmrHandle);
|
||||||
} NwGtpv1uTimerMgrEntityT;
|
} NwGtpv1uTimerMgrEntityT;
|
||||||
|
|
||||||
|
|
||||||
@@ -372,14 +355,13 @@ typedef struct
|
|||||||
* Gtpv2 Log manager entity definition
|
* Gtpv2 Log manager entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv1uLogMgrHandleT logMgrHandle;
|
NwGtpv1uLogMgrHandleT logMgrHandle;
|
||||||
NwGtpv1uRcT (*logReqCallback) (NW_IN NwGtpv1uLogMgrHandleT logMgrHandle,
|
NwGtpv1uRcT (*logReqCallback) (NW_IN NwGtpv1uLogMgrHandleT logMgrHandle,
|
||||||
NW_IN NwU32T logLevel,
|
NW_IN NwU32T logLevel,
|
||||||
NW_IN NwCharT* file,
|
NW_IN NwCharT* file,
|
||||||
NW_IN NwU32T line,
|
NW_IN NwU32T line,
|
||||||
NW_IN NwCharT* logStr);
|
NW_IN NwCharT* logStr);
|
||||||
} NwGtpv1uLogMgrEntityT;
|
} NwGtpv1uLogMgrEntityT;
|
||||||
|
|
||||||
|
|
||||||
@@ -390,12 +372,12 @@ typedef struct
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Constructor
|
* Constructor
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Initialize the nw-gtpv1u stack.
|
Initialize the nw-gtpv1u stack.
|
||||||
|
|
||||||
@param[in,out] phGtpv1uStackHandle : Pointer to stack handle
|
@param[in,out] phGtpv1uStackHandle : Pointer to stack handle
|
||||||
@@ -408,7 +390,7 @@ nwGtpv1uInitialize( NW_INOUT NwGtpv1uStackHandleT* phGtpv1uStackHandle);
|
|||||||
* Destructor
|
* Destructor
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Destroy the nw-gtpv1u stack.
|
Destroy the nw-gtpv1u stack.
|
||||||
|
|
||||||
@param[in] hGtpv1uStackHandle : Stack handle
|
@param[in] hGtpv1uStackHandle : Stack handle
|
||||||
@@ -421,7 +403,7 @@ nwGtpv1uFinalize( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle);
|
|||||||
* Configuration Get/Set Operations
|
* Configuration Get/Set Operations
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set Configuration for the nw-gtpv1u stack.
|
Set Configuration for the nw-gtpv1u stack.
|
||||||
|
|
||||||
@param[in,out] phGtpv1uStackHandle : Pointer to stack handle
|
@param[in,out] phGtpv1uStackHandle : Pointer to stack handle
|
||||||
@@ -430,7 +412,7 @@ nwGtpv1uFinalize( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle);
|
|||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
NwGtpv1uConfigSet( NW_IN NwGtpv1uStackHandleT* phGtpv1uStackHandle, NW_IN NwGtpv1uStackConfigT* pConfig);
|
NwGtpv1uConfigSet( NW_IN NwGtpv1uStackHandleT* phGtpv1uStackHandle, NW_IN NwGtpv1uStackConfigT* pConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get Configuration for the nw-gtpv1u stack.
|
Get Configuration for the nw-gtpv1u stack.
|
||||||
|
|
||||||
@param[in,out] phGtpv1uStackHandle : Pointer to stack handle
|
@param[in,out] phGtpv1uStackHandle : Pointer to stack handle
|
||||||
@@ -439,7 +421,7 @@ NwGtpv1uConfigSet( NW_IN NwGtpv1uStackHandleT* phGtpv1uStackHandle, NW_IN NwGtpv
|
|||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
NwGtpv1uConfigGet( NW_IN NwGtpv1uStackHandleT* phGtpv1uStackHandle, NW_OUT NwGtpv1uStackConfigT* pConfig);
|
NwGtpv1uConfigGet( NW_IN NwGtpv1uStackHandleT* phGtpv1uStackHandle, NW_OUT NwGtpv1uStackConfigT* pConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set ULP entity for the stack.
|
Set ULP entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpv1uStackHandle : Stack handle
|
@param[in] hGtpv1uStackHandle : Stack handle
|
||||||
@@ -449,9 +431,9 @@ NwGtpv1uConfigGet( NW_IN NwGtpv1uStackHandleT* phGtpv1uStackHandle, NW_OUT NwGtp
|
|||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uSetUlpEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
nwGtpv1uSetUlpEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
||||||
NW_IN NwGtpv1uUlpEntityT* pUlpEntity);
|
NW_IN NwGtpv1uUlpEntityT* pUlpEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set UDP entity for the stack.
|
Set UDP entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpv1uStackHandle : Stack handle
|
@param[in] hGtpv1uStackHandle : Stack handle
|
||||||
@@ -461,9 +443,9 @@ nwGtpv1uSetUlpEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
|||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uSetUdpEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
nwGtpv1uSetUdpEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
||||||
NW_IN NwGtpv1uUdpEntityT* pUdpEntity);
|
NW_IN NwGtpv1uUdpEntityT* pUdpEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set MemMgr entity for the stack.
|
Set MemMgr entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpv1uStackHandle : Stack handle
|
@param[in] hGtpv1uStackHandle : Stack handle
|
||||||
@@ -473,10 +455,10 @@ nwGtpv1uSetUdpEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
|||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uSetMemMgrEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
nwGtpv1uSetMemMgrEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
||||||
NW_IN NwGtpv1uMemMgrEntityT* pMemMgr);
|
NW_IN NwGtpv1uMemMgrEntityT* pMemMgr);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set TmrMgr entity for the stack.
|
Set TmrMgr entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpv1uStackHandle : Stack handle
|
@param[in] hGtpv1uStackHandle : Stack handle
|
||||||
@@ -486,9 +468,9 @@ nwGtpv1uSetMemMgrEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
|||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uSetTimerMgrEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
nwGtpv1uSetTimerMgrEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
||||||
NW_IN NwGtpv1uTimerMgrEntityT* pTmrMgr);
|
NW_IN NwGtpv1uTimerMgrEntityT* pTmrMgr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set LogMgr entity for the stack.
|
Set LogMgr entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpv1uStackHandle : Stack handle
|
@param[in] hGtpv1uStackHandle : Stack handle
|
||||||
@@ -498,9 +480,9 @@ nwGtpv1uSetTimerMgrEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
|||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uSetLogMgrEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
nwGtpv1uSetLogMgrEntity( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
||||||
NW_IN NwGtpv1uLogMgrEntityT* pLogMgr);
|
NW_IN NwGtpv1uLogMgrEntityT* pLogMgr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set log level for the stack.
|
Set log level for the stack.
|
||||||
|
|
||||||
@param[in] hGtpv1uStackHandle : Stack handle
|
@param[in] hGtpv1uStackHandle : Stack handle
|
||||||
@@ -526,12 +508,12 @@ nwGtpv1uSetLogLevel( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
|||||||
@return NW_GTPV1U_OK on success.
|
@return NW_GTPV1U_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uProcessUdpReq( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
nwGtpv1uProcessUdpReq( NW_IN NwGtpv1uStackHandleT hGtpv1uStackHandle,
|
||||||
NW_IN NwU8T* udpData,
|
NW_IN NwU8T* udpData,
|
||||||
NW_IN NwU32T udpDataLen,
|
NW_IN NwU32T udpDataLen,
|
||||||
NW_IN NwU16T peerPort,
|
NW_IN NwU16T peerPort,
|
||||||
NW_IN NwU32T peerIP);
|
NW_IN NwU32T peerIP);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Process Request from Upper Layer
|
* Process Request from Upper Layer
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -35,8 +35,8 @@
|
|||||||
#ifndef __NW_GTPV1U_ERROR_H__
|
#ifndef __NW_GTPV1U_ERROR_H__
|
||||||
#define __NW_GTPV1U_ERROR_H__
|
#define __NW_GTPV1U_ERROR_H__
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv1uError.h
|
* @file NwGtpv1uError.h
|
||||||
* @brief This header file contains return error code type definitions.
|
* @brief This header file contains return error code type definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -51,7 +51,8 @@ typedef enum {
|
|||||||
NW_GTPV1U_MANDATORY_IE_MISSING,
|
NW_GTPV1U_MANDATORY_IE_MISSING,
|
||||||
NW_GTPV1U_MSG_MALFORMED,
|
NW_GTPV1U_MSG_MALFORMED,
|
||||||
NW_GTPV1U_FAILURE = 0xFFFFFFFE
|
NW_GTPV1U_FAILURE = 0xFFFFFFFE
|
||||||
} NwGtpv1uRcT;
|
}
|
||||||
|
NwGtpv1uRcT;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 u *
|
* n w - g t p v 2 u *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv1uIe.h
|
* @file NwGtpv1uIe.h
|
||||||
* @brief This header file contains Information Element definitions for GTPv1u
|
* @brief This header file contains Information Element definitions for GTPv1u
|
||||||
* as per 3GPP TS 29281-930.
|
* as per 3GPP TS 29281-930.
|
||||||
@@ -55,8 +55,8 @@
|
|||||||
* G T P V 2 U C A U S E V A L U E D E F I N I T I O N S *
|
* G T P V 2 U C A U S E V A L U E D E F I N I T I O N S *
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define NW_GTPV1U_CAUSE_REQUEST_ACCEPTED (16)
|
#define NW_GTPV1U_CAUSE_REQUEST_ACCEPTED (16)
|
||||||
#define NW_GTPV1U_CAUSE_MANDATORY_IE_MISSING (70)
|
#define NW_GTPV1U_CAUSE_MANDATORY_IE_MISSING (70)
|
||||||
|
|
||||||
#endif /* __NW_GTPV1U_IE_H__ */
|
#endif /* __NW_GTPV1U_IE_H__ */
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 u *
|
* n w - g t p v 2 u *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 u S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
#include "NwTypes.h"
|
#include "NwTypes.h"
|
||||||
#include "NwGtpv1u.h"
|
#include "NwGtpv1u.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv1uMsg.h
|
* @file NwGtpv1uMsg.h
|
||||||
* @brief This file defines APIs for to build new outgoing gtpv1u messages and to parse incoming messages.
|
* @brief This file defines APIs for to build new outgoing gtpv1u messages and to parse incoming messages.
|
||||||
*/
|
*/
|
||||||
@@ -52,26 +52,22 @@ extern "C" {
|
|||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
typedef struct NwGtpv1uIeTv1
|
typedef struct NwGtpv1uIeTv1 {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU8T v;
|
NwU8T v;
|
||||||
} NwGtpv1uIeTv1T;
|
} NwGtpv1uIeTv1T;
|
||||||
|
|
||||||
typedef struct NwGtpv1uIeTv2
|
typedef struct NwGtpv1uIeTv2 {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU8T v;
|
NwU8T v;
|
||||||
} NwGtpv1uIeTv2T;
|
} NwGtpv1uIeTv2T;
|
||||||
|
|
||||||
typedef struct NwGtpv1uIeTv4
|
typedef struct NwGtpv1uIeTv4 {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU32T v;
|
NwU32T v;
|
||||||
} NwGtpv1uIeTv4T;
|
} NwGtpv1uIeTv4T;
|
||||||
|
|
||||||
typedef struct NwGtpv1uIeTlv
|
typedef struct NwGtpv1uIeTlv {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU16T l;
|
NwU16T l;
|
||||||
} NwGtpv1uIeTlvT;
|
} NwGtpv1uIeTlvT;
|
||||||
@@ -79,15 +75,15 @@ typedef struct NwGtpv1uIeTlv
|
|||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a GPDU gtpv1u message.
|
* Allocate a GPDU gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
||||||
* @param[in] teidPresent : TEID is present flag.
|
* @param[in] teidPresent : TEID is present flag.
|
||||||
* @param[in] teid : TEID for this message.
|
* @param[in] teid : TEID for this message.
|
||||||
* @param[in] seqNum : Sequence number for this message.
|
* @param[in] seqNum : Sequence number for this message.
|
||||||
* @param[out] phMsg : Pointer to message handle.
|
* @param[out] phMsg : Pointer to message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
nwGtpv1uMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
||||||
@@ -102,130 +98,130 @@ nwGtpv1uMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
|||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg);
|
NW_OUT NwGtpv1uMsgHandleT *phMsg);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a gtpv1u message.
|
* Allocate a gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
||||||
* @param[in] teid : TEID for this message.
|
* @param[in] teid : TEID for this message.
|
||||||
* @param[in] seqNumFlag : Sequence number flag for this message.
|
* @param[in] seqNumFlag : Sequence number flag for this message.
|
||||||
* @param[in] seqNum : Sequence number for this message.
|
* @param[in] seqNum : Sequence number for this message.
|
||||||
* @param[in] pTpdu: T-PDU for this message.
|
* @param[in] pTpdu: T-PDU for this message.
|
||||||
* @param[in] tpduLength: T-PDU length for this message.
|
* @param[in] tpduLength: T-PDU length for this message.
|
||||||
* @param[out] phMsg : Pointer to message handle.
|
* @param[out] phMsg : Pointer to message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
||||||
NW_IN NwU32T teid,
|
NW_IN NwU32T teid,
|
||||||
NW_IN NwU8T seqNumFlag,
|
NW_IN NwU8T seqNumFlag,
|
||||||
NW_IN NwU16T seqNum,
|
NW_IN NwU16T seqNum,
|
||||||
NW_IN NwU8T* tpdu,
|
NW_IN NwU8T* tpdu,
|
||||||
NW_IN NwU16T tpduLength,
|
NW_IN NwU16T tpduLength,
|
||||||
NW_IN NwU32T tpduOffset,
|
NW_IN NwU32T tpduOffset,
|
||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg);
|
NW_OUT NwGtpv1uMsgHandleT *phMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a gtpv1u message from another gtpv1u message.
|
* Allocate a gtpv1u message from another gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
||||||
* @param[out] hMsg : Handle to input message.
|
* @param[out] hMsg : Handle to input message.
|
||||||
* @param[out] phMsg : Pointer to message handle.
|
* @param[out] phMsg : Pointer to message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgFromMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
nwGtpv1uMsgFromMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
||||||
NW_IN NwGtpv1uMsgHandleT hMsg,
|
NW_IN NwGtpv1uMsgHandleT hMsg,
|
||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg);
|
NW_OUT NwGtpv1uMsgHandleT *phMsg);
|
||||||
/**
|
/**
|
||||||
* Allocate a gtpv1u message from data buffer.
|
* Allocate a gtpv1u message from data buffer.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
||||||
* @param[in] pBuf: Buffer to be copied in this message.
|
* @param[in] pBuf: Buffer to be copied in this message.
|
||||||
* @param[in] bufLen: Buffer length to be copied in this message.
|
* @param[in] bufLen: Buffer length to be copied in this message.
|
||||||
* @param[out] phMsg : Pointer to message handle.
|
* @param[out] phMsg : Pointer to message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgFromBufferNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
nwGtpv1uMsgFromBufferNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
||||||
NW_IN NwU8T* pBuf,
|
NW_IN NwU8T* pBuf,
|
||||||
NW_IN NwU32T bufLen,
|
NW_IN NwU32T bufLen,
|
||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg);
|
NW_OUT NwGtpv1uMsgHandleT *phMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a gtpv1u message.
|
* Free a gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
* @param[in] hGtpuStackHandle : gtpv1u stack handle.
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgDelete( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
nwGtpv1uMsgDelete( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
||||||
NW_IN NwGtpv1uMsgHandleT hMsg);
|
NW_IN NwGtpv1uMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set TEID for gtpv1u message.
|
* Set TEID for gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] teid: TEID value.
|
* @param[in] teid: TEID value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgSetTeid(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T teid);
|
nwGtpv1uMsgSetTeid(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T teid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set TEID present flag for gtpv1u message.
|
* Set TEID present flag for gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] teidPesent: Flag boolean value.
|
* @param[in] teidPesent: Flag boolean value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgSetTeidPresent(NW_IN NwGtpv1uMsgHandleT hMsg, NwBoolT teidPresent);
|
nwGtpv1uMsgSetTeidPresent(NW_IN NwGtpv1uMsgHandleT hMsg, NwBoolT teidPresent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set sequence for gtpv1u message.
|
* Set sequence for gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] seqNum: Flag boolean value.
|
* @param[in] seqNum: Flag boolean value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgSetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T seqNum);
|
nwGtpv1uMsgSetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T seqNum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get TEID present for gtpv1u message.
|
* Get TEID present for gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv1uMsgGetTeid(NW_IN NwGtpv1uMsgHandleT hMsg);
|
nwGtpv1uMsgGetTeid(NW_IN NwGtpv1uMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get TEID present for gtpv1u message.
|
* Get TEID present for gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwBoolT
|
NwBoolT
|
||||||
nwGtpv1uMsgGetTeidPresent(NW_IN NwGtpv1uMsgHandleT hMsg);
|
nwGtpv1uMsgGetTeidPresent(NW_IN NwGtpv1uMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get sequence number for gtpv1u message.
|
* Get sequence number for gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv1uMsgGetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg);
|
nwGtpv1uMsgGetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get tpdu for gtpv1u message.
|
* Get tpdu for gtpv1u message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[inout] pTpduBuf : Buffer to copy the T-PDU.
|
* @param[inout] pTpduBuf : Buffer to copy the T-PDU.
|
||||||
* @param[out] hMsg : T-PDU length.
|
* @param[out] hMsg : T-PDU length.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv1uMsgGetTpdu(NW_IN NwGtpv1uMsgHandleT hMsg, NwU8T* pTpduBuf, NwU32T* pTpduLength);
|
nwGtpv1uMsgGetTpdu(NW_IN NwGtpv1uMsgHandleT hMsg, NwU8T* pTpduBuf, NwU32T* pTpduLength);
|
||||||
@@ -236,64 +232,64 @@ nwGtpv1uMsgGetTpduHandle(NW_IN NwGtpv1uMsgHandleT hMsg);
|
|||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv1uMsgGetTpduLength(NW_IN NwGtpv1uMsgHandleT hMsg);
|
nwGtpv1uMsgGetTpduLength(NW_IN NwGtpv1uMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a gtpv1u information element of length 1 to gtpv1u mesasge.
|
* Add a gtpv1u information element of length 1 to gtpv1u mesasge.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv1u message.
|
* @param[in] hMsg : Handle to gtpv1u message.
|
||||||
* @param[in] type : IE type.
|
* @param[in] type : IE type.
|
||||||
* @param[in] value : IE value.
|
* @param[in] value : IE value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgAddIeTV1(NW_IN NwGtpv1uMsgHandleT hMsg,
|
nwGtpv1uMsgAddIeTV1(NW_IN NwGtpv1uMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T value);
|
NW_IN NwU8T value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a gtpv1u information element of length 2 to gtpv1u mesasge.
|
* Add a gtpv1u information element of length 2 to gtpv1u mesasge.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv1u message.
|
* @param[in] hMsg : Handle to gtpv1u message.
|
||||||
* @param[in] type : IE type.
|
* @param[in] type : IE type.
|
||||||
* @param[in] value : IE value.
|
* @param[in] value : IE value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgAddIeTV2(NW_IN NwGtpv1uMsgHandleT hMsg,
|
nwGtpv1uMsgAddIeTV2(NW_IN NwGtpv1uMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU16T length,
|
NW_IN NwU16T length,
|
||||||
NW_IN NwU16T value);
|
NW_IN NwU16T value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a gtpv1u information element of length 4 to gtpv1u mesasge.
|
* Add a gtpv1u information element of length 4 to gtpv1u mesasge.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv1u message.
|
* @param[in] hMsg : Handle to gtpv1u message.
|
||||||
* @param[in] type : IE type.
|
* @param[in] type : IE type.
|
||||||
* @param[in] value : IE value.
|
* @param[in] value : IE value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgAddIeTV4(NW_IN NwGtpv1uMsgHandleT hMsg,
|
nwGtpv1uMsgAddIeTV4(NW_IN NwGtpv1uMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU16T length,
|
NW_IN NwU16T length,
|
||||||
NW_IN NwU32T value);
|
NW_IN NwU32T value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a gtpv1u information element of variable length to gtpv1u mesasge.
|
* Add a gtpv1u information element of variable length to gtpv1u mesasge.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv1u message.
|
* @param[in] hMsg : Handle to gtpv1u message.
|
||||||
* @param[in] type : IE type.
|
* @param[in] type : IE type.
|
||||||
* @param[in] length : IE length.
|
* @param[in] length : IE length.
|
||||||
* @param[in] value : IE value.
|
* @param[in] value : IE value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgAddIe(NW_IN NwGtpv1uMsgHandleT hMsg,
|
nwGtpv1uMsgAddIe(NW_IN NwGtpv1uMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU16T length,
|
NW_IN NwU16T length,
|
||||||
NW_IN NwU8T* pVal);
|
NW_IN NwU8T* pVal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dump the contents of gtpv1u mesasge.
|
* Dump the contents of gtpv1u mesasge.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -39,8 +39,8 @@
|
|||||||
|
|
||||||
#include "NwTypes.h"
|
#include "NwTypes.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwLog.h
|
* @file NwLog.h
|
||||||
* @brief This header file contains global shared logging definitions.
|
* @brief This header file contains global shared logging definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ extern "C" {
|
|||||||
#define NW_LOG_LEVEL_ALER (1) /**< action must be taken immediately*/
|
#define NW_LOG_LEVEL_ALER (1) /**< action must be taken immediately*/
|
||||||
#define NW_LOG_LEVEL_CRIT (2) /**< critical conditions */
|
#define NW_LOG_LEVEL_CRIT (2) /**< critical conditions */
|
||||||
#define NW_LOG_LEVEL_ERRO (3) /**< error conditions */
|
#define NW_LOG_LEVEL_ERRO (3) /**< error conditions */
|
||||||
#define NW_LOG_LEVEL_WARN (4) /**< warning conditions */
|
#define NW_LOG_LEVEL_WARN (4) /**< warning conditions */
|
||||||
#define NW_LOG_LEVEL_NOTI (5) /**< normal but signification condition */
|
#define NW_LOG_LEVEL_NOTI (5) /**< normal but signification condition */
|
||||||
#define NW_LOG_LEVEL_INFO (6) /**< informational */
|
#define NW_LOG_LEVEL_INFO (6) /**< informational */
|
||||||
#define NW_LOG_LEVEL_DEBG (7) /**< debug-level messages */
|
#define NW_LOG_LEVEL_DEBG (7) /**< debug-level messages */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#ifndef __NW_TYPES_H__
|
#ifndef __NW_TYPES_H__
|
||||||
#define __NW_TYPES_H__
|
#define __NW_TYPES_H__
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwTypes.h
|
* @file NwTypes.h
|
||||||
* @brief This header file contains basic type definitions.
|
* @brief This header file contains basic type definitions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -37,13 +37,13 @@
|
|||||||
#define __NW_UTILS_H__
|
#define __NW_UTILS_H__
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwUtils.h
|
* @file NwUtils.h
|
||||||
* @brief This header file contains utility macro and function definitions.
|
* @brief This header file contains utility macro and function definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NW_ASSERT assert /**< Assertion */
|
#define NW_ASSERT assert /**< Assertion */
|
||||||
|
|
||||||
#define NW_CHK_NULL_PTR(_ptr) NW_ASSERT(_ptr != NULL) /**< Null pointer check */
|
#define NW_CHK_NULL_PTR(_ptr) NW_ASSERT(_ptr != NULL) /**< Null pointer check */
|
||||||
|
|
||||||
#define NW_HTONS(x) ( ( ((x) & 0xff00) >> 8 ) | ( ((x) & 0x00ff) << 8 ) )
|
#define NW_HTONS(x) ( ( ((x) & 0xff00) >> 8 ) | ( ((x) & 0x00ff) << 8 ) )
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
( ( ((NwU64T)x) & 0x0000ff0000000000ULL ) >> 24 ) | ( ( ((NwU64T)x) & 0x000000ff00000000ULL ) >> 8 ) | \
|
( ( ((NwU64T)x) & 0x0000ff0000000000ULL ) >> 24 ) | ( ( ((NwU64T)x) & 0x000000ff00000000ULL ) >> 8 ) | \
|
||||||
( ( ((NwU64T)x) & 0x000000000000ff00ULL ) << 40 ) | ( ( ((NwU64T)x) & 0x00000000000000ffULL ) << 56 ) | \
|
( ( ((NwU64T)x) & 0x000000000000ff00ULL ) << 40 ) | ( ( ((NwU64T)x) & 0x00000000000000ffULL ) << 56 ) | \
|
||||||
( ( ((NwU64T)x) & 0x0000000000ff0000ULL ) << 24 ) | ( ( ((NwU64T)x) & 0x00000000ff000000ULL ) << 8 ) \
|
( ( ((NwU64T)x) & 0x0000000000ff0000ULL ) << 24 ) | ( ( ((NwU64T)x) & 0x00000000ff000000ULL ) << 8 ) \
|
||||||
)
|
)
|
||||||
|
|
||||||
#define NW_NTOHS NW_HTONS
|
#define NW_NTOHS NW_HTONS
|
||||||
#define NW_NTOHL NW_HTONL
|
#define NW_NTOHL NW_HTONL
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -70,48 +70,50 @@ nwGtpv1uMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
|||||||
NW_IN NwU8T nextExtHeader,
|
NW_IN NwU8T nextExtHeader,
|
||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg)
|
NW_OUT NwGtpv1uMsgHandleT *phMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle;
|
NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle;
|
||||||
NwGtpv1uMsgT *pMsg;
|
NwGtpv1uMsgT *pMsg;
|
||||||
|
|
||||||
if(gpGtpv1uMsgPool) {
|
if(gpGtpv1uMsgPool) {
|
||||||
pMsg = gpGtpv1uMsgPool;
|
pMsg = gpGtpv1uMsgPool;
|
||||||
gpGtpv1uMsgPool = gpGtpv1uMsgPool->next;
|
gpGtpv1uMsgPool = gpGtpv1uMsgPool->next;
|
||||||
} else {
|
} else {
|
||||||
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *);
|
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(pMsg) {
|
||||||
|
pMsg->version = NW_GTPU_VERSION;
|
||||||
|
pMsg->protocolType = NW_GTP_PROTOCOL_TYPE_GTP;
|
||||||
|
pMsg->seqNumFlag = seqNumFlag;
|
||||||
|
pMsg->npduNumFlag = npduNumFlag;
|
||||||
|
pMsg->extHdrFlag = extHdrFlag;
|
||||||
|
pMsg->msgType = msgType;
|
||||||
|
|
||||||
|
if(seqNumFlag) {
|
||||||
|
pMsg->seqNum = seqNum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(npduNumFlag) {
|
||||||
if(pMsg) {
|
pMsg->npduNum = npduNum;
|
||||||
pMsg->version = NW_GTPU_VERSION;
|
|
||||||
pMsg->protocolType = NW_GTP_PROTOCOL_TYPE_GTP;
|
|
||||||
pMsg->seqNumFlag = seqNumFlag;
|
|
||||||
pMsg->npduNumFlag = npduNumFlag;
|
|
||||||
pMsg->extHdrFlag = extHdrFlag;
|
|
||||||
pMsg->msgType = msgType;
|
|
||||||
|
|
||||||
if(seqNumFlag) {
|
|
||||||
pMsg->seqNum = seqNum;
|
|
||||||
}
|
|
||||||
if(npduNumFlag) {
|
|
||||||
pMsg->npduNum = npduNum;
|
|
||||||
}
|
|
||||||
if(extHdrFlag) {
|
|
||||||
pMsg->nextExtHdrType = nextExtHeader;
|
|
||||||
}
|
|
||||||
|
|
||||||
pMsg->msgLen = ((pMsg->seqNumFlag || pMsg->npduNumFlag
|
|
||||||
|| pMsg->extHdrFlag) ?
|
|
||||||
4 : 0);
|
|
||||||
//NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE : (NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE - 4));
|
|
||||||
|
|
||||||
pMsg->msgBuf = NULL;
|
|
||||||
pMsg->msgBufLen = 0;
|
|
||||||
pMsg->msgBufOffset = 0;
|
|
||||||
*phMsg = (NwGtpv1uMsgHandleT) pMsg;
|
|
||||||
return NW_GTPV1U_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_GTPV1U_FAILURE;
|
if(extHdrFlag) {
|
||||||
|
pMsg->nextExtHdrType = nextExtHeader;
|
||||||
|
}
|
||||||
|
|
||||||
|
pMsg->msgLen = ((pMsg->seqNumFlag || pMsg->npduNumFlag
|
||||||
|
|| pMsg->extHdrFlag) ?
|
||||||
|
4 : 0);
|
||||||
|
//NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE : (NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE - 4));
|
||||||
|
|
||||||
|
pMsg->msgBuf = NULL;
|
||||||
|
pMsg->msgBufLen = 0;
|
||||||
|
pMsg->msgBufOffset = 0;
|
||||||
|
*phMsg = (NwGtpv1uMsgHandleT) pMsg;
|
||||||
|
return NW_GTPV1U_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NW_GTPV1U_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
@@ -124,87 +126,87 @@ nwGtpv1uGpduMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
|||||||
NW_IN NwU32T tpduOffset,
|
NW_IN NwU32T tpduOffset,
|
||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg)
|
NW_OUT NwGtpv1uMsgHandleT *phMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle;
|
NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle;
|
||||||
NwGtpv1uMsgT *pMsg;
|
NwGtpv1uMsgT *pMsg;
|
||||||
NwU32T msgExtraLen = 0;
|
NwU32T msgExtraLen = 0;
|
||||||
|
|
||||||
if(gpGtpv1uMsgPool) {
|
if(gpGtpv1uMsgPool) {
|
||||||
pMsg = gpGtpv1uMsgPool;
|
pMsg = gpGtpv1uMsgPool;
|
||||||
gpGtpv1uMsgPool = gpGtpv1uMsgPool->next;
|
gpGtpv1uMsgPool = gpGtpv1uMsgPool->next;
|
||||||
} else {
|
} else {
|
||||||
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *);
|
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pMsg) {
|
if(pMsg) {
|
||||||
msgExtraLen = (((seqNumFlag) || (NW_FALSE) || (NW_FALSE) ) ?
|
msgExtraLen = (((seqNumFlag) || (NW_FALSE) || (NW_FALSE) ) ?
|
||||||
(NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE - NW_GTPV1U_EPC_MIN_HEADER_SIZE) : 0);
|
(NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE - NW_GTPV1U_EPC_MIN_HEADER_SIZE) : 0);
|
||||||
AssertFatal((msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE) <= tpduOffset,
|
AssertFatal((msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE) <= tpduOffset,
|
||||||
"Mismatch GTPU len, msgExtraLen %u tpduOffset %u",
|
"Mismatch GTPU len, msgExtraLen %u tpduOffset %u",
|
||||||
msgExtraLen,
|
msgExtraLen,
|
||||||
tpduOffset);
|
tpduOffset);
|
||||||
pMsg->msgBuf = tpdu;
|
pMsg->msgBuf = tpdu;
|
||||||
pMsg->msgBufLen = tpduLength + msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE;
|
pMsg->msgBufLen = tpduLength + msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE;
|
||||||
pMsg->msgBufOffset = tpduOffset - (msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE);
|
pMsg->msgBufOffset = tpduOffset - (msgExtraLen + NW_GTPV1U_EPC_MIN_HEADER_SIZE);
|
||||||
#if defined(LOG_GTPU) && LOG_GTPU > 0
|
#if defined(LOG_GTPU) && LOG_GTPU > 0
|
||||||
GTPU_DEBUG("MSG length %u, offset %u -> length %u offset %u\n",
|
GTPU_DEBUG("MSG length %u, offset %u -> length %u offset %u\n",
|
||||||
tpduLength, tpduOffset,
|
tpduLength, tpduOffset,
|
||||||
pMsg->msgBufLen, pMsg->msgBufOffset);
|
pMsg->msgBufLen, pMsg->msgBufOffset);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Version field: This field is used to determine the version of the GTP-U protocol.
|
// Version field: This field is used to determine the version of the GTP-U protocol.
|
||||||
// The version number shall be set to '1'.
|
// The version number shall be set to '1'.
|
||||||
pMsg->version = NW_GTPU_VERSION;
|
pMsg->version = NW_GTPU_VERSION;
|
||||||
// Protocol Type (PT): This bit is used as a protocol discriminator between GTP (when PT is '1')
|
// Protocol Type (PT): This bit is used as a protocol discriminator between GTP (when PT is '1')
|
||||||
// and GTP' (when PT is '0'). GTP is described in this document and the GTP' protocol in 3GPP TS 32.295 [8].
|
// and GTP' (when PT is '0'). GTP is described in this document and the GTP' protocol in 3GPP TS 32.295 [8].
|
||||||
// Note that the interpretation of the header fields may be different in GTP' than in GTP.
|
// Note that the interpretation of the header fields may be different in GTP' than in GTP.
|
||||||
pMsg->protocolType = NW_GTP_PROTOCOL_TYPE_GTP;
|
pMsg->protocolType = NW_GTP_PROTOCOL_TYPE_GTP;
|
||||||
// Extension Header flag (E): This flag indicates the presence of a meaningful value of the Next Extension
|
// Extension Header flag (E): This flag indicates the presence of a meaningful value of the Next Extension
|
||||||
// Header field. When it is set to '0', the Next Extension Header field either is not present or, if present,
|
// Header field. When it is set to '0', the Next Extension Header field either is not present or, if present,
|
||||||
// shall not be interpreted.
|
// shall not be interpreted.
|
||||||
pMsg->extHdrFlag = NW_FALSE;
|
pMsg->extHdrFlag = NW_FALSE;
|
||||||
// Sequence number flag (S): This flag indicates the presence of a meaningful value of the Sequence Number field.
|
// Sequence number flag (S): This flag indicates the presence of a meaningful value of the Sequence Number field.
|
||||||
// When it is set to '0', the Sequence Number field either is not present or, if present, shall not be interpreted.
|
// When it is set to '0', the Sequence Number field either is not present or, if present, shall not be interpreted.
|
||||||
// When it is set to '1', the Sequence Number field is present, and shall be interpreted, as described below in
|
// When it is set to '1', the Sequence Number field is present, and shall be interpreted, as described below in
|
||||||
// this section.
|
// this section.
|
||||||
// For the Echo Request, Echo Response, Error Indication and Supported Extension Headers Notification
|
// For the Echo Request, Echo Response, Error Indication and Supported Extension Headers Notification
|
||||||
// messages, the S flag shall be set to '1'. Since the use of Sequence Numbers is optional for G-PDUs, the PGW,
|
// messages, the S flag shall be set to '1'. Since the use of Sequence Numbers is optional for G-PDUs, the PGW,
|
||||||
// SGW, ePDG and eNodeB should set the flag to '0'. However, when a G-PDU (T-PDU+header) is being relayed
|
// SGW, ePDG and eNodeB should set the flag to '0'. However, when a G-PDU (T-PDU+header) is being relayed
|
||||||
// by the Indirect Data Forwarding for Inter RAT HO procedure, then if the received G-PDU has the S flag set to
|
// by the Indirect Data Forwarding for Inter RAT HO procedure, then if the received G-PDU has the S flag set to
|
||||||
// '1', then the relaying entity shall set S flag to '1' and forward the G-PDU (T-PDU+header). In an End marker
|
// '1', then the relaying entity shall set S flag to '1' and forward the G-PDU (T-PDU+header). In an End marker
|
||||||
// message the S flag shall be set to '0'.
|
// message the S flag shall be set to '0'.
|
||||||
pMsg->seqNumFlag = (seqNumFlag? NW_TRUE : NW_FALSE);
|
pMsg->seqNumFlag = (seqNumFlag? NW_TRUE : NW_FALSE);
|
||||||
pMsg->seqNum = seqNum;
|
pMsg->seqNum = seqNum;
|
||||||
// N-PDU Number flag (PN): This flag indicates the presence of a meaningful value of the N-PDU Number field.
|
// N-PDU Number flag (PN): This flag indicates the presence of a meaningful value of the N-PDU Number field.
|
||||||
// When it is set to '0', the N-PDU Number field either is not present, or, if present, shall not be interpreted.
|
// When it is set to '0', the N-PDU Number field either is not present, or, if present, shall not be interpreted.
|
||||||
// When it is set to '1', the N-PDU Number field is present, and shall be interpreted.
|
// When it is set to '1', the N-PDU Number field is present, and shall be interpreted.
|
||||||
pMsg->npduNumFlag = NW_FALSE;
|
pMsg->npduNumFlag = NW_FALSE;
|
||||||
pMsg->npduNum = 0x00;
|
pMsg->npduNum = 0x00;
|
||||||
// Message Type: This field indicates the type of GTP-U message.
|
// Message Type: This field indicates the type of GTP-U message.
|
||||||
pMsg->msgType = NW_GTP_GPDU;
|
pMsg->msgType = NW_GTP_GPDU;
|
||||||
// Length: This field indicates the length in octets of the payload, i.e. the rest of the packet following the
|
// Length: This field indicates the length in octets of the payload, i.e. the rest of the packet following the
|
||||||
// mandatory part of the GTP header (that is the first 8 octets).
|
// mandatory part of the GTP header (that is the first 8 octets).
|
||||||
// The Sequence Number, the N-PDU Number or any Extension headers shall be considered to be part of the payload,
|
// The Sequence Number, the N-PDU Number or any Extension headers shall be considered to be part of the payload,
|
||||||
// i.e. included in the length count.
|
// i.e. included in the length count.
|
||||||
//header_len = ((pMsg->seqNumFlag || pMsg->npduNumFlag || pMsg->extHdrFlag ) ?
|
//header_len = ((pMsg->seqNumFlag || pMsg->npduNumFlag || pMsg->extHdrFlag ) ?
|
||||||
// NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE : NW_GTPV1U_EPC_MIN_HEADER_SIZE);
|
// NW_GTPV1U_EPC_SPECIFIC_HEADER_SIZE : NW_GTPV1U_EPC_MIN_HEADER_SIZE);
|
||||||
pMsg->msgLen = msgExtraLen + tpduLength;
|
pMsg->msgLen = msgExtraLen + tpduLength;
|
||||||
|
|
||||||
// Tunnel Endpoint Identifier (TEID): This field unambiguously identifies a tunnel endpoint in the receiving
|
// Tunnel Endpoint Identifier (TEID): This field unambiguously identifies a tunnel endpoint in the receiving
|
||||||
// GTP-U protocol entity. The receiving end side of a GTP tunnel locally assigns the TEID value the transmitting
|
// GTP-U protocol entity. The receiving end side of a GTP tunnel locally assigns the TEID value the transmitting
|
||||||
// side has to use. The TEID shall be used by the receiving entity to find the PDP context, except for the
|
// side has to use. The TEID shall be used by the receiving entity to find the PDP context, except for the
|
||||||
// following cases:
|
// following cases:
|
||||||
// - The Echo Request/Response and Supported Extension Headers notification messages, where the Tunnel
|
// - The Echo Request/Response and Supported Extension Headers notification messages, where the Tunnel
|
||||||
// Endpoint Identifier shall be set to all zeroes.
|
// Endpoint Identifier shall be set to all zeroes.
|
||||||
// - The Error Indication message where the Tunnel Endpoint Identifier shall be set to all zeros.
|
// - The Error Indication message where the Tunnel Endpoint Identifier shall be set to all zeros.
|
||||||
pMsg->teid = teid;
|
pMsg->teid = teid;
|
||||||
pMsg->nextExtHdrType= 0x00;
|
pMsg->nextExtHdrType= 0x00;
|
||||||
|
|
||||||
//memcpy(pMsg->msgBuf + header_len, tpdu, tpduLength);
|
//memcpy(pMsg->msgBuf + header_len, tpdu, tpduLength);
|
||||||
*phMsg = (NwGtpv1uMsgHandleT) pMsg;
|
*phMsg = (NwGtpv1uMsgHandleT) pMsg;
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_GTPV1U_FAILURE;
|
return NW_GTPV1U_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
@@ -212,23 +214,24 @@ nwGtpv1uMsgFromMsgNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
|||||||
NW_IN NwGtpv1uMsgHandleT hMsg,
|
NW_IN NwGtpv1uMsgHandleT hMsg,
|
||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg)
|
NW_OUT NwGtpv1uMsgHandleT *phMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle;
|
NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle;
|
||||||
NwGtpv1uMsgT *pMsg;
|
NwGtpv1uMsgT *pMsg;
|
||||||
|
|
||||||
if(gpGtpv1uMsgPool) {
|
if(gpGtpv1uMsgPool) {
|
||||||
pMsg = gpGtpv1uMsgPool;
|
pMsg = gpGtpv1uMsgPool;
|
||||||
gpGtpv1uMsgPool = gpGtpv1uMsgPool->next;
|
gpGtpv1uMsgPool = gpGtpv1uMsgPool->next;
|
||||||
} else {
|
} else {
|
||||||
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *);
|
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if(pMsg) {
|
if(pMsg) {
|
||||||
memcpy(pMsg, (NwGtpv1uMsgT *)hMsg, sizeof(NwGtpv1uMsgT));
|
memcpy(pMsg, (NwGtpv1uMsgT *)hMsg, sizeof(NwGtpv1uMsgT));
|
||||||
*phMsg = (NwGtpv1uMsgHandleT) pMsg;
|
*phMsg = (NwGtpv1uMsgHandleT) pMsg;
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
return NW_GTPV1U_FAILURE;
|
|
||||||
|
return NW_GTPV1U_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
@@ -237,61 +240,63 @@ nwGtpv1uMsgFromBufferNew( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
|||||||
NW_IN NwU32T bufLen,
|
NW_IN NwU32T bufLen,
|
||||||
NW_OUT NwGtpv1uMsgHandleT *phMsg)
|
NW_OUT NwGtpv1uMsgHandleT *phMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle;
|
NwGtpv1uStackT *pStack = (NwGtpv1uStackT *) hGtpuStackHandle;
|
||||||
NwGtpv1uMsgT *pMsg;
|
NwGtpv1uMsgT *pMsg;
|
||||||
|
|
||||||
if(gpGtpv1uMsgPool) {
|
if(gpGtpv1uMsgPool) {
|
||||||
pMsg = gpGtpv1uMsgPool;
|
pMsg = gpGtpv1uMsgPool;
|
||||||
gpGtpv1uMsgPool = gpGtpv1uMsgPool->next;
|
gpGtpv1uMsgPool = gpGtpv1uMsgPool->next;
|
||||||
} else {
|
} else {
|
||||||
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *);
|
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uMsgT), pMsg, NwGtpv1uMsgT *);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if(pMsg) {
|
||||||
|
pMsg->msgBuf = pBuf;
|
||||||
|
|
||||||
|
pMsg->version = ((*pBuf) & 0xE0) >> 5;
|
||||||
|
pMsg->protocolType = ((*pBuf) & 0x10) >> 4;
|
||||||
|
pMsg->extHdrFlag = ((*pBuf) & 0x04) >> 2;
|
||||||
|
pMsg->seqNumFlag = ((*pBuf) & 0x02) >> 1;
|
||||||
|
pMsg->npduNumFlag = ((*pBuf) & 0x01);
|
||||||
|
pBuf++;
|
||||||
|
|
||||||
|
pMsg->msgType = *(pBuf);
|
||||||
|
pBuf++;
|
||||||
|
|
||||||
|
pBuf += 2;
|
||||||
|
|
||||||
|
pMsg->teid = ntohl(*((NwU32T *)pBuf));
|
||||||
|
pBuf += 4;
|
||||||
|
|
||||||
|
if(pMsg->extHdrFlag || pMsg->seqNumFlag || pMsg->npduNumFlag) {
|
||||||
|
pMsg->seqNum = ntohs(*(((NwU16T *)pBuf)));
|
||||||
|
pBuf += 2;
|
||||||
|
pMsg->npduNum = *(pBuf++);
|
||||||
|
pMsg->nextExtHdrType = *(pBuf++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pMsg->msgBufOffset = (NwU32T)(pBuf - pMsg->msgBuf);
|
||||||
if(pMsg) {
|
pMsg->msgBufLen = bufLen - pMsg->msgBufOffset;
|
||||||
pMsg->msgBuf = pBuf;
|
pMsg->msgLen = bufLen;
|
||||||
|
|
||||||
pMsg->version = ((*pBuf) & 0xE0) >> 5;
|
|
||||||
pMsg->protocolType = ((*pBuf) & 0x10) >> 4;
|
|
||||||
pMsg->extHdrFlag = ((*pBuf) & 0x04) >> 2;
|
|
||||||
pMsg->seqNumFlag = ((*pBuf) & 0x02) >> 1;
|
|
||||||
pMsg->npduNumFlag = ((*pBuf) & 0x01);
|
|
||||||
pBuf++;
|
|
||||||
|
|
||||||
pMsg->msgType = *(pBuf);
|
|
||||||
pBuf++;
|
|
||||||
|
|
||||||
pBuf += 2;
|
|
||||||
|
|
||||||
pMsg->teid = ntohl(*((NwU32T *)pBuf));
|
|
||||||
pBuf += 4;
|
|
||||||
|
|
||||||
if(pMsg->extHdrFlag || pMsg->seqNumFlag || pMsg->npduNumFlag) {
|
|
||||||
pMsg->seqNum = ntohs(*(((NwU16T *)pBuf)));
|
|
||||||
pBuf += 2;
|
|
||||||
pMsg->npduNum = *(pBuf++);
|
|
||||||
pMsg->nextExtHdrType = *(pBuf++);
|
|
||||||
}
|
|
||||||
pMsg->msgBufOffset = (NwU32T)(pBuf - pMsg->msgBuf);
|
|
||||||
pMsg->msgBufLen = bufLen - pMsg->msgBufOffset;
|
|
||||||
pMsg->msgLen = bufLen;
|
|
||||||
#if defined(LOG_GTPU) && LOG_GTPU > 0
|
#if defined(LOG_GTPU) && LOG_GTPU > 0
|
||||||
GTPU_DEBUG("nwGtpv1uMsgFromBufferNew() msgLen %u msgBufLen %u msgBufOffset %u ",
|
GTPU_DEBUG("nwGtpv1uMsgFromBufferNew() msgLen %u msgBufLen %u msgBufOffset %u ",
|
||||||
pMsg->msgLen, pMsg->msgBufLen, pMsg->msgBufOffset);
|
pMsg->msgLen, pMsg->msgBufLen, pMsg->msgBufOffset);
|
||||||
#endif
|
#endif
|
||||||
*phMsg = (NwGtpv1uMsgHandleT) pMsg;
|
*phMsg = (NwGtpv1uMsgHandleT) pMsg;
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
return NW_GTPV1U_FAILURE;
|
|
||||||
|
return NW_GTPV1U_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgDelete( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
nwGtpv1uMsgDelete( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
||||||
NW_IN NwGtpv1uMsgHandleT hMsg)
|
NW_IN NwGtpv1uMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
((NwGtpv1uMsgT *)hMsg)->next = gpGtpv1uMsgPool;
|
((NwGtpv1uMsgT *)hMsg)->next = gpGtpv1uMsgPool;
|
||||||
gpGtpv1uMsgPool = (NwGtpv1uMsgT *) hMsg;
|
gpGtpv1uMsgPool = (NwGtpv1uMsgT *) hMsg;
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -304,12 +309,12 @@ nwGtpv1uMsgDelete( NW_IN NwGtpv1uStackHandleT hGtpuStackHandle,
|
|||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgSetTeid(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T teid)
|
nwGtpv1uMsgSetTeid(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T teid)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
||||||
thiz->teid = teid;
|
thiz->teid = teid;
|
||||||
#if defined(LOG_GTPU) && LOG_GTPU > 0
|
#if defined(LOG_GTPU) && LOG_GTPU > 0
|
||||||
GTPU_DEBUG("nwGtpv1uMsgSetTeid() teid %u", teid);
|
GTPU_DEBUG("nwGtpv1uMsgSetTeid() teid %u", teid);
|
||||||
#endif
|
#endif
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -322,9 +327,9 @@ nwGtpv1uMsgSetTeid(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T teid)
|
|||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgSetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T seqNum)
|
nwGtpv1uMsgSetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T seqNum)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
||||||
thiz->seqNum = seqNum;
|
thiz->seqNum = seqNum;
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -336,8 +341,8 @@ nwGtpv1uMsgSetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg, NwU32T seqNum)
|
|||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv1uMsgGetTeid(NW_IN NwGtpv1uMsgHandleT hMsg)
|
nwGtpv1uMsgGetTeid(NW_IN NwGtpv1uMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
||||||
return (thiz->teid);
|
return (thiz->teid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -350,8 +355,8 @@ nwGtpv1uMsgGetTeid(NW_IN NwGtpv1uMsgHandleT hMsg)
|
|||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv1uMsgGetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg)
|
nwGtpv1uMsgGetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
||||||
return (thiz->seqNum);
|
return (thiz->seqNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -363,8 +368,8 @@ nwGtpv1uMsgGetSeqNumber(NW_IN NwGtpv1uMsgHandleT hMsg)
|
|||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv1uMsgGetMsgType(NW_IN NwGtpv1uMsgHandleT hMsg)
|
nwGtpv1uMsgGetMsgType(NW_IN NwGtpv1uMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
||||||
return (thiz->msgType);
|
return (thiz->msgType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -377,29 +382,29 @@ NwGtpv1uRcT
|
|||||||
nwGtpv1uMsgGetTpdu(NW_IN NwGtpv1uMsgHandleT hMsg, NwU8T *pTpduBuf,
|
nwGtpv1uMsgGetTpdu(NW_IN NwGtpv1uMsgHandleT hMsg, NwU8T *pTpduBuf,
|
||||||
NwU32T *pTpduLength)
|
NwU32T *pTpduLength)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
||||||
NwU8T headerLength = ((thiz->seqNumFlag || thiz->extHdrFlag
|
NwU8T headerLength = ((thiz->seqNumFlag || thiz->extHdrFlag
|
||||||
|| thiz->npduNumFlag) ? 12 : 8);
|
|| thiz->npduNumFlag) ? 12 : 8);
|
||||||
|
|
||||||
*pTpduLength = thiz->msgLen - headerLength;
|
*pTpduLength = thiz->msgLen - headerLength;
|
||||||
memcpy(pTpduBuf, thiz->msgBuf + headerLength, *pTpduLength);
|
memcpy(pTpduBuf, thiz->msgBuf + headerLength, *pTpduLength);
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwU8T *
|
NwU8T *
|
||||||
nwGtpv1uMsgGetTpduHandle(NW_IN NwGtpv1uMsgHandleT hMsg)
|
nwGtpv1uMsgGetTpduHandle(NW_IN NwGtpv1uMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
||||||
return (thiz->msgBuf + ((thiz->seqNumFlag || thiz->extHdrFlag
|
return (thiz->msgBuf + ((thiz->seqNumFlag || thiz->extHdrFlag
|
||||||
|| thiz->npduNumFlag) ? 12 : 8));
|
|| thiz->npduNumFlag) ? 12 : 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv1uMsgGetTpduLength(NW_IN NwGtpv1uMsgHandleT hMsg)
|
nwGtpv1uMsgGetTpduLength(NW_IN NwGtpv1uMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *thiz = (NwGtpv1uMsgT *) hMsg;
|
||||||
return (thiz->msgLen - ((thiz->seqNumFlag || thiz->extHdrFlag
|
return (thiz->msgLen - ((thiz->seqNumFlag || thiz->extHdrFlag
|
||||||
|| thiz->npduNumFlag) ? 12 : 8));
|
|| thiz->npduNumFlag) ? 12 : 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
@@ -407,17 +412,17 @@ nwGtpv1uMsgAddIeTV1(NW_IN NwGtpv1uMsgHandleT hMsg,
|
|||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T value)
|
NW_IN NwU8T value)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
||||||
NwGtpv1uIeTv1T *pIe;
|
NwGtpv1uIeTv1T *pIe;
|
||||||
|
|
||||||
pIe = (NwGtpv1uIeTv1T *) (pMsg->msgBuf + pMsg->msgLen);
|
pIe = (NwGtpv1uIeTv1T *) (pMsg->msgBuf + pMsg->msgLen);
|
||||||
|
|
||||||
pIe->t = type;
|
pIe->t = type;
|
||||||
pIe->v = value;
|
pIe->v = value;
|
||||||
|
|
||||||
pMsg->msgLen += sizeof(NwGtpv1uIeTv1T);
|
pMsg->msgLen += sizeof(NwGtpv1uIeTv1T);
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
@@ -426,17 +431,17 @@ nwGtpv1uMsgAddIeTV2(NW_IN NwGtpv1uMsgHandleT hMsg,
|
|||||||
NW_IN NwU16T length,
|
NW_IN NwU16T length,
|
||||||
NW_IN NwU16T value)
|
NW_IN NwU16T value)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
||||||
NwGtpv1uIeTv2T *pIe;
|
NwGtpv1uIeTv2T *pIe;
|
||||||
|
|
||||||
pIe = (NwGtpv1uIeTv2T *) (pMsg->msgBuf + pMsg->msgLen);
|
pIe = (NwGtpv1uIeTv2T *) (pMsg->msgBuf + pMsg->msgLen);
|
||||||
|
|
||||||
pIe->t = type;
|
pIe->t = type;
|
||||||
pIe->v = htons(value);
|
pIe->v = htons(value);
|
||||||
|
|
||||||
pMsg->msgLen += sizeof(NwGtpv1uIeTv2T);
|
pMsg->msgLen += sizeof(NwGtpv1uIeTv2T);
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
@@ -445,17 +450,17 @@ nwGtpv1uMsgAddIeTV4(NW_IN NwGtpv1uMsgHandleT hMsg,
|
|||||||
NW_IN NwU16T length,
|
NW_IN NwU16T length,
|
||||||
NW_IN NwU32T value)
|
NW_IN NwU32T value)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
||||||
NwGtpv1uIeTv4T *pIe;
|
NwGtpv1uIeTv4T *pIe;
|
||||||
|
|
||||||
pIe = (NwGtpv1uIeTv4T *) (pMsg->msgBuf + pMsg->msgLen);
|
pIe = (NwGtpv1uIeTv4T *) (pMsg->msgBuf + pMsg->msgLen);
|
||||||
|
|
||||||
pIe->t = type;
|
pIe->t = type;
|
||||||
pIe->v = htonl(value);
|
pIe->v = htonl(value);
|
||||||
|
|
||||||
pMsg->msgLen += sizeof(NwGtpv1uIeTv4T);
|
pMsg->msgLen += sizeof(NwGtpv1uIeTv4T);
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
@@ -464,76 +469,81 @@ nwGtpv1uMsgAddIe(NW_IN NwGtpv1uMsgHandleT hMsg,
|
|||||||
NW_IN NwU16T length,
|
NW_IN NwU16T length,
|
||||||
NW_IN NwU8T *pVal)
|
NW_IN NwU8T *pVal)
|
||||||
{
|
{
|
||||||
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
||||||
NwGtpv1uIeTlvT *pIe;
|
NwGtpv1uIeTlvT *pIe;
|
||||||
|
|
||||||
pIe = (NwGtpv1uIeTlvT *) (pMsg->msgBuf + pMsg->msgLen);
|
pIe = (NwGtpv1uIeTlvT *) (pMsg->msgBuf + pMsg->msgLen);
|
||||||
|
|
||||||
pIe->t = type;
|
pIe->t = type;
|
||||||
pIe->l = htons(length);
|
pIe->l = htons(length);
|
||||||
|
|
||||||
memcpy(pIe + 4, pVal, length);
|
memcpy(pIe + 4, pVal, length);
|
||||||
pMsg->msgLen += (4 + length);
|
pMsg->msgLen += (4 + length);
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uMsgHexDump(NwGtpv1uMsgHandleT hMsg, FILE *fp)
|
nwGtpv1uMsgHexDump(NwGtpv1uMsgHandleT hMsg, FILE *fp)
|
||||||
{
|
{
|
||||||
|
|
||||||
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
NwGtpv1uMsgT *pMsg = (NwGtpv1uMsgT *) hMsg;
|
||||||
NwU8T *data = pMsg->msgBuf;
|
NwU8T *data = pMsg->msgBuf;
|
||||||
NwU32T size = pMsg->msgLen;
|
NwU32T size = pMsg->msgLen;
|
||||||
|
|
||||||
unsigned char *p = (unsigned char *)data;
|
unsigned char *p = (unsigned char *)data;
|
||||||
unsigned char c;
|
unsigned char c;
|
||||||
int n;
|
int n;
|
||||||
char bytestr[4] = {0};
|
char bytestr[4] = {0};
|
||||||
char addrstr[10] = {0};
|
char addrstr[10] = {0};
|
||||||
char hexstr[ 16*3 + 5] = {0};
|
char hexstr[ 16*3 + 5] = {0};
|
||||||
char charstr[16*1 + 5] = {0};
|
char charstr[16*1 + 5] = {0};
|
||||||
fprintf((FILE *)fp, "\n");
|
fprintf((FILE *)fp, "\n");
|
||||||
for(n=1; n<=size; n++) {
|
|
||||||
if (n%16 == 1) {
|
|
||||||
/* store address for this line */
|
|
||||||
snprintf(addrstr, sizeof(addrstr), "%.4lx",
|
|
||||||
(p-data) );
|
|
||||||
}
|
|
||||||
|
|
||||||
c = *p;
|
for(n=1; n<=size; n++) {
|
||||||
if (isalnum(c) == 0) {
|
if (n%16 == 1) {
|
||||||
c = '.';
|
/* store address for this line */
|
||||||
}
|
snprintf(addrstr, sizeof(addrstr), "%.4lx",
|
||||||
|
(p-data) );
|
||||||
/* store hex str (for left side) */
|
|
||||||
snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
|
|
||||||
strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
|
|
||||||
|
|
||||||
/* store char str (for right side) */
|
|
||||||
snprintf(bytestr, sizeof(bytestr), "%c", c);
|
|
||||||
strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
|
|
||||||
if(n%16 == 0) {
|
|
||||||
/* line completed */
|
|
||||||
fprintf((FILE *)fp, "[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
|
|
||||||
hexstr[0] = 0;
|
|
||||||
charstr[0] = 0;
|
|
||||||
} else if(n%8 == 0) {
|
|
||||||
/* half line: add whitespaces */
|
|
||||||
strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1);
|
|
||||||
strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
|
|
||||||
}
|
|
||||||
p++; /* next byte */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strlen(hexstr) > 0) {
|
c = *p;
|
||||||
/* print rest of buffer if not empty */
|
|
||||||
fprintf((FILE *)fp, "[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
|
|
||||||
|
|
||||||
|
if (isalnum(c) == 0) {
|
||||||
|
c = '.';
|
||||||
}
|
}
|
||||||
fprintf((FILE *)fp, "\n");
|
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
/* store hex str (for left side) */
|
||||||
|
snprintf(bytestr, sizeof(bytestr), "%02X ", *p);
|
||||||
|
strncat(hexstr, bytestr, sizeof(hexstr)-strlen(hexstr)-1);
|
||||||
|
|
||||||
|
/* store char str (for right side) */
|
||||||
|
snprintf(bytestr, sizeof(bytestr), "%c", c);
|
||||||
|
strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
|
||||||
|
|
||||||
|
if(n%16 == 0) {
|
||||||
|
/* line completed */
|
||||||
|
fprintf((FILE *)fp, "[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
|
||||||
|
hexstr[0] = 0;
|
||||||
|
charstr[0] = 0;
|
||||||
|
} else if(n%8 == 0) {
|
||||||
|
/* half line: add whitespaces */
|
||||||
|
strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1);
|
||||||
|
strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
|
||||||
|
}
|
||||||
|
|
||||||
|
p++; /* next byte */
|
||||||
|
}
|
||||||
|
|
||||||
|
if (strlen(hexstr) > 0) {
|
||||||
|
/* print rest of buffer if not empty */
|
||||||
|
fprintf((FILE *)fp, "[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf((FILE *)fp, "\n");
|
||||||
|
|
||||||
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -64,61 +64,62 @@ static NwGtpv1uTrxnT *gpGtpv1uTrxnPool = NULL;
|
|||||||
static NwGtpv1uRcT
|
static NwGtpv1uRcT
|
||||||
nwGtpv1uTrxnSendMsgRetransmission(NwGtpv1uTrxnT *thiz)
|
nwGtpv1uTrxnSendMsgRetransmission(NwGtpv1uTrxnT *thiz)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
|
|
||||||
NW_ASSERT(thiz);
|
NW_ASSERT(thiz);
|
||||||
NW_ASSERT(thiz->pMsg);
|
NW_ASSERT(thiz->pMsg);
|
||||||
|
|
||||||
rc = thiz->pStack->udp.udpDataReqCallback(thiz->pStack->udp.hUdp,
|
rc = thiz->pStack->udp.udpDataReqCallback(thiz->pStack->udp.hUdp,
|
||||||
thiz->pMsg->msgBuf,
|
thiz->pMsg->msgBuf,
|
||||||
thiz->pMsg->msgLen,
|
thiz->pMsg->msgLen,
|
||||||
thiz->pMsg->msgBufOffset,
|
thiz->pMsg->msgBufOffset,
|
||||||
thiz->peerIp,
|
thiz->peerIp,
|
||||||
thiz->peerPort);
|
thiz->peerPort);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NwGtpv1uRcT
|
static NwGtpv1uRcT
|
||||||
nwGtpv1uTrxnPeerRspTimeout(void *arg)
|
nwGtpv1uTrxnPeerRspTimeout(void *arg)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||||
NwGtpv1uTrxnT *thiz;
|
NwGtpv1uTrxnT *thiz;
|
||||||
NwGtpv1uStackT *pStack;
|
NwGtpv1uStackT *pStack;
|
||||||
NwGtpv1uTimeoutInfoT *timeoutInfo = arg;
|
NwGtpv1uTimeoutInfoT *timeoutInfo = arg;
|
||||||
|
|
||||||
thiz = ((NwGtpv1uTrxnT *)timeoutInfo->timeoutArg);
|
thiz = ((NwGtpv1uTrxnT *)timeoutInfo->timeoutArg);
|
||||||
pStack = thiz->pStack;
|
pStack = thiz->pStack;
|
||||||
|
|
||||||
NW_ASSERT(pStack);
|
NW_ASSERT(pStack);
|
||||||
|
|
||||||
NW_LOG(pStack, NW_LOG_LEVEL_WARN, "T3 timer expired for transaction 0x%p",
|
NW_LOG(pStack, NW_LOG_LEVEL_WARN, "T3 timer expired for transaction 0x%p",
|
||||||
thiz);
|
thiz);
|
||||||
|
|
||||||
rc = nwGtpv1uTrxnSendMsgRetransmission(thiz);
|
rc = nwGtpv1uTrxnSendMsgRetransmission(thiz);
|
||||||
|
|
||||||
if(thiz->maxRetries) {
|
if(thiz->maxRetries) {
|
||||||
rc = pStack->tmrMgr.tmrStartCallback(pStack->tmrMgr.tmrMgrHandle,
|
rc = pStack->tmrMgr.tmrStartCallback(pStack->tmrMgr.tmrMgrHandle,
|
||||||
thiz->t3Timer, 0, NW_GTPV1U_TMR_TYPE_ONE_SHOT, (void *)timeoutInfo,
|
thiz->t3Timer, 0, NW_GTPV1U_TMR_TYPE_ONE_SHOT, (void *)timeoutInfo,
|
||||||
&thiz->hRspTmr);
|
&thiz->hRspTmr);
|
||||||
thiz->maxRetries--;
|
thiz->maxRetries--;
|
||||||
} else {
|
} else {
|
||||||
NwGtpv1uUlpApiT ulpApi;
|
NwGtpv1uUlpApiT ulpApi;
|
||||||
ulpApi.apiType = NW_GTPV1U_ULP_API_RSP_FAILURE;
|
ulpApi.apiType = NW_GTPV1U_ULP_API_RSP_FAILURE;
|
||||||
ulpApi.apiInfo.recvMsgInfo.msgType = nwGtpv1uMsgGetMsgType((
|
ulpApi.apiInfo.recvMsgInfo.msgType = nwGtpv1uMsgGetMsgType((
|
||||||
NwGtpv1uMsgHandleT)thiz->pMsg);
|
NwGtpv1uMsgHandleT)thiz->pMsg);
|
||||||
ulpApi.apiInfo.recvMsgInfo.hUlpTrxn = thiz->hUlpTrxn;
|
ulpApi.apiInfo.recvMsgInfo.hUlpTrxn = thiz->hUlpTrxn;
|
||||||
ulpApi.apiInfo.recvMsgInfo.peerIp = thiz->peerIp;
|
ulpApi.apiInfo.recvMsgInfo.peerIp = thiz->peerIp;
|
||||||
ulpApi.apiInfo.recvMsgInfo.peerPort = thiz->peerPort;
|
ulpApi.apiInfo.recvMsgInfo.peerPort = thiz->peerPort;
|
||||||
thiz->hRspTmr = 0;
|
thiz->hRspTmr = 0;
|
||||||
|
|
||||||
rc = nwGtpv1uTrxnDelete(&thiz);
|
rc = nwGtpv1uTrxnDelete(&thiz);
|
||||||
NW_ASSERT(rc == NW_GTPV1U_OK);
|
NW_ASSERT(rc == NW_GTPV1U_OK);
|
||||||
|
|
||||||
rc = pStack->ulp.ulpReqCallback(pStack->ulp.hUlp, &ulpApi);
|
rc = pStack->ulp.ulpReqCallback(pStack->ulp.hUlp, &ulpApi);
|
||||||
NW_ASSERT(rc == NW_GTPV1U_OK);
|
NW_ASSERT(rc == NW_GTPV1U_OK);
|
||||||
}
|
}
|
||||||
return rc;
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -133,21 +134,21 @@ static NwGtpv1uRcT
|
|||||||
nwGtpv1uTrxnStartPeerRspTimer(NwGtpv1uTrxnT *thiz,
|
nwGtpv1uTrxnStartPeerRspTimer(NwGtpv1uTrxnT *thiz,
|
||||||
NwGtpv1uRcT (*timeoutCallbackFunc)(void *))
|
NwGtpv1uRcT (*timeoutCallbackFunc)(void *))
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
NwGtpv1uTimeoutInfoT *timeoutInfo;
|
NwGtpv1uTimeoutInfoT *timeoutInfo;
|
||||||
|
|
||||||
NW_ASSERT(thiz->pStack->tmrMgr.tmrStartCallback != NULL);
|
NW_ASSERT(thiz->pStack->tmrMgr.tmrStartCallback != NULL);
|
||||||
|
|
||||||
timeoutInfo = &thiz->peerRspTimeoutInfo;
|
timeoutInfo = &thiz->peerRspTimeoutInfo;
|
||||||
timeoutInfo->timeoutArg = thiz;
|
timeoutInfo->timeoutArg = thiz;
|
||||||
timeoutInfo->timeoutCallbackFunc = timeoutCallbackFunc;
|
timeoutInfo->timeoutCallbackFunc = timeoutCallbackFunc;
|
||||||
timeoutInfo->hStack = (NwGtpv1uStackHandleT)thiz->pStack;
|
timeoutInfo->hStack = (NwGtpv1uStackHandleT)thiz->pStack;
|
||||||
|
|
||||||
rc = thiz->pStack->tmrMgr.tmrStartCallback(thiz->pStack->tmrMgr.tmrMgrHandle,
|
rc = thiz->pStack->tmrMgr.tmrStartCallback(thiz->pStack->tmrMgr.tmrMgrHandle,
|
||||||
thiz->t3Timer, 0, NW_GTPV1U_TMR_TYPE_ONE_SHOT, (void *)timeoutInfo,
|
thiz->t3Timer, 0, NW_GTPV1U_TMR_TYPE_ONE_SHOT, (void *)timeoutInfo,
|
||||||
&thiz->hRspTmr);
|
&thiz->hRspTmr);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -160,16 +161,16 @@ nwGtpv1uTrxnStartPeerRspTimer(NwGtpv1uTrxnT *thiz,
|
|||||||
static NwGtpv1uRcT
|
static NwGtpv1uRcT
|
||||||
nwGtpv1uTrxnStopPeerRspTimer(NwGtpv1uTrxnT *thiz)
|
nwGtpv1uTrxnStopPeerRspTimer(NwGtpv1uTrxnT *thiz)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
|
|
||||||
NW_ASSERT(thiz->pStack->tmrMgr.tmrStopCallback != NULL);
|
NW_ASSERT(thiz->pStack->tmrMgr.tmrStopCallback != NULL);
|
||||||
|
|
||||||
rc = thiz->pStack->tmrMgr.tmrStopCallback(thiz->pStack->tmrMgr.tmrMgrHandle,
|
rc = thiz->pStack->tmrMgr.tmrStopCallback(thiz->pStack->tmrMgr.tmrMgrHandle,
|
||||||
thiz->hRspTmr);
|
thiz->hRspTmr);
|
||||||
|
|
||||||
thiz->hRspTmr = 0;
|
thiz->hRspTmr = 0;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
@@ -187,37 +188,38 @@ NwGtpv1uRcT
|
|||||||
nwGtpv1uTrxnNew( NW_IN NwGtpv1uStackT *thiz,
|
nwGtpv1uTrxnNew( NW_IN NwGtpv1uStackT *thiz,
|
||||||
NW_OUT NwGtpv1uTrxnT **ppTrxn)
|
NW_OUT NwGtpv1uTrxnT **ppTrxn)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||||
NwGtpv1uTrxnT *pTrxn;
|
NwGtpv1uTrxnT *pTrxn;
|
||||||
|
|
||||||
if(gpGtpv1uTrxnPool) {
|
if(gpGtpv1uTrxnPool) {
|
||||||
pTrxn = gpGtpv1uTrxnPool;
|
pTrxn = gpGtpv1uTrxnPool;
|
||||||
gpGtpv1uTrxnPool = gpGtpv1uTrxnPool->next;
|
gpGtpv1uTrxnPool = gpGtpv1uTrxnPool->next;
|
||||||
} else {
|
} else {
|
||||||
NW_GTPV1U_MALLOC(thiz, sizeof(NwGtpv1uTrxnT), pTrxn, NwGtpv1uTrxnT *);
|
NW_GTPV1U_MALLOC(thiz, sizeof(NwGtpv1uTrxnT), pTrxn, NwGtpv1uTrxnT *);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pTrxn) {
|
||||||
|
pTrxn->maxRetries = 2;
|
||||||
|
pTrxn->pStack = thiz;
|
||||||
|
pTrxn->t3Timer = 2;
|
||||||
|
pTrxn->seqNum = thiz->seq;
|
||||||
|
|
||||||
|
/* Increment sequence number */
|
||||||
|
thiz->seq++;
|
||||||
|
|
||||||
|
if(thiz->seq == 0x800000) {
|
||||||
|
thiz->seq = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTrxn) {
|
} else {
|
||||||
pTrxn->maxRetries = 2;
|
rc = NW_GTPV1U_FAILURE;
|
||||||
pTrxn->pStack = thiz;
|
}
|
||||||
pTrxn->t3Timer = 2;
|
|
||||||
pTrxn->seqNum = thiz->seq;
|
|
||||||
|
|
||||||
/* Increment sequence number */
|
NW_LOG(thiz, NW_LOG_LEVEL_DEBG, "Created transaction 0x%p", pTrxn);
|
||||||
thiz->seq++;
|
|
||||||
if(thiz->seq == 0x800000) {
|
|
||||||
thiz->seq = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
*ppTrxn = pTrxn;
|
||||||
rc = NW_GTPV1U_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
NW_LOG(thiz, NW_LOG_LEVEL_DEBG, "Created transaction 0x%p", pTrxn);
|
return rc;
|
||||||
|
|
||||||
*ppTrxn = pTrxn;
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -233,32 +235,32 @@ nwGtpv1uTrxnWithSeqNew( NW_IN NwGtpv1uStackT *thiz,
|
|||||||
NW_IN NwU32T seqNum,
|
NW_IN NwU32T seqNum,
|
||||||
NW_OUT NwGtpv1uTrxnT **ppTrxn)
|
NW_OUT NwGtpv1uTrxnT **ppTrxn)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||||
NwGtpv1uTrxnT *pTrxn;
|
NwGtpv1uTrxnT *pTrxn;
|
||||||
|
|
||||||
if(gpGtpv1uTrxnPool) {
|
if(gpGtpv1uTrxnPool) {
|
||||||
pTrxn = gpGtpv1uTrxnPool;
|
pTrxn = gpGtpv1uTrxnPool;
|
||||||
gpGtpv1uTrxnPool = gpGtpv1uTrxnPool->next;
|
gpGtpv1uTrxnPool = gpGtpv1uTrxnPool->next;
|
||||||
} else {
|
} else {
|
||||||
NW_GTPV1U_MALLOC(thiz, sizeof(NwGtpv1uTrxnT), pTrxn, NwGtpv1uTrxnT *);
|
NW_GTPV1U_MALLOC(thiz, sizeof(NwGtpv1uTrxnT), pTrxn, NwGtpv1uTrxnT *);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (pTrxn) {
|
if (pTrxn) {
|
||||||
pTrxn->maxRetries = 2;
|
pTrxn->maxRetries = 2;
|
||||||
pTrxn->pStack = thiz;
|
pTrxn->pStack = thiz;
|
||||||
pTrxn->t3Timer = 2;
|
pTrxn->t3Timer = 2;
|
||||||
pTrxn->seqNum = seqNum;
|
pTrxn->seqNum = seqNum;
|
||||||
pTrxn->pMsg = NULL;
|
pTrxn->pMsg = NULL;
|
||||||
} else {
|
} else {
|
||||||
rc = NW_GTPV1U_FAILURE;
|
rc = NW_GTPV1U_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NW_LOG(thiz, NW_LOG_LEVEL_DEBG, "Created transaction 0x%p", pTrxn);
|
NW_LOG(thiz, NW_LOG_LEVEL_DEBG, "Created transaction 0x%p", pTrxn);
|
||||||
|
|
||||||
*ppTrxn = pTrxn;
|
*ppTrxn = pTrxn;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -270,30 +272,30 @@ nwGtpv1uTrxnWithSeqNew( NW_IN NwGtpv1uStackT *thiz,
|
|||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwGtpv1uTrxnDelete( NW_INOUT NwGtpv1uTrxnT **pthiz)
|
nwGtpv1uTrxnDelete( NW_INOUT NwGtpv1uTrxnT **pthiz)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||||
NwGtpv1uStackT *pStack;
|
NwGtpv1uStackT *pStack;
|
||||||
NwGtpv1uTrxnT *thiz = *pthiz;
|
NwGtpv1uTrxnT *thiz = *pthiz;
|
||||||
|
|
||||||
pStack = thiz->pStack;
|
pStack = thiz->pStack;
|
||||||
|
|
||||||
if(thiz->hRspTmr) {
|
if(thiz->hRspTmr) {
|
||||||
rc = nwGtpv1uTrxnStopPeerRspTimer(thiz);
|
rc = nwGtpv1uTrxnStopPeerRspTimer(thiz);
|
||||||
NW_ASSERT(rc == NW_GTPV1U_OK);
|
NW_ASSERT(rc == NW_GTPV1U_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thiz->pMsg) {
|
if(thiz->pMsg) {
|
||||||
rc = nwGtpv1uMsgDelete((NwGtpv1uStackHandleT)pStack,
|
rc = nwGtpv1uMsgDelete((NwGtpv1uStackHandleT)pStack,
|
||||||
(NwGtpv1uMsgHandleT)thiz->pMsg);
|
(NwGtpv1uMsgHandleT)thiz->pMsg);
|
||||||
NW_ASSERT(rc == NW_GTPV1U_OK);
|
NW_ASSERT(rc == NW_GTPV1U_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
thiz->next = gpGtpv1uTrxnPool;
|
thiz->next = gpGtpv1uTrxnPool;
|
||||||
gpGtpv1uTrxnPool = thiz;
|
gpGtpv1uTrxnPool = thiz;
|
||||||
|
|
||||||
NW_LOG(pStack, NW_LOG_LEVEL_DEBG, "Purged transaction 0x%p", thiz);
|
NW_LOG(pStack, NW_LOG_LEVEL_DEBG, "Purged transaction 0x%p", thiz);
|
||||||
|
|
||||||
*pthiz = NULL;
|
*pthiz = NULL;
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -315,72 +317,75 @@ nwGtpv1uTrxnCreateAndSendMsg( NW_IN NwGtpv1uStackT *thiz,
|
|||||||
NW_IN NwU32T peerPort,
|
NW_IN NwU32T peerPort,
|
||||||
NW_IN NwGtpv1uMsgT *pMsg)
|
NW_IN NwGtpv1uMsgT *pMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
NwU8T *msgHdr;
|
NwU8T *msgHdr;
|
||||||
|
|
||||||
NW_ASSERT(thiz);
|
NW_ASSERT(thiz);
|
||||||
NW_ASSERT(pMsg);
|
NW_ASSERT(pMsg);
|
||||||
|
|
||||||
msgHdr = &pMsg->msgBuf[pMsg->msgBufOffset];
|
msgHdr = &pMsg->msgBuf[pMsg->msgBufOffset];
|
||||||
|
|
||||||
NW_ASSERT(msgHdr != NULL);
|
NW_ASSERT(msgHdr != NULL);
|
||||||
|
|
||||||
*(msgHdr++) = (pMsg->version << 5) |
|
*(msgHdr++) = (pMsg->version << 5) |
|
||||||
(pMsg->protocolType << 4) |
|
(pMsg->protocolType << 4) |
|
||||||
(pMsg->extHdrFlag << 2) |
|
(pMsg->extHdrFlag << 2) |
|
||||||
(pMsg->seqNumFlag << 1) |
|
(pMsg->seqNumFlag << 1) |
|
||||||
(pMsg->npduNumFlag);
|
(pMsg->npduNumFlag);
|
||||||
|
|
||||||
|
*(msgHdr++) = (pMsg->msgType);
|
||||||
|
*((NwU16T *) msgHdr) = htons(pMsg->msgLen);
|
||||||
|
msgHdr += 2;
|
||||||
|
|
||||||
|
*((NwU32T *) msgHdr) = htonl(pMsg->teid);
|
||||||
|
msgHdr += 4;
|
||||||
|
|
||||||
|
if(pMsg->seqNumFlag | pMsg->extHdrFlag | pMsg->npduNumFlag) {
|
||||||
|
if(pMsg->seqNumFlag) {
|
||||||
|
*((NwU16T *) msgHdr) = htons((pTrxn ? pTrxn->seqNum : pMsg->seqNum));
|
||||||
|
} else {
|
||||||
|
*((NwU16T *) msgHdr) = 0x0000;
|
||||||
|
}
|
||||||
|
|
||||||
*(msgHdr++) = (pMsg->msgType);
|
|
||||||
*((NwU16T *) msgHdr) = htons(pMsg->msgLen);
|
|
||||||
msgHdr += 2;
|
msgHdr += 2;
|
||||||
|
|
||||||
*((NwU32T *) msgHdr) = htonl(pMsg->teid);
|
if(pMsg->npduNumFlag) {
|
||||||
msgHdr += 4;
|
*((NwU8T *) msgHdr) = pMsg->npduNumFlag;
|
||||||
|
} else {
|
||||||
if(pMsg->seqNumFlag | pMsg->extHdrFlag | pMsg->npduNumFlag) {
|
*((NwU8T *) msgHdr) = 0x00;
|
||||||
if(pMsg->seqNumFlag) {
|
|
||||||
*((NwU16T *) msgHdr) = htons((pTrxn ? pTrxn->seqNum : pMsg->seqNum));
|
|
||||||
} else {
|
|
||||||
*((NwU16T *) msgHdr) = 0x0000;
|
|
||||||
}
|
|
||||||
msgHdr += 2;
|
|
||||||
|
|
||||||
if(pMsg->npduNumFlag) {
|
|
||||||
*((NwU8T *) msgHdr) = pMsg->npduNumFlag;
|
|
||||||
} else {
|
|
||||||
*((NwU8T *) msgHdr) = 0x00;
|
|
||||||
}
|
|
||||||
msgHdr++;
|
|
||||||
|
|
||||||
if(pMsg->extHdrFlag) {
|
|
||||||
*((NwU8T *) msgHdr) = pMsg->extHdrFlag;
|
|
||||||
} else {
|
|
||||||
*((NwU8T *) msgHdr) = 0x00;
|
|
||||||
}
|
|
||||||
msgHdr++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NW_ASSERT(thiz->udp.udpDataReqCallback != NULL);
|
msgHdr++;
|
||||||
|
|
||||||
rc = thiz->udp.udpDataReqCallback(thiz->udp.hUdp,
|
if(pMsg->extHdrFlag) {
|
||||||
pMsg->msgBuf,
|
*((NwU8T *) msgHdr) = pMsg->extHdrFlag;
|
||||||
pMsg->msgLen,
|
} else {
|
||||||
pMsg->msgBufOffset,
|
*((NwU8T *) msgHdr) = 0x00;
|
||||||
peerIp,
|
|
||||||
peerPort);
|
|
||||||
|
|
||||||
/* Save the message for retransmission */
|
|
||||||
if(rc == NW_GTPV1U_OK && pTrxn) {
|
|
||||||
pTrxn->pMsg = pMsg;
|
|
||||||
pTrxn->peerIp = peerIp;
|
|
||||||
pTrxn->peerPort = peerPort;
|
|
||||||
|
|
||||||
rc = nwGtpv1uTrxnStartPeerRspTimer(pTrxn, nwGtpv1uTrxnPeerRspTimeout);
|
|
||||||
NW_ASSERT(rc == NW_GTPV1U_OK);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
msgHdr++;
|
||||||
|
}
|
||||||
|
|
||||||
|
NW_ASSERT(thiz->udp.udpDataReqCallback != NULL);
|
||||||
|
|
||||||
|
rc = thiz->udp.udpDataReqCallback(thiz->udp.hUdp,
|
||||||
|
pMsg->msgBuf,
|
||||||
|
pMsg->msgLen,
|
||||||
|
pMsg->msgBufOffset,
|
||||||
|
peerIp,
|
||||||
|
peerPort);
|
||||||
|
|
||||||
|
/* Save the message for retransmission */
|
||||||
|
if(rc == NW_GTPV1U_OK && pTrxn) {
|
||||||
|
pTrxn->pMsg = pMsg;
|
||||||
|
pTrxn->peerIp = peerIp;
|
||||||
|
pTrxn->peerPort = peerPort;
|
||||||
|
|
||||||
|
rc = nwGtpv1uTrxnStartPeerRspTimer(pTrxn, nwGtpv1uTrxnPeerRspTimeout);
|
||||||
|
NW_ASSERT(rc == NW_GTPV1U_OK);
|
||||||
|
}
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -70,16 +70,17 @@ static NwGtpv1uTunnelEndPointT *gpTunnelEndPointPool = NULL;
|
|||||||
NwGtpv1uTunnelEndPointT *
|
NwGtpv1uTunnelEndPointT *
|
||||||
nwGtpTunnelEndPointNew(struct NwGtpv1uStack *pStack)
|
nwGtpTunnelEndPointNew(struct NwGtpv1uStack *pStack)
|
||||||
{
|
{
|
||||||
NwGtpv1uTunnelEndPointT *thiz;
|
NwGtpv1uTunnelEndPointT *thiz;
|
||||||
if(gpTunnelEndPointPool) {
|
|
||||||
thiz = gpTunnelEndPointPool;
|
|
||||||
gpTunnelEndPointPool = gpTunnelEndPointPool->next;
|
|
||||||
} else {
|
|
||||||
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uTunnelEndPointT), thiz,
|
|
||||||
NwGtpv1uTunnelEndPointT *);
|
|
||||||
}
|
|
||||||
|
|
||||||
return thiz;
|
if(gpTunnelEndPointPool) {
|
||||||
|
thiz = gpTunnelEndPointPool;
|
||||||
|
gpTunnelEndPointPool = gpTunnelEndPointPool->next;
|
||||||
|
} else {
|
||||||
|
NW_GTPV1U_MALLOC(pStack, sizeof(NwGtpv1uTunnelEndPointT), thiz,
|
||||||
|
NwGtpv1uTunnelEndPointT *);
|
||||||
|
}
|
||||||
|
|
||||||
|
return thiz;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -93,9 +94,9 @@ NwGtpv1uRcT
|
|||||||
nwGtpTunnelEndPointDestroy(struct NwGtpv1uStack *pStack,
|
nwGtpTunnelEndPointDestroy(struct NwGtpv1uStack *pStack,
|
||||||
NwGtpv1uTunnelEndPointT *thiz)
|
NwGtpv1uTunnelEndPointT *thiz)
|
||||||
{
|
{
|
||||||
thiz->next = gpTunnelEndPointPool;
|
thiz->next = gpTunnelEndPointPool;
|
||||||
gpTunnelEndPointPool = thiz;
|
gpTunnelEndPointPool = thiz;
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,19 +111,19 @@ NwGtpv1uRcT
|
|||||||
nwGtpSessionSendMsgApiToUlpEntity(NwGtpv1uTunnelEndPointT *thiz,
|
nwGtpSessionSendMsgApiToUlpEntity(NwGtpv1uTunnelEndPointT *thiz,
|
||||||
NwGtpv1uMsgT *pMsg)
|
NwGtpv1uMsgT *pMsg)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||||
NwGtpv1uUlpApiT api;
|
NwGtpv1uUlpApiT api;
|
||||||
|
|
||||||
api.apiType = NW_GTPV1U_ULP_API_RECV_TPDU;
|
api.apiType = NW_GTPV1U_ULP_API_RECV_TPDU;
|
||||||
api.apiInfo.recvMsgInfo.hUlpSession = thiz->hUlpSession;
|
api.apiInfo.recvMsgInfo.hUlpSession = thiz->hUlpSession;
|
||||||
api.apiInfo.recvMsgInfo.teid = thiz->teid;
|
api.apiInfo.recvMsgInfo.teid = thiz->teid;
|
||||||
api.apiInfo.recvMsgInfo.hMsg = (NwGtpv1uMsgHandleT)pMsg;
|
api.apiInfo.recvMsgInfo.hMsg = (NwGtpv1uMsgHandleT)pMsg;
|
||||||
|
|
||||||
NW_ASSERT(thiz->pStack->ulp.ulpReqCallback != NULL);
|
NW_ASSERT(thiz->pStack->ulp.ulpReqCallback != NULL);
|
||||||
|
|
||||||
thiz->pStack->ulp.ulpReqCallback(thiz->pStack->ulp.hUlp, &api);
|
thiz->pStack->ulp.ulpReqCallback(thiz->pStack->ulp.hUlp, &api);
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -29,9 +29,9 @@
|
|||||||
|
|
||||||
#ifndef __NW_EVT_H__
|
#ifndef __NW_EVT_H__
|
||||||
#define __NW_EVT_H__
|
#define __NW_EVT_H__
|
||||||
/**
|
/**
|
||||||
* @file NwEvt.h
|
* @file NwEvt.h
|
||||||
* @brief
|
* @brief
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __WITH_LIBEVENT__
|
#ifdef __WITH_LIBEVENT__
|
||||||
@@ -60,9 +60,8 @@ typedef struct event NwEventT;
|
|||||||
|
|
||||||
/* HACK : Defining dummy values for compilation!*/
|
/* HACK : Defining dummy values for compilation!*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
int __tbd;
|
||||||
int __tbd;
|
|
||||||
} NwEventT;
|
} NwEventT;
|
||||||
|
|
||||||
#define NW_EVT_READ (0)
|
#define NW_EVT_READ (0)
|
||||||
@@ -71,9 +70,9 @@ typedef struct
|
|||||||
#define NW_TMR_CALLBACK(__cbFunc) __cbFunc(void *arg)
|
#define NW_TMR_CALLBACK(__cbFunc) __cbFunc(void *arg)
|
||||||
|
|
||||||
|
|
||||||
#define NW_EVT_INIT() do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
#define NW_EVT_INIT() do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
||||||
#define NW_EVT_LOOP() do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
#define NW_EVT_LOOP() do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
||||||
#define NW_EVENT_ADD(...) do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
#define NW_EVENT_ADD(...) do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -31,13 +31,13 @@ NwU32T g_log_level = NW_LOG_LEVEL_INFO;
|
|||||||
|
|
||||||
NwGtpv1uRcT nwMiniLogMgrInit(NwMiniLogMgrT *thiz, NwU32T logLevel )
|
NwGtpv1uRcT nwMiniLogMgrInit(NwMiniLogMgrT *thiz, NwU32T logLevel )
|
||||||
{
|
{
|
||||||
thiz->logLevel = logLevel;
|
thiz->logLevel = logLevel;
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT nwMiniLogMgrSetLogLevel(NwMiniLogMgrT *thiz, NwU32T logLevel)
|
NwGtpv1uRcT nwMiniLogMgrSetLogLevel(NwMiniLogMgrT *thiz, NwU32T logLevel)
|
||||||
{
|
{
|
||||||
thiz->logLevel = logLevel;
|
thiz->logLevel = logLevel;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT nwMiniLogMgrLogRequest (NwGtpv1uLogMgrHandleT hLogMgr,
|
NwGtpv1uRcT nwMiniLogMgrLogRequest (NwGtpv1uLogMgrHandleT hLogMgr,
|
||||||
@@ -46,12 +46,14 @@ NwGtpv1uRcT nwMiniLogMgrLogRequest (NwGtpv1uLogMgrHandleT hLogMgr,
|
|||||||
NwU32T line,
|
NwU32T line,
|
||||||
NwCharT *logStr)
|
NwCharT *logStr)
|
||||||
{
|
{
|
||||||
NwMiniLogMgrT *thiz = (NwMiniLogMgrT *) hLogMgr;
|
NwMiniLogMgrT *thiz = (NwMiniLogMgrT *) hLogMgr;
|
||||||
if(thiz->logLevel >= logLevel) {
|
|
||||||
printf("NWGTPv2U-STK %s - %s <%s,%u>\n", gLogLevelStr[logLevel], logStr,
|
if(thiz->logLevel >= logLevel) {
|
||||||
basename(file), line);
|
printf("NWGTPv2U-STK %s - %s <%s,%u>\n", gLogLevelStr[logLevel], logStr,
|
||||||
}
|
basename(file), line);
|
||||||
return NW_GTPV1U_OK;
|
}
|
||||||
|
|
||||||
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* *
|
* *
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file hello-world.c
|
* @file hello-world.c
|
||||||
* @brief This file contains example of a minimalistic log manager entity.
|
* @brief This file contains example of a minimalistic log manager entity.
|
||||||
*/
|
*/
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __NW_MINI_LOG_MGR_H__
|
#ifndef __NW_MINI_LOG_MGR_H__
|
||||||
#define __NW_MINI_LOG_MGR_H__
|
#define __NW_MINI_LOG_MGR_H__
|
||||||
@@ -36,8 +36,7 @@ extern NwU32T g_log_level;
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwU8T logLevel;
|
NwU8T logLevel;
|
||||||
} NwMiniLogMgrT;
|
} NwMiniLogMgrT;
|
||||||
|
|
||||||
@@ -46,12 +45,12 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
NwGtpv1uRcT nwMiniLogMgrLogRequest (NwGtpv1uLogMgrHandleT logMgrHandle,
|
NwGtpv1uRcT nwMiniLogMgrLogRequest (NwGtpv1uLogMgrHandleT logMgrHandle,
|
||||||
NwU32T logLevel,
|
NwU32T logLevel,
|
||||||
NwCharT* file,
|
NwCharT* file,
|
||||||
NwU32T line,
|
NwU32T line,
|
||||||
NwCharT* logStr);
|
NwCharT* logStr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -33,19 +33,19 @@ extern "C" {
|
|||||||
static void
|
static void
|
||||||
NW_TMR_CALLBACK(nwMiniTmrMgrHandleTimeout)
|
NW_TMR_CALLBACK(nwMiniTmrMgrHandleTimeout)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
NwMiniTmrMgrEntityT *pTmr = (NwMiniTmrMgrEntityT *) arg;
|
NwMiniTmrMgrEntityT *pTmr = (NwMiniTmrMgrEntityT *) arg;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Send Timeout Request to GTPv1u Stack Instance
|
* Send Timeout Request to GTPv1u Stack Instance
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
rc = nwGtpv1uProcessTimeout(pTmr->timeoutArg);
|
rc = nwGtpv1uProcessTimeout(pTmr->timeoutArg);
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
free(pTmr);
|
free(pTmr);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
@@ -59,41 +59,41 @@ NwGtpv1uRcT nwTimerStart( NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
|||||||
void *timeoutArg,
|
void *timeoutArg,
|
||||||
NwGtpv1uTimerHandleT *hTmr)
|
NwGtpv1uTimerHandleT *hTmr)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
NwGtpv1uRcT rc = NW_GTPV1U_OK;
|
||||||
NwMiniTmrMgrEntityT *pTmr;
|
NwMiniTmrMgrEntityT *pTmr;
|
||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
|
|
||||||
NW_LOG(NW_LOG_LEVEL_INFO,
|
NW_LOG(NW_LOG_LEVEL_INFO,
|
||||||
"Received start timer request from stack with timer type %u, arg %x, for %u sec and %u usec",
|
"Received start timer request from stack with timer type %u, arg %x, for %u sec and %u usec",
|
||||||
tmrType, timeoutArg, timeoutSec, timeoutUsec);
|
tmrType, timeoutArg, timeoutSec, timeoutUsec);
|
||||||
|
|
||||||
pTmr = (NwMiniTmrMgrEntityT *) malloc (sizeof(NwMiniTmrMgrEntityT));
|
pTmr = (NwMiniTmrMgrEntityT *) malloc (sizeof(NwMiniTmrMgrEntityT));
|
||||||
|
|
||||||
/* set the timevalues*/
|
/* set the timevalues*/
|
||||||
timerclear(&tv);
|
timerclear(&tv);
|
||||||
tv.tv_sec = timeoutSec;
|
tv.tv_sec = timeoutSec;
|
||||||
tv.tv_usec = timeoutUsec;
|
tv.tv_usec = timeoutUsec;
|
||||||
|
|
||||||
pTmr->timeoutArg = timeoutArg;
|
pTmr->timeoutArg = timeoutArg;
|
||||||
evtimer_set(&pTmr->ev, nwMiniTmrMgrHandleTimeout, pTmr);
|
evtimer_set(&pTmr->ev, nwMiniTmrMgrHandleTimeout, pTmr);
|
||||||
|
|
||||||
/*add event*/
|
/*add event*/
|
||||||
|
|
||||||
event_add(&(pTmr->ev), &tv);
|
event_add(&(pTmr->ev), &tv);
|
||||||
|
|
||||||
*hTmr = (NwGtpv1uTimerHandleT)pTmr;
|
*hTmr = (NwGtpv1uTimerHandleT)pTmr;
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT nwTimerStop( NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
NwGtpv1uRcT nwTimerStop( NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||||
NwGtpv1uTimerHandleT hTmr)
|
NwGtpv1uTimerHandleT hTmr)
|
||||||
{
|
{
|
||||||
NW_LOG(NW_LOG_LEVEL_INFO,
|
NW_LOG(NW_LOG_LEVEL_INFO,
|
||||||
"Received stop timer request from stack for timer handle %u", hTmr);
|
"Received stop timer request from stack for timer handle %u", hTmr);
|
||||||
evtimer_del(&(((NwMiniTmrMgrEntityT *)hTmr)->ev));
|
evtimer_del(&(((NwMiniTmrMgrEntityT *)hTmr)->ev));
|
||||||
free((void *)hTmr);
|
free((void *)hTmr);
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwMiniTmrMgrEntity.c
|
* @file NwMiniTmrMgrEntity.c
|
||||||
* @brief This file ontains example of a minimalistic timer manager entity.
|
* @brief This file ontains example of a minimalistic timer manager entity.
|
||||||
*/
|
*/
|
||||||
@@ -19,13 +19,12 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __NW_MINI_TMR_MGR_H__
|
#ifndef __NW_MINI_TMR_MGR_H__
|
||||||
#define __NW_MINI_TMR_MGR_H__
|
#define __NW_MINI_TMR_MGR_H__
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwEventT ev;
|
NwEventT ev;
|
||||||
void* timeoutArg;
|
void* timeoutArg;
|
||||||
} NwMiniTmrMgrEntityT;
|
} NwMiniTmrMgrEntityT;
|
||||||
@@ -36,15 +35,15 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
NwGtpv1uRcT nwTimerStart( NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
NwGtpv1uRcT nwTimerStart( NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||||
NwU32T timeoutSec,
|
NwU32T timeoutSec,
|
||||||
NwU32T timeoutUsec,
|
NwU32T timeoutUsec,
|
||||||
NwU32T tmrType,
|
NwU32T tmrType,
|
||||||
void* timeoutArg,
|
void* timeoutArg,
|
||||||
NwGtpv1uTimerHandleT* hTmr);
|
NwGtpv1uTimerHandleT* hTmr);
|
||||||
|
|
||||||
|
|
||||||
NwGtpv1uRcT nwTimerStop( NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
NwGtpv1uRcT nwTimerStop( NwGtpv1uTimerMgrHandleT tmrMgrHandle,
|
||||||
NwGtpv1uTimerHandleT hTmr);
|
NwGtpv1uTimerHandleT hTmr);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -43,25 +43,26 @@ extern "C" {
|
|||||||
static
|
static
|
||||||
void NW_TMR_CALLBACK(nwUdpDataIndicationCallbackData)
|
void NW_TMR_CALLBACK(nwUdpDataIndicationCallbackData)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
NwU8T udpBuf[MAX_UDP_PAYLOAD_LEN];
|
NwU8T udpBuf[MAX_UDP_PAYLOAD_LEN];
|
||||||
NwS32T bytesRead;
|
NwS32T bytesRead;
|
||||||
NwU32T peerLen;
|
NwU32T peerLen;
|
||||||
struct sockaddr_in peer;
|
struct sockaddr_in peer;
|
||||||
NwMiniUdpEntityT *thiz = (NwMiniUdpEntityT *) arg;
|
NwMiniUdpEntityT *thiz = (NwMiniUdpEntityT *) arg;
|
||||||
|
|
||||||
peerLen = sizeof(peer);
|
peerLen = sizeof(peer);
|
||||||
|
|
||||||
bytesRead = recvfrom(thiz->hSocket, udpBuf, MAX_UDP_PAYLOAD_LEN , 0,
|
bytesRead = recvfrom(thiz->hSocket, udpBuf, MAX_UDP_PAYLOAD_LEN , 0,
|
||||||
(struct sockaddr *) &peer,(socklen_t *) &peerLen);
|
(struct sockaddr *) &peer,(socklen_t *) &peerLen);
|
||||||
if(bytesRead) {
|
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG, "Received UDP message of length %u from %X:%u",
|
if(bytesRead) {
|
||||||
bytesRead, ntohl(peer.sin_addr.s_addr), ntohs(peer.sin_port));
|
NW_LOG(NW_LOG_LEVEL_DEBG, "Received UDP message of length %u from %X:%u",
|
||||||
rc = nwGtpv1uProcessUdpReq(thiz->hGtpv1uStack, udpBuf, bytesRead,
|
bytesRead, ntohl(peer.sin_addr.s_addr), ntohs(peer.sin_port));
|
||||||
peer.sin_port, peer.sin_addr.s_addr);
|
rc = nwGtpv1uProcessUdpReq(thiz->hGtpv1uStack, udpBuf, bytesRead,
|
||||||
} else {
|
peer.sin_port, peer.sin_addr.s_addr);
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
} else {
|
||||||
}
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -72,39 +73,39 @@ void NW_TMR_CALLBACK(nwUdpDataIndicationCallbackData)
|
|||||||
NwGtpv1uRcT nwMiniUdpInit(NwMiniUdpEntityT *thiz,
|
NwGtpv1uRcT nwMiniUdpInit(NwMiniUdpEntityT *thiz,
|
||||||
NwGtpv1uStackHandleT hGtpv1uStack, NwU8T *ipAddr)
|
NwGtpv1uStackHandleT hGtpv1uStack, NwU8T *ipAddr)
|
||||||
{
|
{
|
||||||
int sd;
|
int sd;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (sd < 0) {
|
if (sd < 0) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(2152);
|
addr.sin_port = htons(2152);
|
||||||
addr.sin_addr.s_addr = inet_addr(ipAddr);
|
addr.sin_addr.s_addr = inet_addr(ipAddr);
|
||||||
memset(addr.sin_zero, '\0', sizeof (addr.sin_zero));
|
memset(addr.sin_zero, '\0', sizeof (addr.sin_zero));
|
||||||
|
|
||||||
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_set(&(thiz->ev), sd, EV_READ|EV_PERSIST, nwUdpDataIndicationCallbackData,
|
event_set(&(thiz->ev), sd, EV_READ|EV_PERSIST, nwUdpDataIndicationCallbackData,
|
||||||
thiz);
|
thiz);
|
||||||
event_add(&(thiz->ev), NULL);
|
event_add(&(thiz->ev), NULL);
|
||||||
|
|
||||||
thiz->hSocket = sd;
|
thiz->hSocket = sd;
|
||||||
thiz->hGtpv1uStack = hGtpv1uStack;
|
thiz->hGtpv1uStack = hGtpv1uStack;
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT nwMiniUdpDestroy(NwMiniUdpEntityT *thiz)
|
NwGtpv1uRcT nwMiniUdpDestroy(NwMiniUdpEntityT *thiz)
|
||||||
{
|
{
|
||||||
close(thiz->hSocket);
|
close(thiz->hSocket);
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT nwMiniUdpDataReq(NwGtpv1uUdpHandleT udpHandle,
|
NwGtpv1uRcT nwMiniUdpDataReq(NwGtpv1uUdpHandleT udpHandle,
|
||||||
@@ -113,38 +114,39 @@ NwGtpv1uRcT nwMiniUdpDataReq(NwGtpv1uUdpHandleT udpHandle,
|
|||||||
NwU32T peerIpAddr,
|
NwU32T peerIpAddr,
|
||||||
NwU32T peerPort)
|
NwU32T peerPort)
|
||||||
{
|
{
|
||||||
struct sockaddr_in peerAddr;
|
struct sockaddr_in peerAddr;
|
||||||
NwS32T bytesSent;
|
NwS32T bytesSent;
|
||||||
NwMiniUdpEntityT *thiz = (NwMiniUdpEntityT *) udpHandle;
|
NwMiniUdpEntityT *thiz = (NwMiniUdpEntityT *) udpHandle;
|
||||||
|
|
||||||
peerAddr.sin_family = AF_INET;
|
peerAddr.sin_family = AF_INET;
|
||||||
peerAddr.sin_port = htons(peerPort);
|
peerAddr.sin_port = htons(peerPort);
|
||||||
peerAddr.sin_addr.s_addr = (peerIpAddr);
|
peerAddr.sin_addr.s_addr = (peerIpAddr);
|
||||||
memset(peerAddr.sin_zero, '\0', sizeof (peerAddr.sin_zero));
|
memset(peerAddr.sin_zero, '\0', sizeof (peerAddr.sin_zero));
|
||||||
|
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG,
|
NW_LOG(NW_LOG_LEVEL_DEBG,
|
||||||
"Sending %u bytes on handle 0x%x to peer %u.%u.%u.%u:%u", dataSize, udpHandle,
|
"Sending %u bytes on handle 0x%x to peer %u.%u.%u.%u:%u", dataSize, udpHandle,
|
||||||
|
(peerIpAddr & 0x000000ff),
|
||||||
|
(peerIpAddr & 0x0000ff00) >> 8,
|
||||||
|
(peerIpAddr & 0x00ff0000) >> 16,
|
||||||
|
(peerIpAddr & 0xff000000) >> 24,
|
||||||
|
peerPort);
|
||||||
|
|
||||||
|
bytesSent = sendto (thiz->hSocket, dataBuf, dataSize, 0,
|
||||||
|
(struct sockaddr *) &peerAddr, sizeof(peerAddr));
|
||||||
|
|
||||||
|
if(bytesSent < 0) {
|
||||||
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
|
} else {
|
||||||
|
NW_LOG(NW_LOG_LEVEL_DEBG, "Sent %u bytes on handle 0x%x to peer %u.%u.%u.%u",
|
||||||
|
dataSize, udpHandle,
|
||||||
(peerIpAddr & 0x000000ff),
|
(peerIpAddr & 0x000000ff),
|
||||||
(peerIpAddr & 0x0000ff00) >> 8,
|
(peerIpAddr & 0x0000ff00) >> 8,
|
||||||
(peerIpAddr & 0x00ff0000) >> 16,
|
(peerIpAddr & 0x00ff0000) >> 16,
|
||||||
(peerIpAddr & 0xff000000) >> 24,
|
(peerIpAddr & 0xff000000) >> 24);
|
||||||
peerPort);
|
|
||||||
|
|
||||||
bytesSent = sendto (thiz->hSocket, dataBuf, dataSize, 0,
|
}
|
||||||
(struct sockaddr *) &peerAddr, sizeof(peerAddr));
|
|
||||||
|
|
||||||
if(bytesSent < 0) {
|
return NW_GTPV1U_OK;
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
|
||||||
} else {
|
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG, "Sent %u bytes on handle 0x%x to peer %u.%u.%u.%u",
|
|
||||||
dataSize, udpHandle,
|
|
||||||
(peerIpAddr & 0x000000ff),
|
|
||||||
(peerIpAddr & 0x0000ff00) >> 8,
|
|
||||||
(peerIpAddr & 0x00ff0000) >> 16,
|
|
||||||
(peerIpAddr & 0xff000000) >> 24);
|
|
||||||
|
|
||||||
}
|
|
||||||
return NW_GTPV1U_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwMiniUdpEntity.h
|
* @file NwMiniUdpEntity.h
|
||||||
* @brief This file contains example of a minimalistic ULP entity.
|
* @brief This file contains example of a minimalistic ULP entity.
|
||||||
*/
|
*/
|
||||||
@@ -19,13 +19,12 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __NW_MINI_UDP_ENTITY_H__
|
#ifndef __NW_MINI_UDP_ENTITY_H__
|
||||||
#define __NW_MINI_UDP_ENTITY_H__
|
#define __NW_MINI_UDP_ENTITY_H__
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwU32T hSocket;
|
NwU32T hSocket;
|
||||||
NwEventT ev;
|
NwEventT ev;
|
||||||
NwGtpv1uStackHandleT hGtpv1uStack;
|
NwGtpv1uStackHandleT hGtpv1uStack;
|
||||||
@@ -40,10 +39,10 @@ NwGtpv1uRcT nwMiniUdpInit(NwMiniUdpEntityT* thiz, NwGtpv1uStackHandleT hGtpv1uSt
|
|||||||
NwGtpv1uRcT nwMiniUdpDestroy(NwMiniUdpEntityT* thiz);
|
NwGtpv1uRcT nwMiniUdpDestroy(NwMiniUdpEntityT* thiz);
|
||||||
|
|
||||||
NwGtpv1uRcT nwMiniUdpDataReq(NwGtpv1uUdpHandleT udpHandle,
|
NwGtpv1uRcT nwMiniUdpDataReq(NwGtpv1uUdpHandleT udpHandle,
|
||||||
NwU8T* dataBuf,
|
NwU8T* dataBuf,
|
||||||
NwU32T dataSize,
|
NwU32T dataSize,
|
||||||
NwU32T peerAddr,
|
NwU32T peerAddr,
|
||||||
NwU32T peerPort);
|
NwU32T peerPort);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,66 +38,67 @@ extern "C" {
|
|||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwMiniUlpSendEchoRequestToPeer(NwMiniUlpEntityT *thiz, NwU32T peerIp)
|
nwMiniUlpSendEchoRequestToPeer(NwMiniUlpEntityT *thiz, NwU32T peerIp)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
NwGtpv1uUlpApiT ulpReq;
|
NwGtpv1uUlpApiT ulpReq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send Message Request to Gtpv1u Stack Instance
|
* Send Message Request to Gtpv1u Stack Instance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ulpReq.apiType = NW_GTPV1U_ULP_API_INITIAL_REQ;
|
ulpReq.apiType = NW_GTPV1U_ULP_API_INITIAL_REQ;
|
||||||
|
|
||||||
ulpReq.apiInfo.initialReqInfo.hUlpTrxn = (NwGtpv1uUlpTrxnHandleT)thiz;
|
ulpReq.apiInfo.initialReqInfo.hUlpTrxn = (NwGtpv1uUlpTrxnHandleT)thiz;
|
||||||
ulpReq.apiInfo.initialReqInfo.teid = 0x00;
|
ulpReq.apiInfo.initialReqInfo.teid = 0x00;
|
||||||
ulpReq.apiInfo.initialReqInfo.peerIp = (peerIp);
|
ulpReq.apiInfo.initialReqInfo.peerIp = (peerIp);
|
||||||
ulpReq.apiInfo.initialReqInfo.peerPort = 2152;
|
ulpReq.apiInfo.initialReqInfo.peerPort = 2152;
|
||||||
|
|
||||||
/* Send Echo Request*/
|
/* Send Echo Request*/
|
||||||
|
|
||||||
rc = nwGtpv1uMsgNew( thiz->hGtpv1uStack,
|
rc = nwGtpv1uMsgNew( thiz->hGtpv1uStack,
|
||||||
NW_TRUE, /* SeqNum flag */
|
NW_TRUE, /* SeqNum flag */
|
||||||
NW_FALSE,
|
NW_FALSE,
|
||||||
NW_FALSE,
|
NW_FALSE,
|
||||||
NW_GTP_ECHO_REQ, /* Msg Type */
|
NW_GTP_ECHO_REQ, /* Msg Type */
|
||||||
0x00000000UL, /* TEID */
|
0x00000000UL, /* TEID */
|
||||||
0x5678, /* Seq Number */
|
0x5678, /* Seq Number */
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
(&ulpReq.hMsg));
|
(&ulpReq.hMsg));
|
||||||
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
rc = nwGtpv1uMsgAddIeTV1((ulpReq.hMsg), NW_GTPV1U_IE_RECOVERY,
|
rc = nwGtpv1uMsgAddIeTV1((ulpReq.hMsg), NW_GTPV1U_IE_RECOVERY,
|
||||||
thiz->restartCounter);
|
thiz->restartCounter);
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq);
|
rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq);
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
void NW_EVT_CALLBACK(nwMiniUlpDataIndicationCallbackData)
|
void NW_EVT_CALLBACK(nwMiniUlpDataIndicationCallbackData)
|
||||||
{
|
{
|
||||||
NwMiniUlpEntityT *thiz = (NwMiniUlpEntityT *) arg;
|
NwMiniUlpEntityT *thiz = (NwMiniUlpEntityT *) arg;
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
NwU8T udpBuf[MAX_UDP_PAYLOAD_LEN];
|
NwU8T udpBuf[MAX_UDP_PAYLOAD_LEN];
|
||||||
NwS32T bytesRead;
|
NwS32T bytesRead;
|
||||||
NwU32T peerLen;
|
NwU32T peerLen;
|
||||||
struct sockaddr_in peer;
|
struct sockaddr_in peer;
|
||||||
|
|
||||||
peerLen = sizeof(peer);
|
peerLen = sizeof(peer);
|
||||||
|
|
||||||
bytesRead = recvfrom(thiz->hSocket, udpBuf, MAX_UDP_PAYLOAD_LEN , 0,
|
bytesRead = recvfrom(thiz->hSocket, udpBuf, MAX_UDP_PAYLOAD_LEN , 0,
|
||||||
(struct sockaddr *) &peer,(socklen_t *) &peerLen);
|
(struct sockaddr *) &peer,(socklen_t *) &peerLen);
|
||||||
if(bytesRead) {
|
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG, "Received UDP message of length %u from %X:%u",
|
if(bytesRead) {
|
||||||
bytesRead, ntohl(peer.sin_addr.s_addr), ntohs(peer.sin_port));
|
NW_LOG(NW_LOG_LEVEL_DEBG, "Received UDP message of length %u from %X:%u",
|
||||||
rc = nwMiniUlpTpduSend(thiz, udpBuf, bytesRead, thiz->localPort[fd]);
|
bytesRead, ntohl(peer.sin_addr.s_addr), ntohs(peer.sin_port));
|
||||||
} else {
|
rc = nwMiniUlpTpduSend(thiz, udpBuf, bytesRead, thiz->localPort[fd]);
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
} else {
|
||||||
}
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
@@ -107,108 +108,108 @@ void NW_EVT_CALLBACK(nwMiniUlpDataIndicationCallbackData)
|
|||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwMiniUlpInit(NwMiniUlpEntityT *thiz, NwGtpv1uStackHandleT hGtpv1uStack)
|
nwMiniUlpInit(NwMiniUlpEntityT *thiz, NwGtpv1uStackHandleT hGtpv1uStack)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
thiz->hGtpv1uStack = hGtpv1uStack;
|
thiz->hGtpv1uStack = hGtpv1uStack;
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwMiniUlpDestroy(NwMiniUlpEntityT *thiz)
|
nwMiniUlpDestroy(NwMiniUlpEntityT *thiz)
|
||||||
{
|
{
|
||||||
NW_ASSERT(thiz);
|
NW_ASSERT(thiz);
|
||||||
memset(thiz, 0, sizeof(NwMiniUlpEntityT));
|
memset(thiz, 0, sizeof(NwMiniUlpEntityT));
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwMiniUlpCreateConn(NwMiniUlpEntityT *thiz, char *localIpStr, NwU16T localport,
|
nwMiniUlpCreateConn(NwMiniUlpEntityT *thiz, char *localIpStr, NwU16T localport,
|
||||||
char *peerIpStr)
|
char *peerIpStr)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
int sd;
|
int sd;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
NwGtpv1uUlpApiT ulpReq;
|
NwGtpv1uUlpApiT ulpReq;
|
||||||
|
|
||||||
strcpy(thiz->peerIpStr, peerIpStr);
|
strcpy(thiz->peerIpStr, peerIpStr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create local tunnel endpoint
|
* Create local tunnel endpoint
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NW_LOG(NW_LOG_LEVEL_NOTI, "Creating tunnel endpoint with teid %d", localport);
|
NW_LOG(NW_LOG_LEVEL_NOTI, "Creating tunnel endpoint with teid %d", localport);
|
||||||
ulpReq.apiType =
|
ulpReq.apiType =
|
||||||
NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT;
|
NW_GTPV1U_ULP_API_CREATE_TUNNEL_ENDPOINT;
|
||||||
ulpReq.apiInfo.createTunnelEndPointInfo.teid = localport;
|
ulpReq.apiInfo.createTunnelEndPointInfo.teid = localport;
|
||||||
ulpReq.apiInfo.createTunnelEndPointInfo.hUlpSession =
|
ulpReq.apiInfo.createTunnelEndPointInfo.hUlpSession =
|
||||||
(NwGtpv1uUlpSessionHandleT)thiz;
|
(NwGtpv1uUlpSessionHandleT)thiz;
|
||||||
|
|
||||||
rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq);
|
rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq);
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
thiz->hGtpv1uConn = ulpReq.apiInfo.createTunnelEndPointInfo.hStackSession;
|
thiz->hGtpv1uConn = ulpReq.apiInfo.createTunnelEndPointInfo.hStackSession;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create local udp listening endpoint
|
* Create local udp listening endpoint
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (sd < 0) {
|
if (sd < 0) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(localport);
|
addr.sin_port = htons(localport);
|
||||||
addr.sin_addr.s_addr = inet_addr(localIpStr);
|
addr.sin_addr.s_addr = inet_addr(localIpStr);
|
||||||
memset(addr.sin_zero, '\0', sizeof (addr.sin_zero));
|
memset(addr.sin_zero, '\0', sizeof (addr.sin_zero));
|
||||||
|
|
||||||
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
event_set(&(thiz->ev[sd]), sd, EV_READ|EV_PERSIST,
|
event_set(&(thiz->ev[sd]), sd, EV_READ|EV_PERSIST,
|
||||||
nwMiniUlpDataIndicationCallbackData, thiz);
|
nwMiniUlpDataIndicationCallbackData, thiz);
|
||||||
event_add(&(thiz->ev[sd]), NULL);
|
event_add(&(thiz->ev[sd]), NULL);
|
||||||
|
|
||||||
thiz->localPort[sd] = localport;
|
thiz->localPort[sd] = localport;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Create local udp for sendign data
|
* Create local udp for sendign data
|
||||||
*/
|
*/
|
||||||
|
|
||||||
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (sd < 0) {
|
if (sd < 0) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
thiz->hSocket = sd;
|
thiz->hSocket = sd;
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwMiniUlpDestroyConn(NwMiniUlpEntityT *thiz)
|
nwMiniUlpDestroyConn(NwMiniUlpEntityT *thiz)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
NwGtpv1uUlpApiT ulpReq;
|
NwGtpv1uUlpApiT ulpReq;
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Send Destroy Session Request to GTPv1u Stack Instance
|
* Send Destroy Session Request to GTPv1u Stack Instance
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
ulpReq.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT;
|
ulpReq.apiType = NW_GTPV1U_ULP_API_DESTROY_TUNNEL_ENDPOINT;
|
||||||
ulpReq.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle = thiz->hGtpv1uConn;
|
ulpReq.apiInfo.destroyTunnelEndPointInfo.hStackSessionHandle = thiz->hGtpv1uConn;
|
||||||
|
|
||||||
rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq);
|
rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq);
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
thiz->hGtpv1uConn = 0;
|
thiz->hGtpv1uConn = 0;
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -216,88 +217,90 @@ NwGtpv1uRcT
|
|||||||
nwMiniUlpTpduSend(NwMiniUlpEntityT *thiz, NwU8T *tpduBuf, NwU32T tpduLen ,
|
nwMiniUlpTpduSend(NwMiniUlpEntityT *thiz, NwU8T *tpduBuf, NwU32T tpduLen ,
|
||||||
NwU16T fromPort)
|
NwU16T fromPort)
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
NwGtpv1uUlpApiT ulpReq;
|
NwGtpv1uUlpApiT ulpReq;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Send Message Request to GTPv1u Stack Instance
|
* Send Message Request to GTPv1u Stack Instance
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ulpReq.apiType = NW_GTPV1U_ULP_API_SEND_TPDU;
|
ulpReq.apiType = NW_GTPV1U_ULP_API_SEND_TPDU;
|
||||||
ulpReq.apiInfo.sendtoInfo.teid = fromPort;
|
ulpReq.apiInfo.sendtoInfo.teid = fromPort;
|
||||||
ulpReq.apiInfo.sendtoInfo.ipAddr = inet_addr(thiz->peerIpStr);
|
ulpReq.apiInfo.sendtoInfo.ipAddr = inet_addr(thiz->peerIpStr);
|
||||||
|
|
||||||
rc = nwGtpv1uGpduMsgNew( thiz->hGtpv1uStack,
|
rc = nwGtpv1uGpduMsgNew( thiz->hGtpv1uStack,
|
||||||
fromPort,
|
fromPort,
|
||||||
NW_FALSE,
|
NW_FALSE,
|
||||||
thiz->seqNum++,
|
thiz->seqNum++,
|
||||||
tpduBuf,
|
tpduBuf,
|
||||||
tpduLen,
|
tpduLen,
|
||||||
&(ulpReq.apiInfo.sendtoInfo.hMsg));
|
&(ulpReq.apiInfo.sendtoInfo.hMsg));
|
||||||
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq);
|
rc = nwGtpv1uProcessUlpReq(thiz->hGtpv1uStack, &ulpReq);
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
rc = nwGtpv1uMsgDelete(thiz->hGtpv1uStack, (ulpReq.apiInfo.sendtoInfo.hMsg));
|
rc = nwGtpv1uMsgDelete(thiz->hGtpv1uStack, (ulpReq.apiInfo.sendtoInfo.hMsg));
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
return NW_GTPV1U_OK;
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwMiniUlpProcessStackReqCallback (NwGtpv1uUlpHandleT hUlp,
|
nwMiniUlpProcessStackReqCallback (NwGtpv1uUlpHandleT hUlp,
|
||||||
NwGtpv1uUlpApiT *pUlpApi)
|
NwGtpv1uUlpApiT *pUlpApi)
|
||||||
{
|
{
|
||||||
NwMiniUlpEntityT *thiz;
|
NwMiniUlpEntityT *thiz;
|
||||||
NW_ASSERT(pUlpApi != NULL);
|
NW_ASSERT(pUlpApi != NULL);
|
||||||
|
|
||||||
thiz = (NwMiniUlpEntityT *) hUlp;
|
thiz = (NwMiniUlpEntityT *) hUlp;
|
||||||
|
|
||||||
switch(pUlpApi->apiType) {
|
switch(pUlpApi->apiType) {
|
||||||
case NW_GTPV1U_ULP_API_RECV_TPDU: {
|
case NW_GTPV1U_ULP_API_RECV_TPDU: {
|
||||||
struct sockaddr_in peerAddr;
|
struct sockaddr_in peerAddr;
|
||||||
NwS32T bytesSent;
|
NwS32T bytesSent;
|
||||||
NwU8T dataBuf[4096];
|
NwU8T dataBuf[4096];
|
||||||
NwU32T dataSize;
|
NwU32T dataSize;
|
||||||
NwU32T peerIpAddr = (inet_addr(thiz->peerIpStr));
|
NwU32T peerIpAddr = (inet_addr(thiz->peerIpStr));
|
||||||
|
|
||||||
NW_ASSERT( NW_GTPV1U_OK == nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
|
NW_ASSERT( NW_GTPV1U_OK == nwGtpv1uMsgGetTpdu(pUlpApi->apiInfo.recvMsgInfo.hMsg,
|
||||||
dataBuf, &dataSize) );
|
dataBuf, &dataSize) );
|
||||||
|
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG, "Received TPDU from gtpv1u stack %u!",
|
NW_LOG(NW_LOG_LEVEL_DEBG, "Received TPDU from gtpv1u stack %u!",
|
||||||
pUlpApi->apiInfo.recvMsgInfo.teid);
|
pUlpApi->apiInfo.recvMsgInfo.teid);
|
||||||
|
|
||||||
peerAddr.sin_family = AF_INET;
|
peerAddr.sin_family = AF_INET;
|
||||||
peerAddr.sin_port = htons(pUlpApi->apiInfo.recvMsgInfo.teid);
|
peerAddr.sin_port = htons(pUlpApi->apiInfo.recvMsgInfo.teid);
|
||||||
peerAddr.sin_addr.s_addr = (peerIpAddr);
|
peerAddr.sin_addr.s_addr = (peerIpAddr);
|
||||||
memset(peerAddr.sin_zero, '\0', sizeof (peerAddr.sin_zero));
|
memset(peerAddr.sin_zero, '\0', sizeof (peerAddr.sin_zero));
|
||||||
|
|
||||||
bytesSent = sendto (thiz->hSocket, dataBuf, dataSize, 0,
|
bytesSent = sendto (thiz->hSocket, dataBuf, dataSize, 0,
|
||||||
(struct sockaddr *) &peerAddr, sizeof(peerAddr));
|
(struct sockaddr *) &peerAddr, sizeof(peerAddr));
|
||||||
|
|
||||||
if(bytesSent < 0) {
|
if(bytesSent < 0) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
} else {
|
} else {
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG, "Sent %u bytes to peer %u.%u.%u.%u", dataSize,
|
NW_LOG(NW_LOG_LEVEL_DEBG, "Sent %u bytes to peer %u.%u.%u.%u", dataSize,
|
||||||
(peerIpAddr & 0x000000ff),
|
(peerIpAddr & 0x000000ff),
|
||||||
(peerIpAddr & 0x0000ff00) >> 8,
|
(peerIpAddr & 0x0000ff00) >> 8,
|
||||||
(peerIpAddr & 0x00ff0000) >> 16,
|
(peerIpAddr & 0x00ff0000) >> 16,
|
||||||
(peerIpAddr & 0xff000000) >> 24);
|
(peerIpAddr & 0xff000000) >> 24);
|
||||||
}
|
|
||||||
|
|
||||||
NW_ASSERT(nwGtpv1uMsgDelete(thiz->hGtpv1uStack,
|
|
||||||
(pUlpApi->apiInfo.recvMsgInfo.hMsg)) == NW_GTPV1U_OK);
|
|
||||||
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
NW_LOG(NW_LOG_LEVEL_WARN, "Received undefined UlpApi (%d) from gtpv1u stack!",
|
|
||||||
pUlpApi->apiType);
|
|
||||||
}
|
}
|
||||||
return NW_GTPV1U_OK;
|
|
||||||
|
NW_ASSERT(nwGtpv1uMsgDelete(thiz->hGtpv1uStack,
|
||||||
|
(pUlpApi->apiInfo.recvMsgInfo.hMsg)) == NW_GTPV1U_OK);
|
||||||
|
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NW_LOG(NW_LOG_LEVEL_WARN, "Received undefined UlpApi (%d) from gtpv1u stack!",
|
||||||
|
pUlpApi->apiType);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NW_GTPV1U_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* *
|
* *
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwMiniUlpEntity.h
|
* @file NwMiniUlpEntity.h
|
||||||
* @brief This file contains example of a minimalistic ULP entity.
|
* @brief This file contains example of a minimalistic ULP entity.
|
||||||
*/
|
*/
|
||||||
@@ -16,11 +16,10 @@
|
|||||||
#include "NwEvt.h"
|
#include "NwEvt.h"
|
||||||
#include "NwLog.h"
|
#include "NwLog.h"
|
||||||
|
|
||||||
#ifndef __NW_MINI_ULP_H__
|
#ifndef __NW_MINI_ULP_H__
|
||||||
#define __NW_MINI_ULP_H__
|
#define __NW_MINI_ULP_H__
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
int hSocket;
|
int hSocket;
|
||||||
NwU16T seqNum;
|
NwU16T seqNum;
|
||||||
NwU8T restartCounter;
|
NwU8T restartCounter;
|
||||||
@@ -54,9 +53,9 @@ nwMiniUlpSendMsg(NwMiniUlpEntityT* thiz);
|
|||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwMiniUlpTpduSend(NwMiniUlpEntityT* thiz, NwU8T* tpduBuf, NwU32T tpduLen , NwU16T fromPort);
|
nwMiniUlpTpduSend(NwMiniUlpEntityT* thiz, NwU8T* tpduBuf, NwU32T tpduLen , NwU16T fromPort);
|
||||||
|
|
||||||
NwGtpv1uRcT
|
NwGtpv1uRcT
|
||||||
nwMiniUlpProcessStackReqCallback (NwGtpv1uUlpHandleT hUlp,
|
nwMiniUlpProcessStackReqCallback (NwGtpv1uUlpHandleT hUlp,
|
||||||
NwGtpv1uUlpApiT *pUlpApi);
|
NwGtpv1uUlpApiT *pUlpApi);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,173 +35,173 @@
|
|||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
NwGtpv1uRcT rc;
|
NwGtpv1uRcT rc;
|
||||||
char *logLevelStr;
|
char *logLevelStr;
|
||||||
NwU32T logLevel;
|
NwU32T logLevel;
|
||||||
NwU32T num_of_connections;
|
NwU32T num_of_connections;
|
||||||
|
|
||||||
NwGtpv1uStackHandleT hGtpv1uStack = 0;
|
NwGtpv1uStackHandleT hGtpv1uStack = 0;
|
||||||
NwMiniUlpEntityT ulpObj;
|
NwMiniUlpEntityT ulpObj;
|
||||||
NwMiniUdpEntityT udpObj;
|
NwMiniUdpEntityT udpObj;
|
||||||
NwMiniLogMgrT logObj;
|
NwMiniLogMgrT logObj;
|
||||||
NwGtpv1uUlpEntityT ulp;
|
NwGtpv1uUlpEntityT ulp;
|
||||||
NwGtpv1uUdpEntityT udp;
|
NwGtpv1uUdpEntityT udp;
|
||||||
NwGtpv1uTimerMgrEntityT tmrMgr;
|
NwGtpv1uTimerMgrEntityT tmrMgr;
|
||||||
NwGtpv1uLogMgrEntityT logMgr;
|
NwGtpv1uLogMgrEntityT logMgr;
|
||||||
|
|
||||||
if(argc != 4) {
|
if(argc != 4) {
|
||||||
printf("Usage: %s <num-of-connections> <local-ip> <peer-ip>\n", argv[0]);
|
printf("Usage: %s <num-of-connections> <local-ip> <peer-ip>\n", argv[0]);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
logLevelStr = getenv ("NW_LOG_LEVEL");
|
||||||
|
|
||||||
|
if(logLevelStr == NULL) {
|
||||||
|
logLevel = NW_LOG_LEVEL_INFO;
|
||||||
|
} else {
|
||||||
|
if(strncmp(logLevelStr, "EMER",4) == 0) {
|
||||||
|
logLevel = NW_LOG_LEVEL_EMER;
|
||||||
|
} else if(strncmp(logLevelStr, "ALER",4) == 0) {
|
||||||
|
logLevel = NW_LOG_LEVEL_ALER;
|
||||||
|
} else if(strncmp(logLevelStr, "CRIT",4) == 0) {
|
||||||
|
logLevel = NW_LOG_LEVEL_CRIT;
|
||||||
|
} else if(strncmp(logLevelStr, "ERRO",4) == 0) {
|
||||||
|
logLevel = NW_LOG_LEVEL_ERRO ;
|
||||||
|
} else if(strncmp(logLevelStr, "WARN",4) == 0) {
|
||||||
|
logLevel = NW_LOG_LEVEL_WARN;
|
||||||
|
} else if(strncmp(logLevelStr, "NOTI",4) == 0) {
|
||||||
|
logLevel = NW_LOG_LEVEL_NOTI;
|
||||||
|
} else if(strncmp(logLevelStr, "INFO",4) == 0) {
|
||||||
|
logLevel = NW_LOG_LEVEL_INFO;
|
||||||
|
} else if(strncmp(logLevelStr, "DEBG",4) == 0) {
|
||||||
|
logLevel = NW_LOG_LEVEL_DEBG;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Initialize event library
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
NW_EVT_INIT();
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Initialize Log Manager
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
nwMiniLogMgrInit(&logObj, logLevel);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Create GTPv1u Stack Instance
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
rc = nwGtpv1uInitialize(&hGtpv1uStack);
|
||||||
|
|
||||||
|
if(rc != NW_GTPV1U_OK) {
|
||||||
|
NW_LOG(NW_LOG_LEVEL_ERRO,
|
||||||
|
"Failed to create gtpv1u stack instance. Error '%u' occured", rc);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
NW_LOG(NW_LOG_LEVEL_INFO, "Gtpv1u Stack Handle '%X' Creation Successful!",
|
||||||
|
hGtpv1uStack);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Set up Ulp Entity
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
rc = nwMiniUlpInit(&ulpObj, hGtpv1uStack);
|
||||||
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
|
ulp.hUlp = (NwGtpv1uUlpHandleT) &ulpObj;
|
||||||
|
ulp.ulpReqCallback = nwMiniUlpProcessStackReqCallback;
|
||||||
|
|
||||||
|
rc = nwGtpv1uSetUlpEntity(hGtpv1uStack, &ulp);
|
||||||
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
|
|
||||||
logLevelStr = getenv ("NW_LOG_LEVEL");
|
/*---------------------------------------------------------------------------
|
||||||
|
* Set up Udp Entity
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
if(logLevelStr == NULL) {
|
rc = nwMiniUdpInit(&udpObj, hGtpv1uStack, (argv[2]));
|
||||||
logLevel = NW_LOG_LEVEL_INFO;
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
} else {
|
|
||||||
if(strncmp(logLevelStr, "EMER",4) == 0) {
|
|
||||||
logLevel = NW_LOG_LEVEL_EMER;
|
|
||||||
} else if(strncmp(logLevelStr, "ALER",4) == 0) {
|
|
||||||
logLevel = NW_LOG_LEVEL_ALER;
|
|
||||||
} else if(strncmp(logLevelStr, "CRIT",4) == 0) {
|
|
||||||
logLevel = NW_LOG_LEVEL_CRIT;
|
|
||||||
} else if(strncmp(logLevelStr, "ERRO",4) == 0) {
|
|
||||||
logLevel = NW_LOG_LEVEL_ERRO ;
|
|
||||||
} else if(strncmp(logLevelStr, "WARN",4) == 0) {
|
|
||||||
logLevel = NW_LOG_LEVEL_WARN;
|
|
||||||
} else if(strncmp(logLevelStr, "NOTI",4) == 0) {
|
|
||||||
logLevel = NW_LOG_LEVEL_NOTI;
|
|
||||||
} else if(strncmp(logLevelStr, "INFO",4) == 0) {
|
|
||||||
logLevel = NW_LOG_LEVEL_INFO;
|
|
||||||
} else if(strncmp(logLevelStr, "DEBG",4) == 0) {
|
|
||||||
logLevel = NW_LOG_LEVEL_DEBG;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
udp.hUdp = (NwGtpv1uUdpHandleT) &udpObj;
|
||||||
* Initialize event library
|
udp.udpDataReqCallback = nwMiniUdpDataReq;
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
NW_EVT_INIT();
|
rc = nwGtpv1uSetUdpEntity(hGtpv1uStack, &udp);
|
||||||
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Initialize Log Manager
|
* Set up Log Entity
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
nwMiniLogMgrInit(&logObj, logLevel);
|
tmrMgr.tmrMgrHandle = 0;
|
||||||
|
tmrMgr.tmrStartCallback = nwTimerStart;
|
||||||
|
tmrMgr.tmrStopCallback = nwTimerStop;
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
rc = nwGtpv1uSetTimerMgrEntity(hGtpv1uStack, &tmrMgr);
|
||||||
* Create GTPv1u Stack Instance
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
rc = nwGtpv1uInitialize(&hGtpv1uStack);
|
/*---------------------------------------------------------------------------
|
||||||
|
* Set up Log Entity
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
if(rc != NW_GTPV1U_OK) {
|
logMgr.logMgrHandle = (NwGtpv1uLogMgrHandleT) &logObj;
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO,
|
logMgr.logReqCallback = nwMiniLogMgrLogRequest;
|
||||||
"Failed to create gtpv1u stack instance. Error '%u' occured", rc);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
NW_LOG(NW_LOG_LEVEL_INFO, "Gtpv1u Stack Handle '%X' Creation Successful!",
|
rc = nwGtpv1uSetLogMgrEntity(hGtpv1uStack, &logMgr);
|
||||||
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Set GTPv1u log level
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
rc = nwGtpv1uSetLogLevel(hGtpv1uStack, logLevel);
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Send Create Session Request to GTPv1u Stack Instance
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
num_of_connections = atoi(argv[1]);
|
||||||
|
|
||||||
|
while ( num_of_connections-- ) {
|
||||||
|
//rc = nwMiniUlpCreateConn(&ulpObj, argv[2], 1234 + num_of_connections, argv[3]);
|
||||||
|
rc = nwMiniUlpSendEchoRequestToPeer(&ulpObj, inet_addr(argv[3]));
|
||||||
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
}
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Event loop
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
NW_EVT_LOOP();
|
||||||
|
|
||||||
|
NW_LOG(NW_LOG_LEVEL_ERRO, "Exit from eventloop, no events to process!");
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Send Destroy Session Request to GTPv1u Stack Instance
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
rc = nwMiniUlpDestroyConn(&ulpObj);
|
||||||
|
NW_ASSERT( rc == NW_GTPV1U_OK );
|
||||||
|
|
||||||
|
|
||||||
|
/*---------------------------------------------------------------------------
|
||||||
|
* Destroy GTPv1u Stack Instance
|
||||||
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
rc = nwGtpv1uFinalize(hGtpv1uStack);
|
||||||
|
|
||||||
|
if(rc != NW_GTPV1U_OK) {
|
||||||
|
NW_LOG(NW_LOG_LEVEL_ERRO,
|
||||||
|
"Failed to finalize gtpv1u stack instance. Error '%u' occured", rc);
|
||||||
|
} else {
|
||||||
|
NW_LOG(NW_LOG_LEVEL_INFO, "Gtpv1u Stack Handle '%X' Finalize Successful!",
|
||||||
hGtpv1uStack);
|
hGtpv1uStack);
|
||||||
|
}
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
* Set up Ulp Entity
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
rc = nwMiniUlpInit(&ulpObj, hGtpv1uStack);
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
|
||||||
|
|
||||||
ulp.hUlp = (NwGtpv1uUlpHandleT) &ulpObj;
|
|
||||||
ulp.ulpReqCallback = nwMiniUlpProcessStackReqCallback;
|
|
||||||
|
|
||||||
rc = nwGtpv1uSetUlpEntity(hGtpv1uStack, &ulp);
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
return rc;
|
||||||
* Set up Udp Entity
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
rc = nwMiniUdpInit(&udpObj, hGtpv1uStack, (argv[2]));
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
|
||||||
|
|
||||||
udp.hUdp = (NwGtpv1uUdpHandleT) &udpObj;
|
|
||||||
udp.udpDataReqCallback = nwMiniUdpDataReq;
|
|
||||||
|
|
||||||
rc = nwGtpv1uSetUdpEntity(hGtpv1uStack, &udp);
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
* Set up Log Entity
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
tmrMgr.tmrMgrHandle = 0;
|
|
||||||
tmrMgr.tmrStartCallback = nwTimerStart;
|
|
||||||
tmrMgr.tmrStopCallback = nwTimerStop;
|
|
||||||
|
|
||||||
rc = nwGtpv1uSetTimerMgrEntity(hGtpv1uStack, &tmrMgr);
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
* Set up Log Entity
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
logMgr.logMgrHandle = (NwGtpv1uLogMgrHandleT) &logObj;
|
|
||||||
logMgr.logReqCallback = nwMiniLogMgrLogRequest;
|
|
||||||
|
|
||||||
rc = nwGtpv1uSetLogMgrEntity(hGtpv1uStack, &logMgr);
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
* Set GTPv1u log level
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
rc = nwGtpv1uSetLogLevel(hGtpv1uStack, logLevel);
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
* Send Create Session Request to GTPv1u Stack Instance
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
num_of_connections = atoi(argv[1]);
|
|
||||||
|
|
||||||
while ( num_of_connections-- ) {
|
|
||||||
//rc = nwMiniUlpCreateConn(&ulpObj, argv[2], 1234 + num_of_connections, argv[3]);
|
|
||||||
rc = nwMiniUlpSendEchoRequestToPeer(&ulpObj, inet_addr(argv[3]));
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
|
||||||
}
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
* Event loop
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
NW_EVT_LOOP();
|
|
||||||
|
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "Exit from eventloop, no events to process!");
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
* Send Destroy Session Request to GTPv1u Stack Instance
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
rc = nwMiniUlpDestroyConn(&ulpObj);
|
|
||||||
NW_ASSERT( rc == NW_GTPV1U_OK );
|
|
||||||
|
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
|
||||||
* Destroy GTPv1u Stack Instance
|
|
||||||
*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
rc = nwGtpv1uFinalize(hGtpv1uStack);
|
|
||||||
|
|
||||||
if(rc != NW_GTPV1U_OK) {
|
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO,
|
|
||||||
"Failed to finalize gtpv1u stack instance. Error '%u' occured", rc);
|
|
||||||
} else {
|
|
||||||
NW_LOG(NW_LOG_LEVEL_INFO, "Gtpv1u Stack Handle '%X' Finalize Successful!",
|
|
||||||
hGtpv1uStack);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return rc;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -37,8 +37,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include "NwLog.h"
|
#include "NwLog.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv2cLog.h
|
* @file NwGtpv2cLog.h
|
||||||
* @brief This header contains logging related definitions.
|
* @brief This header contains logging related definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -37,13 +37,12 @@
|
|||||||
#include "NwTypes.h"
|
#include "NwTypes.h"
|
||||||
#include "NwGtpv2c.h"
|
#include "NwGtpv2c.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv2cMsgParseInfo.h
|
* @file NwGtpv2cMsgParseInfo.h
|
||||||
* @brief This file defines APIs for to parse incoming messages.
|
* @brief This file defines APIs for to parse incoming messages.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwU8T groupedIeType;
|
NwU8T groupedIeType;
|
||||||
NwU16T mandatoryIeCount;
|
NwU16T mandatoryIeCount;
|
||||||
NwGtpv2cStackHandleT hStack;
|
NwGtpv2cStackHandleT hStack;
|
||||||
@@ -55,8 +54,7 @@ typedef struct
|
|||||||
|
|
||||||
} NwGtpv2cGroupedIeParseInfoT;
|
} NwGtpv2cGroupedIeParseInfoT;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwU16T msgType;
|
NwU16T msgType;
|
||||||
NwU16T mandatoryIeCount;
|
NwU16T mandatoryIeCount;
|
||||||
NwGtpv2cStackHandleT hStack;
|
NwGtpv2cStackHandleT hStack;
|
||||||
@@ -80,9 +78,9 @@ NwRcT
|
|||||||
nwGtpv2cMsgIeParseInfoDelete(NwGtpv2cMsgIeParseInfoT* thiz);
|
nwGtpv2cMsgIeParseInfoDelete(NwGtpv2cMsgIeParseInfoT* thiz);
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
||||||
NW_IN NwGtpv2cMsgHandleT hMsg,
|
NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_INOUT NwGtpv2cErrorT *pError);
|
NW_INOUT NwGtpv2cErrorT *pError);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -47,9 +47,9 @@
|
|||||||
#include "NwGtpv2cMsgIeParseInfo.h"
|
#include "NwGtpv2cMsgIeParseInfo.h"
|
||||||
#include "NwGtpv2cTunnel.h"
|
#include "NwGtpv2cTunnel.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv2cPrivate.h
|
* @file NwGtpv2cPrivate.h
|
||||||
* @brief This header file contains nw-gtpv2c private definitions not to be
|
* @brief This header file contains nw-gtpv2c private definitions not to be
|
||||||
* exposed to user application.
|
* exposed to user application.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -89,8 +89,7 @@ extern "C" {
|
|||||||
* gtpv2c stack class definition
|
* gtpv2c stack class definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv2cStack
|
typedef struct NwGtpv2cStack {
|
||||||
{
|
|
||||||
NwU32T id;
|
NwU32T id;
|
||||||
NwGtpv2cUlpEntityT ulp;
|
NwGtpv2cUlpEntityT ulp;
|
||||||
NwGtpv2cUdpEntityT udp;
|
NwGtpv2cUdpEntityT udp;
|
||||||
@@ -110,19 +109,18 @@ typedef struct NwGtpv2cStack
|
|||||||
RB_HEAD( NwGtpv2cOutstandingRxSeqNumTrxnMap, NwGtpv2cTrxn ) outstandingRxSeqNumMap;
|
RB_HEAD( NwGtpv2cOutstandingRxSeqNumTrxnMap, NwGtpv2cTrxn ) outstandingRxSeqNumMap;
|
||||||
RB_HEAD( NwGtpv2cActiveTimerList, NwGtpv2cTimeoutInfo ) activeTimerList;
|
RB_HEAD( NwGtpv2cActiveTimerList, NwGtpv2cTimeoutInfo ) activeTimerList;
|
||||||
NwHandleT hTmrMinHeap;
|
NwHandleT hTmrMinHeap;
|
||||||
} NwGtpv2cStackT;
|
} NwGtpv2cStackT;
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* Timeout Info Type Definition
|
* Timeout Info Type Definition
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* gtpv2c timeout info
|
* gtpv2c timeout info
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv2cTimeoutInfo
|
typedef struct NwGtpv2cTimeoutInfo {
|
||||||
{
|
|
||||||
NwGtpv2cStackHandleT hStack;
|
NwGtpv2cStackHandleT hStack;
|
||||||
struct timeval tvTimeout;
|
struct timeval tvTimeout;
|
||||||
NwU32T tmrType;
|
NwU32T tmrType;
|
||||||
@@ -144,8 +142,7 @@ typedef struct NwGtpv2cTimeoutInfo
|
|||||||
/**
|
/**
|
||||||
* NwGtpv2cMsgT holds gtpv2c messages to/from the peer.
|
* NwGtpv2cMsgT holds gtpv2c messages to/from the peer.
|
||||||
*/
|
*/
|
||||||
typedef struct NwGtpv2cMsgS
|
typedef struct NwGtpv2cMsgS {
|
||||||
{
|
|
||||||
NwU8T version;
|
NwU8T version;
|
||||||
NwU8T teidPresent;
|
NwU8T teidPresent;
|
||||||
NwU8T msgType;
|
NwU8T msgType;
|
||||||
@@ -171,8 +168,7 @@ typedef struct NwGtpv2cMsgS
|
|||||||
* Transaction structure
|
* Transaction structure
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv2cTrxn
|
typedef struct NwGtpv2cTrxn {
|
||||||
{
|
|
||||||
NwU32T seqNum;
|
NwU32T seqNum;
|
||||||
NwU32T peerIp;
|
NwU32T peerIp;
|
||||||
NwU32T peerPort;
|
NwU32T peerPort;
|
||||||
@@ -192,8 +188,7 @@ typedef struct NwGtpv2cTrxn
|
|||||||
* GTPv2c Path Context
|
* GTPv2c Path Context
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv2cPathS
|
typedef struct NwGtpv2cPathS {
|
||||||
{
|
|
||||||
NwU32T hUlpPath; /**< Handle to ULP path contect */
|
NwU32T hUlpPath; /**< Handle to ULP path contect */
|
||||||
NwU32T ipv4Address;
|
NwU32T ipv4Address;
|
||||||
NwU32T restartCounter;
|
NwU32T restartCounter;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -34,10 +34,10 @@
|
|||||||
/**
|
/**
|
||||||
* @file NwGtpv2cTrxn.h
|
* @file NwGtpv2cTrxn.h
|
||||||
* @author Amit Chawre
|
* @author Amit Chawre
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
* This header file contains required definitions and functions
|
* This header file contains required definitions and functions
|
||||||
* prototypes used by gtpv2c transactions.
|
* prototypes used by gtpv2c transactions.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -49,24 +49,24 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructotr
|
* Constructotr
|
||||||
*/
|
*/
|
||||||
NwGtpv2cTrxnT*
|
NwGtpv2cTrxnT*
|
||||||
nwGtpv2cTrxnNew( NW_IN NwGtpv2cStackT* pStack);
|
nwGtpv2cTrxnNew( NW_IN NwGtpv2cStackT* pStack);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Overloaded Constructotr
|
* Overloaded Constructotr
|
||||||
*/
|
*/
|
||||||
NwGtpv2cTrxnT*
|
NwGtpv2cTrxnT*
|
||||||
nwGtpv2cTrxnWithSeqNumNew( NW_IN NwGtpv2cStackT* pStack,
|
nwGtpv2cTrxnWithSeqNumNew( NW_IN NwGtpv2cStackT* pStack,
|
||||||
NW_IN NwU32T seqNum);
|
NW_IN NwU32T seqNum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Another overloaded constructor. Create transaction as outstanding
|
* Another overloaded constructor. Create transaction as outstanding
|
||||||
* RX transaction for detecting duplicated requests.
|
* RX transaction for detecting duplicated requests.
|
||||||
*
|
*
|
||||||
* @param[in] thiz : Pointer to stack.
|
* @param[in] thiz : Pointer to stack.
|
||||||
* @param[in] teidLocal : Trxn teid.
|
* @param[in] teidLocal : Trxn teid.
|
||||||
* @param[in] peerIp : Peer Ip address.
|
* @param[in] peerIp : Peer Ip address.
|
||||||
* @param[in] peerPort : Peer Ip port.
|
* @param[in] peerPort : Peer Ip port.
|
||||||
@@ -76,10 +76,10 @@ nwGtpv2cTrxnWithSeqNumNew( NW_IN NwGtpv2cStackT* pStack,
|
|||||||
|
|
||||||
NwGtpv2cTrxnT*
|
NwGtpv2cTrxnT*
|
||||||
nwGtpv2cTrxnOutstandingRxNew( NW_IN NwGtpv2cStackT* pStack,
|
nwGtpv2cTrxnOutstandingRxNew( NW_IN NwGtpv2cStackT* pStack,
|
||||||
NW_IN NwU32T teidLocal,
|
NW_IN NwU32T teidLocal,
|
||||||
NW_IN NwU32T peerIp,
|
NW_IN NwU32T peerIp,
|
||||||
NW_IN NwU32T peerPort,
|
NW_IN NwU32T peerPort,
|
||||||
NW_IN NwU32T seqNum);
|
NW_IN NwU32T seqNum);
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cTrxnDelete( NW_INOUT NwGtpv2cTrxnT **ppTrxn);
|
nwGtpv2cTrxnDelete( NW_INOUT NwGtpv2cTrxnT **ppTrxn);
|
||||||
@@ -96,7 +96,7 @@ nwGtpv2cTrxnStartDulpicateRequestWaitTimer(NwGtpv2cTrxnT* thiz);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Start timer to wait for rsp of a req message
|
* Start timer to wait for rsp of a req message
|
||||||
*
|
*
|
||||||
* @param[in] thiz : Pointer to transaction
|
* @param[in] thiz : Pointer to transaction
|
||||||
* @param[in] timeoutCallbackFunc : Timeout handler callback function.
|
* @param[in] timeoutCallbackFunc : Timeout handler callback function.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -50,8 +50,7 @@ extern "C" {
|
|||||||
|
|
||||||
struct NwGtpv2cStack;
|
struct NwGtpv2cStack;
|
||||||
|
|
||||||
typedef struct NwGtpv2cTunnel
|
typedef struct NwGtpv2cTunnel {
|
||||||
{
|
|
||||||
NwU32T teid;
|
NwU32T teid;
|
||||||
NwU32T ipv4AddrRemote;
|
NwU32T ipv4AddrRemote;
|
||||||
NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 1991, 1993
|
* Copyright (c) 1991, 1993
|
||||||
* The Regents of the University of California. All rights reserved.
|
* The Regents of the University of California. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
@@ -12,8 +12,8 @@
|
|||||||
* documentation and/or other materials provided with the distribution.
|
* documentation and/or other materials provided with the distribution.
|
||||||
* 3. All advertising materials mentioning features or use of this software
|
* 3. All advertising materials mentioning features or use of this software
|
||||||
* must display the following acknowledgement:
|
* must display the following acknowledgement:
|
||||||
* This product includes software developed by the University of
|
* This product includes software developed by the University of
|
||||||
* California, Berkeley and its contributors.
|
* California, Berkeley and its contributors.
|
||||||
* 4. Neither the name of the University nor the names of its contributors
|
* 4. Neither the name of the University nor the names of its contributors
|
||||||
* may be used to endorse or promote products derived from this software
|
* may be used to endorse or promote products derived from this software
|
||||||
* without specific prior written permission.
|
* without specific prior written permission.
|
||||||
@@ -30,12 +30,12 @@
|
|||||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
* SUCH DAMAGE.
|
* SUCH DAMAGE.
|
||||||
*
|
*
|
||||||
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
* @(#)queue.h 8.5 (Berkeley) 8/20/94
|
||||||
* $FreeBSD: src/sys/sys/queue.h,v 1.32.2.6 2001/12/18 10:09:02 ru Exp $
|
* $FreeBSD: src/sys/sys/queue.h,v 1.32.2.6 2001/12/18 10:09:02 ru Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _SYS_QUEUE_H_
|
#ifndef _SYS_QUEUE_H_
|
||||||
#define _SYS_QUEUE_H_
|
#define _SYS_QUEUE_H_
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -88,431 +88,431 @@
|
|||||||
* For details on the use of these macros, see the queue(3) manual page.
|
* For details on the use of these macros, see the queue(3) manual page.
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* SLIST LIST STAILQ TAILQ CIRCLEQ
|
* SLIST LIST STAILQ TAILQ CIRCLEQ
|
||||||
* _HEAD + + + + +
|
* _HEAD + + + + +
|
||||||
* _HEAD_INITIALIZER + + + + +
|
* _HEAD_INITIALIZER + + + + +
|
||||||
* _ENTRY + + + + +
|
* _ENTRY + + + + +
|
||||||
* _INIT + + + + +
|
* _INIT + + + + +
|
||||||
* _EMPTY + + + + +
|
* _EMPTY + + + + +
|
||||||
* _FIRST + + + + +
|
* _FIRST + + + + +
|
||||||
* _NEXT + + + + +
|
* _NEXT + + + + +
|
||||||
* _PREV - - - + +
|
* _PREV - - - + +
|
||||||
* _LAST - - + + +
|
* _LAST - - + + +
|
||||||
* _FOREACH + + + + +
|
* _FOREACH + + + + +
|
||||||
* _FOREACH_REVERSE - - - + +
|
* _FOREACH_REVERSE - - - + +
|
||||||
* _INSERT_HEAD + + + + +
|
* _INSERT_HEAD + + + + +
|
||||||
* _INSERT_BEFORE - + - + +
|
* _INSERT_BEFORE - + - + +
|
||||||
* _INSERT_AFTER + + + + +
|
* _INSERT_AFTER + + + + +
|
||||||
* _INSERT_TAIL - - + + +
|
* _INSERT_TAIL - - + + +
|
||||||
* _REMOVE_HEAD + - + - -
|
* _REMOVE_HEAD + - + - -
|
||||||
* _REMOVE + + + + +
|
* _REMOVE + + + + +
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Singly-linked List declarations.
|
* Singly-linked List declarations.
|
||||||
*/
|
*/
|
||||||
#define SLIST_HEAD(name, type) \
|
#define SLIST_HEAD(name, type) \
|
||||||
struct name { \
|
struct name { \
|
||||||
struct type *slh_first; /* first element */ \
|
struct type *slh_first; /* first element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define SLIST_HEAD_INITIALIZER(head) \
|
#define SLIST_HEAD_INITIALIZER(head) \
|
||||||
{ NULL }
|
{ NULL }
|
||||||
|
|
||||||
#define SLIST_ENTRY(type) \
|
#define SLIST_ENTRY(type) \
|
||||||
struct { \
|
struct { \
|
||||||
struct type *sle_next; /* next element */ \
|
struct type *sle_next; /* next element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Singly-linked List functions.
|
* Singly-linked List functions.
|
||||||
*/
|
*/
|
||||||
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
#define SLIST_EMPTY(head) ((head)->slh_first == NULL)
|
||||||
|
|
||||||
#define SLIST_FIRST(head) ((head)->slh_first)
|
#define SLIST_FIRST(head) ((head)->slh_first)
|
||||||
|
|
||||||
#define SLIST_FOREACH(var, head, field) \
|
#define SLIST_FOREACH(var, head, field) \
|
||||||
for ((var) = SLIST_FIRST((head)); \
|
for ((var) = SLIST_FIRST((head)); \
|
||||||
(var); \
|
(var); \
|
||||||
(var) = SLIST_NEXT((var), field))
|
(var) = SLIST_NEXT((var), field))
|
||||||
|
|
||||||
#define SLIST_INIT(head) do { \
|
#define SLIST_INIT(head) do { \
|
||||||
SLIST_FIRST((head)) = NULL; \
|
SLIST_FIRST((head)) = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
#define SLIST_INSERT_AFTER(slistelm, elm, field) do { \
|
||||||
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
SLIST_NEXT((elm), field) = SLIST_NEXT((slistelm), field); \
|
||||||
SLIST_NEXT((slistelm), field) = (elm); \
|
SLIST_NEXT((slistelm), field) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
#define SLIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
SLIST_NEXT((elm), field) = SLIST_FIRST((head)); \
|
||||||
SLIST_FIRST((head)) = (elm); \
|
SLIST_FIRST((head)) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
#define SLIST_NEXT(elm, field) ((elm)->field.sle_next)
|
||||||
|
|
||||||
#define SLIST_REMOVE(head, elm, type, field) do { \
|
#define SLIST_REMOVE(head, elm, type, field) do { \
|
||||||
if (SLIST_FIRST((head)) == (elm)) { \
|
if (SLIST_FIRST((head)) == (elm)) { \
|
||||||
SLIST_REMOVE_HEAD((head), field); \
|
SLIST_REMOVE_HEAD((head), field); \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
struct type *curelm = SLIST_FIRST((head)); \
|
struct type *curelm = SLIST_FIRST((head)); \
|
||||||
while (SLIST_NEXT(curelm, field) != (elm)) \
|
while (SLIST_NEXT(curelm, field) != (elm)) \
|
||||||
curelm = SLIST_NEXT(curelm, field); \
|
curelm = SLIST_NEXT(curelm, field); \
|
||||||
SLIST_NEXT(curelm, field) = \
|
SLIST_NEXT(curelm, field) = \
|
||||||
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
SLIST_NEXT(SLIST_NEXT(curelm, field), field); \
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define SLIST_REMOVE_HEAD(head, field) do { \
|
#define SLIST_REMOVE_HEAD(head, field) do { \
|
||||||
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
SLIST_FIRST((head)) = SLIST_NEXT(SLIST_FIRST((head)), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Singly-linked Tail queue declarations.
|
* Singly-linked Tail queue declarations.
|
||||||
*/
|
*/
|
||||||
#define STAILQ_HEAD(name, type) \
|
#define STAILQ_HEAD(name, type) \
|
||||||
struct name { \
|
struct name { \
|
||||||
struct type *stqh_first;/* first element */ \
|
struct type *stqh_first;/* first element */ \
|
||||||
struct type **stqh_last;/* addr of last next element */ \
|
struct type **stqh_last;/* addr of last next element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define STAILQ_HEAD_INITIALIZER(head) \
|
#define STAILQ_HEAD_INITIALIZER(head) \
|
||||||
{ NULL, &(head).stqh_first }
|
{ NULL, &(head).stqh_first }
|
||||||
|
|
||||||
#define STAILQ_HEAD_INIT(head) do{ \
|
#define STAILQ_HEAD_INIT(head) do{ \
|
||||||
(head).stqh_first = NULL; \
|
(head).stqh_first = NULL; \
|
||||||
(head).stqh_last = &(head).stqh_first; \
|
(head).stqh_last = &(head).stqh_first; \
|
||||||
}while(0)
|
}while(0)
|
||||||
|
|
||||||
#define STAILQ_ENTRY(type) \
|
#define STAILQ_ENTRY(type) \
|
||||||
struct { \
|
struct { \
|
||||||
struct type *stqe_next; /* next element */ \
|
struct type *stqe_next; /* next element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Singly-linked Tail queue functions.
|
* Singly-linked Tail queue functions.
|
||||||
*/
|
*/
|
||||||
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
#define STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
|
||||||
|
|
||||||
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
#define STAILQ_FIRST(head) ((head)->stqh_first)
|
||||||
|
|
||||||
#define STAILQ_FOREACH(var, head, field) \
|
#define STAILQ_FOREACH(var, head, field) \
|
||||||
for((var) = STAILQ_FIRST((head)); \
|
for((var) = STAILQ_FIRST((head)); \
|
||||||
(var); \
|
(var); \
|
||||||
(var) = STAILQ_NEXT((var), field))
|
(var) = STAILQ_NEXT((var), field))
|
||||||
|
|
||||||
#define STAILQ_INIT(head) do { \
|
#define STAILQ_INIT(head) do { \
|
||||||
STAILQ_FIRST((head)) = NULL; \
|
STAILQ_FIRST((head)) = NULL; \
|
||||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
#define STAILQ_INSERT_AFTER(head, tqelm, elm, field) do { \
|
||||||
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
if ((STAILQ_NEXT((elm), field) = STAILQ_NEXT((tqelm), field)) == NULL)\
|
||||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||||
STAILQ_NEXT((tqelm), field) = (elm); \
|
STAILQ_NEXT((tqelm), field) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
#define STAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
if ((STAILQ_NEXT((elm), field) = STAILQ_FIRST((head))) == NULL) \
|
||||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||||
STAILQ_FIRST((head)) = (elm); \
|
STAILQ_FIRST((head)) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
#define STAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
STAILQ_NEXT((elm), field) = NULL; \
|
STAILQ_NEXT((elm), field) = NULL; \
|
||||||
*(head)->stqh_last = (elm); \
|
*(head)->stqh_last = (elm); \
|
||||||
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
(head)->stqh_last = &STAILQ_NEXT((elm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_LAST(head, type, field) \
|
#define STAILQ_LAST(head, type, field) \
|
||||||
(STAILQ_EMPTY(head) ? \
|
(STAILQ_EMPTY(head) ? \
|
||||||
NULL : \
|
NULL : \
|
||||||
((struct type *) \
|
((struct type *) \
|
||||||
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
|
((char *)((head)->stqh_last) - __offsetof(struct type, field))))
|
||||||
|
|
||||||
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
#define STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
|
||||||
|
|
||||||
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
#define STAILQ_REMOVE(head, elm, type, field) do { \
|
||||||
if (STAILQ_FIRST((head)) == (elm)) { \
|
if (STAILQ_FIRST((head)) == (elm)) { \
|
||||||
STAILQ_REMOVE_HEAD(head, field); \
|
STAILQ_REMOVE_HEAD(head, field); \
|
||||||
} \
|
} \
|
||||||
else { \
|
else { \
|
||||||
struct type *curelm = STAILQ_FIRST((head)); \
|
struct type *curelm = STAILQ_FIRST((head)); \
|
||||||
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
while (STAILQ_NEXT(curelm, field) != (elm)) \
|
||||||
curelm = STAILQ_NEXT(curelm, field); \
|
curelm = STAILQ_NEXT(curelm, field); \
|
||||||
if ((STAILQ_NEXT(curelm, field) = \
|
if ((STAILQ_NEXT(curelm, field) = \
|
||||||
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
|
STAILQ_NEXT(STAILQ_NEXT(curelm, field), field)) == NULL)\
|
||||||
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
|
(head)->stqh_last = &STAILQ_NEXT((curelm), field);\
|
||||||
} \
|
} \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
#define STAILQ_REMOVE_HEAD(head, field) do { \
|
||||||
if ((STAILQ_FIRST((head)) = \
|
if ((STAILQ_FIRST((head)) = \
|
||||||
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
STAILQ_NEXT(STAILQ_FIRST((head)), field)) == NULL) \
|
||||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
|
#define STAILQ_REMOVE_HEAD_UNTIL(head, elm, field) do { \
|
||||||
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
if ((STAILQ_FIRST((head)) = STAILQ_NEXT((elm), field)) == NULL) \
|
||||||
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
(head)->stqh_last = &STAILQ_FIRST((head)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List declarations.
|
* List declarations.
|
||||||
*/
|
*/
|
||||||
#define LIST_HEAD(name, type) \
|
#define LIST_HEAD(name, type) \
|
||||||
struct name { \
|
struct name { \
|
||||||
struct type *lh_first; /* first element */ \
|
struct type *lh_first; /* first element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define LIST_HEAD_INITIALIZER(head) \
|
#define LIST_HEAD_INITIALIZER(head) \
|
||||||
{ NULL }
|
{ NULL }
|
||||||
|
|
||||||
#define LIST_ENTRY(type) \
|
#define LIST_ENTRY(type) \
|
||||||
struct { \
|
struct { \
|
||||||
struct type *le_next; /* next element */ \
|
struct type *le_next; /* next element */ \
|
||||||
struct type **le_prev; /* address of previous next element */ \
|
struct type **le_prev; /* address of previous next element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* List functions.
|
* List functions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
#define LIST_EMPTY(head) ((head)->lh_first == NULL)
|
||||||
|
|
||||||
#define LIST_FIRST(head) ((head)->lh_first)
|
#define LIST_FIRST(head) ((head)->lh_first)
|
||||||
|
|
||||||
#define LIST_FOREACH(var, head, field) \
|
#define LIST_FOREACH(var, head, field) \
|
||||||
for ((var) = LIST_FIRST((head)); \
|
for ((var) = LIST_FIRST((head)); \
|
||||||
(var); \
|
(var); \
|
||||||
(var) = LIST_NEXT((var), field))
|
(var) = LIST_NEXT((var), field))
|
||||||
|
|
||||||
#define LIST_INIT(head) do { \
|
#define LIST_INIT(head) do { \
|
||||||
LIST_FIRST((head)) = NULL; \
|
LIST_FIRST((head)) = NULL; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
#define LIST_INSERT_AFTER(listelm, elm, field) do { \
|
||||||
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
if ((LIST_NEXT((elm), field) = LIST_NEXT((listelm), field)) != NULL)\
|
||||||
LIST_NEXT((listelm), field)->field.le_prev = \
|
LIST_NEXT((listelm), field)->field.le_prev = \
|
||||||
&LIST_NEXT((elm), field); \
|
&LIST_NEXT((elm), field); \
|
||||||
LIST_NEXT((listelm), field) = (elm); \
|
LIST_NEXT((listelm), field) = (elm); \
|
||||||
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
(elm)->field.le_prev = &LIST_NEXT((listelm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
#define LIST_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
(elm)->field.le_prev = (listelm)->field.le_prev; \
|
||||||
LIST_NEXT((elm), field) = (listelm); \
|
LIST_NEXT((elm), field) = (listelm); \
|
||||||
*(listelm)->field.le_prev = (elm); \
|
*(listelm)->field.le_prev = (elm); \
|
||||||
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
(listelm)->field.le_prev = &LIST_NEXT((elm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
#define LIST_INSERT_HEAD(head, elm, field) do { \
|
||||||
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
if ((LIST_NEXT((elm), field) = LIST_FIRST((head))) != NULL) \
|
||||||
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
LIST_FIRST((head))->field.le_prev = &LIST_NEXT((elm), field);\
|
||||||
LIST_FIRST((head)) = (elm); \
|
LIST_FIRST((head)) = (elm); \
|
||||||
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
(elm)->field.le_prev = &LIST_FIRST((head)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
#define LIST_NEXT(elm, field) ((elm)->field.le_next)
|
||||||
|
|
||||||
#define LIST_REMOVE(elm, field) do { \
|
#define LIST_REMOVE(elm, field) do { \
|
||||||
if (LIST_NEXT((elm), field) != NULL) \
|
if (LIST_NEXT((elm), field) != NULL) \
|
||||||
LIST_NEXT((elm), field)->field.le_prev = \
|
LIST_NEXT((elm), field)->field.le_prev = \
|
||||||
(elm)->field.le_prev; \
|
(elm)->field.le_prev; \
|
||||||
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
*(elm)->field.le_prev = LIST_NEXT((elm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tail queue declarations.
|
* Tail queue declarations.
|
||||||
*/
|
*/
|
||||||
#define TAILQ_HEAD(name, type) \
|
#define TAILQ_HEAD(name, type) \
|
||||||
struct name { \
|
struct name { \
|
||||||
struct type *tqh_first; /* first element */ \
|
struct type *tqh_first; /* first element */ \
|
||||||
struct type **tqh_last; /* addr of last next element */ \
|
struct type **tqh_last; /* addr of last next element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TAILQ_HEAD_INITIALIZER(head) \
|
#define TAILQ_HEAD_INITIALIZER(head) \
|
||||||
{ NULL, &(head).tqh_first }
|
{ NULL, &(head).tqh_first }
|
||||||
|
|
||||||
#define TAILQ_ENTRY(type) \
|
#define TAILQ_ENTRY(type) \
|
||||||
struct { \
|
struct { \
|
||||||
struct type *tqe_next; /* next element */ \
|
struct type *tqe_next; /* next element */ \
|
||||||
struct type **tqe_prev; /* address of previous next element */ \
|
struct type **tqe_prev; /* address of previous next element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Tail queue functions.
|
* Tail queue functions.
|
||||||
*/
|
*/
|
||||||
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
#define TAILQ_EMPTY(head) ((head)->tqh_first == NULL)
|
||||||
|
|
||||||
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
#define TAILQ_FIRST(head) ((head)->tqh_first)
|
||||||
|
|
||||||
#define TAILQ_FOREACH(var, head, field) \
|
#define TAILQ_FOREACH(var, head, field) \
|
||||||
for ((var) = TAILQ_FIRST((head)); \
|
for ((var) = TAILQ_FIRST((head)); \
|
||||||
(var); \
|
(var); \
|
||||||
(var) = TAILQ_NEXT((var), field))
|
(var) = TAILQ_NEXT((var), field))
|
||||||
|
|
||||||
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
#define TAILQ_FOREACH_REVERSE(var, head, headname, field) \
|
||||||
for ((var) = TAILQ_LAST((head), headname); \
|
for ((var) = TAILQ_LAST((head), headname); \
|
||||||
(var); \
|
(var); \
|
||||||
(var) = TAILQ_PREV((var), headname, field))
|
(var) = TAILQ_PREV((var), headname, field))
|
||||||
|
|
||||||
#define TAILQ_INIT(head) do { \
|
#define TAILQ_INIT(head) do { \
|
||||||
TAILQ_FIRST((head)) = NULL; \
|
TAILQ_FIRST((head)) = NULL; \
|
||||||
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
(head)->tqh_last = &TAILQ_FIRST((head)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
#define TAILQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
if ((TAILQ_NEXT((elm), field) = TAILQ_NEXT((listelm), field)) != NULL)\
|
||||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||||
&TAILQ_NEXT((elm), field); \
|
&TAILQ_NEXT((elm), field); \
|
||||||
else \
|
else \
|
||||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||||
TAILQ_NEXT((listelm), field) = (elm); \
|
TAILQ_NEXT((listelm), field) = (elm); \
|
||||||
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
(elm)->field.tqe_prev = &TAILQ_NEXT((listelm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
#define TAILQ_INSERT_BEFORE(listelm, elm, field) do { \
|
||||||
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
(elm)->field.tqe_prev = (listelm)->field.tqe_prev; \
|
||||||
TAILQ_NEXT((elm), field) = (listelm); \
|
TAILQ_NEXT((elm), field) = (listelm); \
|
||||||
*(listelm)->field.tqe_prev = (elm); \
|
*(listelm)->field.tqe_prev = (elm); \
|
||||||
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
(listelm)->field.tqe_prev = &TAILQ_NEXT((elm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
#define TAILQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
if ((TAILQ_NEXT((elm), field) = TAILQ_FIRST((head))) != NULL) \
|
||||||
TAILQ_FIRST((head))->field.tqe_prev = \
|
TAILQ_FIRST((head))->field.tqe_prev = \
|
||||||
&TAILQ_NEXT((elm), field); \
|
&TAILQ_NEXT((elm), field); \
|
||||||
else \
|
else \
|
||||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||||
TAILQ_FIRST((head)) = (elm); \
|
TAILQ_FIRST((head)) = (elm); \
|
||||||
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
(elm)->field.tqe_prev = &TAILQ_FIRST((head)); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
#define TAILQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
TAILQ_NEXT((elm), field) = NULL; \
|
TAILQ_NEXT((elm), field) = NULL; \
|
||||||
(elm)->field.tqe_prev = (head)->tqh_last; \
|
(elm)->field.tqe_prev = (head)->tqh_last; \
|
||||||
*(head)->tqh_last = (elm); \
|
*(head)->tqh_last = (elm); \
|
||||||
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
(head)->tqh_last = &TAILQ_NEXT((elm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define TAILQ_LAST(head, headname) \
|
#define TAILQ_LAST(head, headname) \
|
||||||
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
(*(((struct headname *)((head)->tqh_last))->tqh_last))
|
||||||
|
|
||||||
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
#define TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
|
||||||
|
|
||||||
#define TAILQ_PREV(elm, headname, field) \
|
#define TAILQ_PREV(elm, headname, field) \
|
||||||
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
(*(((struct headname *)((elm)->field.tqe_prev))->tqh_last))
|
||||||
|
|
||||||
#define TAILQ_REMOVE(head, elm, field) do { \
|
#define TAILQ_REMOVE(head, elm, field) do { \
|
||||||
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
if ((TAILQ_NEXT((elm), field)) != NULL) \
|
||||||
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
TAILQ_NEXT((elm), field)->field.tqe_prev = \
|
||||||
(elm)->field.tqe_prev; \
|
(elm)->field.tqe_prev; \
|
||||||
else \
|
else \
|
||||||
(head)->tqh_last = (elm)->field.tqe_prev; \
|
(head)->tqh_last = (elm)->field.tqe_prev; \
|
||||||
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
*(elm)->field.tqe_prev = TAILQ_NEXT((elm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Circular queue declarations.
|
* Circular queue declarations.
|
||||||
*/
|
*/
|
||||||
#define CIRCLEQ_HEAD(name, type) \
|
#define CIRCLEQ_HEAD(name, type) \
|
||||||
struct name { \
|
struct name { \
|
||||||
struct type *cqh_first; /* first element */ \
|
struct type *cqh_first; /* first element */ \
|
||||||
struct type *cqh_last; /* last element */ \
|
struct type *cqh_last; /* last element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
#define CIRCLEQ_HEAD_INITIALIZER(head) \
|
||||||
{ (void *)&(head), (void *)&(head) }
|
{ (void *)&(head), (void *)&(head) }
|
||||||
|
|
||||||
#define CIRCLEQ_ENTRY(type) \
|
#define CIRCLEQ_ENTRY(type) \
|
||||||
struct { \
|
struct { \
|
||||||
struct type *cqe_next; /* next element */ \
|
struct type *cqe_next; /* next element */ \
|
||||||
struct type *cqe_prev; /* previous element */ \
|
struct type *cqe_prev; /* previous element */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Circular queue functions.
|
* Circular queue functions.
|
||||||
*/
|
*/
|
||||||
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
|
#define CIRCLEQ_EMPTY(head) ((head)->cqh_first == (void *)(head))
|
||||||
|
|
||||||
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
#define CIRCLEQ_FIRST(head) ((head)->cqh_first)
|
||||||
|
|
||||||
#define CIRCLEQ_FOREACH(var, head, field) \
|
#define CIRCLEQ_FOREACH(var, head, field) \
|
||||||
for ((var) = CIRCLEQ_FIRST((head)); \
|
for ((var) = CIRCLEQ_FIRST((head)); \
|
||||||
(var) != (void *)(head); \
|
(var) != (void *)(head); \
|
||||||
(var) = CIRCLEQ_NEXT((var), field))
|
(var) = CIRCLEQ_NEXT((var), field))
|
||||||
|
|
||||||
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
#define CIRCLEQ_FOREACH_REVERSE(var, head, field) \
|
||||||
for ((var) = CIRCLEQ_LAST((head)); \
|
for ((var) = CIRCLEQ_LAST((head)); \
|
||||||
(var) != (void *)(head); \
|
(var) != (void *)(head); \
|
||||||
(var) = CIRCLEQ_PREV((var), field))
|
(var) = CIRCLEQ_PREV((var), field))
|
||||||
|
|
||||||
#define CIRCLEQ_INIT(head) do { \
|
#define CIRCLEQ_INIT(head) do { \
|
||||||
CIRCLEQ_FIRST((head)) = (void *)(head); \
|
CIRCLEQ_FIRST((head)) = (void *)(head); \
|
||||||
CIRCLEQ_LAST((head)) = (void *)(head); \
|
CIRCLEQ_LAST((head)) = (void *)(head); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
#define CIRCLEQ_INSERT_AFTER(head, listelm, elm, field) do { \
|
||||||
CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \
|
CIRCLEQ_NEXT((elm), field) = CIRCLEQ_NEXT((listelm), field); \
|
||||||
CIRCLEQ_PREV((elm), field) = (listelm); \
|
CIRCLEQ_PREV((elm), field) = (listelm); \
|
||||||
if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \
|
if (CIRCLEQ_NEXT((listelm), field) == (void *)(head)) \
|
||||||
CIRCLEQ_LAST((head)) = (elm); \
|
CIRCLEQ_LAST((head)) = (elm); \
|
||||||
else \
|
else \
|
||||||
CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\
|
CIRCLEQ_PREV(CIRCLEQ_NEXT((listelm), field), field) = (elm);\
|
||||||
CIRCLEQ_NEXT((listelm), field) = (elm); \
|
CIRCLEQ_NEXT((listelm), field) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
#define CIRCLEQ_INSERT_BEFORE(head, listelm, elm, field) do { \
|
||||||
CIRCLEQ_NEXT((elm), field) = (listelm); \
|
CIRCLEQ_NEXT((elm), field) = (listelm); \
|
||||||
CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \
|
CIRCLEQ_PREV((elm), field) = CIRCLEQ_PREV((listelm), field); \
|
||||||
if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \
|
if (CIRCLEQ_PREV((listelm), field) == (void *)(head)) \
|
||||||
CIRCLEQ_FIRST((head)) = (elm); \
|
CIRCLEQ_FIRST((head)) = (elm); \
|
||||||
else \
|
else \
|
||||||
CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\
|
CIRCLEQ_NEXT(CIRCLEQ_PREV((listelm), field), field) = (elm);\
|
||||||
CIRCLEQ_PREV((listelm), field) = (elm); \
|
CIRCLEQ_PREV((listelm), field) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
#define CIRCLEQ_INSERT_HEAD(head, elm, field) do { \
|
||||||
CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \
|
CIRCLEQ_NEXT((elm), field) = CIRCLEQ_FIRST((head)); \
|
||||||
CIRCLEQ_PREV((elm), field) = (void *)(head); \
|
CIRCLEQ_PREV((elm), field) = (void *)(head); \
|
||||||
if (CIRCLEQ_LAST((head)) == (void *)(head)) \
|
if (CIRCLEQ_LAST((head)) == (void *)(head)) \
|
||||||
CIRCLEQ_LAST((head)) = (elm); \
|
CIRCLEQ_LAST((head)) = (elm); \
|
||||||
else \
|
else \
|
||||||
CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \
|
CIRCLEQ_PREV(CIRCLEQ_FIRST((head)), field) = (elm); \
|
||||||
CIRCLEQ_FIRST((head)) = (elm); \
|
CIRCLEQ_FIRST((head)) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
#define CIRCLEQ_INSERT_TAIL(head, elm, field) do { \
|
||||||
CIRCLEQ_NEXT((elm), field) = (void *)(head); \
|
CIRCLEQ_NEXT((elm), field) = (void *)(head); \
|
||||||
CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \
|
CIRCLEQ_PREV((elm), field) = CIRCLEQ_LAST((head)); \
|
||||||
if (CIRCLEQ_FIRST((head)) == (void *)(head)) \
|
if (CIRCLEQ_FIRST((head)) == (void *)(head)) \
|
||||||
CIRCLEQ_FIRST((head)) = (elm); \
|
CIRCLEQ_FIRST((head)) = (elm); \
|
||||||
else \
|
else \
|
||||||
CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \
|
CIRCLEQ_NEXT(CIRCLEQ_LAST((head)), field) = (elm); \
|
||||||
CIRCLEQ_LAST((head)) = (elm); \
|
CIRCLEQ_LAST((head)) = (elm); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
#define CIRCLEQ_LAST(head) ((head)->cqh_last)
|
||||||
|
|
||||||
#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
|
#define CIRCLEQ_NEXT(elm,field) ((elm)->field.cqe_next)
|
||||||
|
|
||||||
#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
|
#define CIRCLEQ_PREV(elm,field) ((elm)->field.cqe_prev)
|
||||||
|
|
||||||
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
#define CIRCLEQ_REMOVE(head, elm, field) do { \
|
||||||
if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \
|
if (CIRCLEQ_NEXT((elm), field) == (void *)(head)) \
|
||||||
CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \
|
CIRCLEQ_LAST((head)) = CIRCLEQ_PREV((elm), field); \
|
||||||
else \
|
else \
|
||||||
CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \
|
CIRCLEQ_PREV(CIRCLEQ_NEXT((elm), field), field) = \
|
||||||
CIRCLEQ_PREV((elm), field); \
|
CIRCLEQ_PREV((elm), field); \
|
||||||
if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \
|
if (CIRCLEQ_PREV((elm), field) == (void *)(head)) \
|
||||||
CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \
|
CIRCLEQ_FIRST((head)) = CIRCLEQ_NEXT((elm), field); \
|
||||||
else \
|
else \
|
||||||
CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \
|
CIRCLEQ_NEXT(CIRCLEQ_PREV((elm), field), field) = \
|
||||||
CIRCLEQ_NEXT((elm), field); \
|
CIRCLEQ_NEXT((elm), field); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#ifdef _KERNEL
|
#ifdef _KERNEL
|
||||||
@@ -523,38 +523,38 @@ struct { \
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
struct quehead {
|
struct quehead {
|
||||||
struct quehead *qh_link;
|
struct quehead *qh_link;
|
||||||
struct quehead *qh_rlink;
|
struct quehead *qh_rlink;
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
insque(void *a, void *b)
|
insque(void *a, void *b)
|
||||||
{
|
{
|
||||||
struct quehead *element = (struct quehead *)a,
|
struct quehead *element = (struct quehead *)a,
|
||||||
*head = (struct quehead *)b;
|
*head = (struct quehead *)b;
|
||||||
|
|
||||||
element->qh_link = head->qh_link;
|
element->qh_link = head->qh_link;
|
||||||
element->qh_rlink = head;
|
element->qh_rlink = head;
|
||||||
head->qh_link = element;
|
head->qh_link = element;
|
||||||
element->qh_link->qh_rlink = element;
|
element->qh_link->qh_rlink = element;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __inline void
|
static __inline void
|
||||||
remque(void *a)
|
remque(void *a)
|
||||||
{
|
{
|
||||||
struct quehead *element = (struct quehead *)a;
|
struct quehead *element = (struct quehead *)a;
|
||||||
|
|
||||||
element->qh_link->qh_rlink = element->qh_rlink;
|
element->qh_link->qh_rlink = element->qh_rlink;
|
||||||
element->qh_rlink->qh_link = element->qh_link;
|
element->qh_rlink->qh_link = element->qh_link;
|
||||||
element->qh_rlink = 0;
|
element->qh_rlink = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#else /* !__GNUC__ */
|
#else /* !__GNUC__ */
|
||||||
|
|
||||||
void insque __P((void *a, void *b));
|
void insque __P((void *a, void *b));
|
||||||
void remque __P((void *a));
|
void remque __P((void *a));
|
||||||
|
|
||||||
#endif /* __GNUC__ */
|
#endif /* __GNUC__ */
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -35,8 +35,8 @@
|
|||||||
#ifndef __NW_ERROR_H__
|
#ifndef __NW_ERROR_H__
|
||||||
#define __NW_ERROR_H__
|
#define __NW_ERROR_H__
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwError.h
|
* @file NwError.h
|
||||||
* @brief This header file contains return error code type definitions.
|
* @brief This header file contains return error code type definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -54,7 +54,8 @@ typedef enum {
|
|||||||
NW_GTPV2C_MANDATORY_IE_MISSING,
|
NW_GTPV2C_MANDATORY_IE_MISSING,
|
||||||
NW_GTPV2C_MSG_MALFORMED,
|
NW_GTPV2C_MSG_MALFORMED,
|
||||||
NW_FAILURE = 0xFFFFFFFE
|
NW_FAILURE = 0xFFFFFFFE
|
||||||
} NwRcT;
|
}
|
||||||
|
NwRcT;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -44,46 +44,46 @@
|
|||||||
|
|
||||||
@section intro Introduction
|
@section intro Introduction
|
||||||
|
|
||||||
nw-gtpv2c library is a free and open source control plane implementation of GPRS
|
nw-gtpv2c library is a free and open source control plane implementation of GPRS
|
||||||
Tunneling protocol v2 also known as eGTPc as per 3GPP TS29274-930.
|
Tunneling protocol v2 also known as eGTPc as per 3GPP TS29274-930.
|
||||||
The library is published under BSD three clause license.
|
The library is published under BSD three clause license.
|
||||||
|
|
||||||
@section scope Scope
|
@section scope Scope
|
||||||
|
|
||||||
The stack library also does basic tasks like packet/header validation,
|
The stack library also does basic tasks like packet/header validation,
|
||||||
retransmission and message parsing.
|
retransmission and message parsing.
|
||||||
|
|
||||||
@section design Design Philosophy
|
@section design Design Philosophy
|
||||||
|
|
||||||
The stack is fully-asynchronous in design for compatibility with event loop
|
The stack is fully-asynchronous in design for compatibility with event loop
|
||||||
mechanisms such as select, poll, etc. and can also be used for multi-threaded
|
mechanisms such as select, poll, etc. and can also be used for multi-threaded
|
||||||
applications. It should compile on Linux, *BSD, Mac OS X, Solaris and Windows
|
applications. It should compile on Linux, *BSD, Mac OS X, Solaris and Windows
|
||||||
(cygwin).
|
(cygwin).
|
||||||
|
|
||||||
The stack is designed for high portability not only for the hardware and OS it will
|
The stack is designed for high portability not only for the hardware and OS it will
|
||||||
run on but also for the application software that uses it. The stack doesn't mandate
|
run on but also for the application software that uses it. The stack doesn't mandate
|
||||||
conditions on the user application architecture or design. The stack relies on
|
conditions on the user application architecture or design. The stack relies on
|
||||||
the user application for infrastructure utilities such as I/O, timers,
|
the user application for infrastructure utilities such as I/O, timers,
|
||||||
logs and multithreading. This realized by using callback mechanisms and enables the
|
logs and multithreading. This realized by using callback mechanisms and enables the
|
||||||
stack library to seamlessly integrate without or very little changes to the existing
|
stack library to seamlessly integrate without or very little changes to the existing
|
||||||
application framework.
|
application framework.
|
||||||
|
|
||||||
The stack architecture builds upon following mentioned entities that are external to it.
|
The stack architecture builds upon following mentioned entities that are external to it.
|
||||||
|
|
||||||
User Layer Protocol (ULP) Entity:
|
User Layer Protocol (ULP) Entity:
|
||||||
This layer implements the intelligent logic for the application and sits on top of the
|
This layer implements the intelligent logic for the application and sits on top of the
|
||||||
stack.
|
stack.
|
||||||
|
|
||||||
UDP Entity:
|
UDP Entity:
|
||||||
This is the layer below the stack and is responsible for UDP I/O with the stack and network.
|
This is the layer below the stack and is responsible for UDP I/O with the stack and network.
|
||||||
It may or may not be housed in ULP.
|
It may or may not be housed in ULP.
|
||||||
|
|
||||||
Timer Manager Entity:
|
Timer Manager Entity:
|
||||||
Timer Manager Entity provides the stack with infrastructure for timer CRUD operations.
|
Timer Manager Entity provides the stack with infrastructure for timer CRUD operations.
|
||||||
|
|
||||||
Log Manager Entity:
|
Log Manager Entity:
|
||||||
Log Manager Entity provides the stack with callbacks for logging operations. It may
|
Log Manager Entity provides the stack with callbacks for logging operations. It may
|
||||||
or may not be housed in ULP.
|
or may not be housed in ULP.
|
||||||
|
|
||||||
The application may implement all above entities as a single or multiple object.
|
The application may implement all above entities as a single or multiple object.
|
||||||
|
|
||||||
@@ -96,10 +96,10 @@
|
|||||||
/**
|
/**
|
||||||
* @file NwGtpv2c.h
|
* @file NwGtpv2c.h
|
||||||
* @author Amit Chawre
|
* @author Amit Chawre
|
||||||
* @brief
|
* @brief
|
||||||
*
|
*
|
||||||
* This header file contains all required definitions and functions
|
* This header file contains all required definitions and functions
|
||||||
* prototypes for using nw-gtpv2c library.
|
* prototypes for using nw-gtpv2c library.
|
||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
@@ -108,11 +108,11 @@
|
|||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
typedef NwPtrT NwGtpv2cStackHandleT; /**< Gtpv2c Stack Handle */
|
typedef NwPtrT NwGtpv2cStackHandleT; /**< Gtpv2c Stack Handle */
|
||||||
typedef NwPtrT NwGtpv2cUlpHandleT; /**< Gtpv2c Stack Ulp Entity Handle */
|
typedef NwPtrT NwGtpv2cUlpHandleT; /**< Gtpv2c Stack Ulp Entity Handle */
|
||||||
typedef NwPtrT NwGtpv2cUdpHandleT; /**< Gtpv2c Stack Udp Entity Handle */
|
typedef NwPtrT NwGtpv2cUdpHandleT; /**< Gtpv2c Stack Udp Entity Handle */
|
||||||
typedef NwPtrT NwGtpv2cTimerMgrHandleT; /**< Gtpv2c Stack Timer Manager Handle */
|
typedef NwPtrT NwGtpv2cTimerMgrHandleT; /**< Gtpv2c Stack Timer Manager Handle */
|
||||||
typedef NwPtrT NwGtpv2cMemMgrHandleT; /**< Gtpv2c Stack Memory Manager Handle */
|
typedef NwPtrT NwGtpv2cMemMgrHandleT; /**< Gtpv2c Stack Memory Manager Handle */
|
||||||
typedef NwPtrT NwGtpv2cLogMgrHandleT; /**< Gtpv2c Stack Log Manager Handle */
|
typedef NwPtrT NwGtpv2cLogMgrHandleT; /**< Gtpv2c Stack Log Manager Handle */
|
||||||
typedef NwPtrT NwGtpv2cTimerHandleT; /**< Gtpv2c Stack Timer Handle */
|
typedef NwPtrT NwGtpv2cTimerHandleT; /**< Gtpv2c Stack Timer Handle */
|
||||||
typedef NwPtrT NwGtpv2cMsgHandleT; /**< Gtpv2c Msg Handle */
|
typedef NwPtrT NwGtpv2cMsgHandleT; /**< Gtpv2c Msg Handle */
|
||||||
typedef NwPtrT NwGtpv2cTrxnHandleT; /**< Gtpv2c Transaction Handle */
|
typedef NwPtrT NwGtpv2cTrxnHandleT; /**< Gtpv2c Transaction Handle */
|
||||||
@@ -122,8 +122,7 @@ typedef NwPtrT NwGtpv2cUlpTunnelHandleT; /**< Gtpv2c Ulp
|
|||||||
|
|
||||||
typedef NwU8T NwGtpv2cMsgTypeT; /**< Gtpv2c Msg Type */
|
typedef NwU8T NwGtpv2cMsgTypeT; /**< Gtpv2c Msg Type */
|
||||||
|
|
||||||
typedef struct NwGtpv2cStackConfigS
|
typedef struct NwGtpv2cStackConfigS {
|
||||||
{
|
|
||||||
NwU16T __tbd;
|
NwU16T __tbd;
|
||||||
} NwGtpv2cStackConfigT;
|
} NwGtpv2cStackConfigT;
|
||||||
|
|
||||||
@@ -140,12 +139,11 @@ typedef struct NwGtpv2cStackConfigS
|
|||||||
* Gtpv2c Stack ULP API type definitions
|
* Gtpv2c Stack ULP API type definitions
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* APIs types between ULP and Stack
|
* APIs types between ULP and Stack
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef enum
|
typedef enum {
|
||||||
{
|
|
||||||
/* APIs from ULP to stack */
|
/* APIs from ULP to stack */
|
||||||
|
|
||||||
NW_GTPV2C_ULP_API_INITIAL_REQ = 0x00000000, /**< Send a initial message */
|
NW_GTPV2C_ULP_API_INITIAL_REQ = 0x00000000, /**< Send a initial message */
|
||||||
@@ -173,8 +171,7 @@ typedef enum
|
|||||||
* Error information of incoming GTP messages
|
* Error information of incoming GTP messages
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct NwGtpv2cErrorS
|
typedef struct NwGtpv2cErrorS {
|
||||||
{
|
|
||||||
NW_IN NwU8T cause;
|
NW_IN NwU8T cause;
|
||||||
NW_IN NwU8T flags;
|
NW_IN NwU8T flags;
|
||||||
struct {
|
struct {
|
||||||
@@ -183,13 +180,12 @@ typedef struct NwGtpv2cErrorS
|
|||||||
} offendingIe;
|
} offendingIe;
|
||||||
} NwGtpv2cErrorT;
|
} NwGtpv2cErrorT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv2c initial message.
|
* sending a Gtpv2c initial message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_INOUT NwGtpv2cTunnelHandleT hTunnel; /**< Tunnel handle over which the mesasge is to be sent.*/
|
NW_INOUT NwGtpv2cTunnelHandleT hTunnel; /**< Tunnel handle over which the mesasge is to be sent.*/
|
||||||
NW_IN NwU16T t3Timer;
|
NW_IN NwU16T t3Timer;
|
||||||
NW_IN NwU16T maxRetries;
|
NW_IN NwU16T maxRetries;
|
||||||
@@ -200,13 +196,12 @@ typedef struct
|
|||||||
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel; /**< Required only in case when hTunnel == 0 */
|
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel; /**< Required only in case when hTunnel == 0 */
|
||||||
} NwGtpv2cInitialReqInfoT;
|
} NwGtpv2cInitialReqInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv2c triggered request message.
|
* sending a Gtpv2c triggered request message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv2cTunnelHandleT hTunnel; /**< Tunnel handle over which the mesasge is to be sent */
|
NW_IN NwGtpv2cTunnelHandleT hTunnel; /**< Tunnel handle over which the mesasge is to be sent */
|
||||||
NW_IN NwGtpv2cTrxnHandleT hTrxn; /**< Request Trxn handle which to which triggered req is being sent */
|
NW_IN NwGtpv2cTrxnHandleT hTrxn; /**< Request Trxn handle which to which triggered req is being sent */
|
||||||
NW_IN NwU16T t3Timer;
|
NW_IN NwU16T t3Timer;
|
||||||
@@ -218,28 +213,26 @@ typedef struct
|
|||||||
|
|
||||||
} NwGtpv2cTriggeredReqInfoT;
|
} NwGtpv2cTriggeredReqInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv2c triggered response message.
|
* sending a Gtpv2c triggered response message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv2cTrxnHandleT hTrxn; /**< Request Trxn handle which to which triggered rsp is being sent */
|
NW_IN NwGtpv2cTrxnHandleT hTrxn; /**< Request Trxn handle which to which triggered rsp is being sent */
|
||||||
NW_IN NwU32T teidLocal; /**< Required only if NW_GTPV2C_ULP_API_FLAG_CREATE_LOCAL_TUNNEL is set to flags. */
|
NW_IN NwU32T teidLocal; /**< Required only if NW_GTPV2C_ULP_API_FLAG_CREATE_LOCAL_TUNNEL is set to flags. */
|
||||||
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel; /**< Required only if NW_GTPV2C_ULP_API_FLAG_CREATE_LOCAL_TUNNEL is set to flags. */
|
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel; /**< Required only if NW_GTPV2C_ULP_API_FLAG_CREATE_LOCAL_TUNNEL is set to flags. */
|
||||||
|
|
||||||
NW_OUT NwGtpv2cTunnelHandleT hTunnel; /**< Returned only in case flags is set to
|
NW_OUT NwGtpv2cTunnelHandleT hTunnel; /**< Returned only in case flags is set to
|
||||||
NW_GTPV2C_ULP_API_FLAG_CREATE_LOCAL_TUNNEL */
|
NW_GTPV2C_ULP_API_FLAG_CREATE_LOCAL_TUNNEL */
|
||||||
} NwGtpv2cTriggeredRspInfoT;
|
} NwGtpv2cTriggeredRspInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv2c initial message.
|
* sending a Gtpv2c initial message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv2cErrorT error;
|
NW_IN NwGtpv2cErrorT error;
|
||||||
NW_IN NwGtpv2cTrxnHandleT hTrxn;
|
NW_IN NwGtpv2cTrxnHandleT hTrxn;
|
||||||
NW_IN NwGtpv2cUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv2cUlpTrxnHandleT hUlpTrxn;
|
||||||
@@ -250,13 +243,12 @@ typedef struct
|
|||||||
NW_INOUT NwGtpv2cTunnelHandleT hTunnel;
|
NW_INOUT NwGtpv2cTunnelHandleT hTunnel;
|
||||||
} NwGtpv2cInitialReqIndInfoT;
|
} NwGtpv2cInitialReqIndInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv2c triggered request message.
|
* sending a Gtpv2c triggered request message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv2cErrorT error;
|
NW_IN NwGtpv2cErrorT error;
|
||||||
NW_IN NwGtpv2cTrxnHandleT hTrxn;
|
NW_IN NwGtpv2cTrxnHandleT hTrxn;
|
||||||
NW_IN NwGtpv2cUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv2cUlpTrxnHandleT hUlpTrxn;
|
||||||
@@ -267,37 +259,34 @@ typedef struct
|
|||||||
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
||||||
} NwGtpv2cTriggeredReqIndInfoT;
|
} NwGtpv2cTriggeredReqIndInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* sending a Gtpv2c triggered response message.
|
* sending a Gtpv2c triggered response message.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv2cErrorT error;
|
NW_IN NwGtpv2cErrorT error;
|
||||||
NW_IN NwGtpv2cUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv2cUlpTrxnHandleT hUlpTrxn;
|
||||||
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
||||||
NW_IN NwGtpv2cMsgTypeT msgType;
|
NW_IN NwGtpv2cMsgTypeT msgType;
|
||||||
} NwGtpv2cTriggeredRspIndInfoT;
|
} NwGtpv2cTriggeredRspIndInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* receving a path failure indication from stack.
|
* receving a path failure indication from stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv2cUlpTrxnHandleT hUlpTrxn;
|
NW_IN NwGtpv2cUlpTrxnHandleT hUlpTrxn;
|
||||||
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
||||||
} NwGtpv2cRspFailureIndInfoT;
|
} NwGtpv2cRspFailureIndInfoT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* creating local tunnel.
|
* creating local tunnel.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_OUT NwGtpv2cTunnelHandleT hTunnel;
|
NW_OUT NwGtpv2cTunnelHandleT hTunnel;
|
||||||
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
NW_IN NwGtpv2cUlpTunnelHandleT hUlpTunnel;
|
||||||
NW_IN NwU32T teidLocal;
|
NW_IN NwU32T teidLocal;
|
||||||
@@ -305,27 +294,24 @@ typedef struct
|
|||||||
} NwGtpv2cCreateLocalTunnelInfoT;
|
} NwGtpv2cCreateLocalTunnelInfoT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API information elements between ULP and Stack for
|
* API information elements between ULP and Stack for
|
||||||
* deleting a local tunnel.
|
* deleting a local tunnel.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NW_IN NwGtpv2cTunnelHandleT hTunnel;
|
NW_IN NwGtpv2cTunnelHandleT hTunnel;
|
||||||
} NwGtpv2cDeleteLocalTunnelInfoT;
|
} NwGtpv2cDeleteLocalTunnelInfoT;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API container structure between ULP and Stack.
|
* API container structure between ULP and Stack.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv2cUlpApiTypeT apiType; /**< First bytes of this field is used as flag holder */
|
NwGtpv2cUlpApiTypeT apiType; /**< First bytes of this field is used as flag holder */
|
||||||
NwGtpv2cMsgHandleT hMsg; /**< Handle associated with this API */
|
NwGtpv2cMsgHandleT hMsg; /**< Handle associated with this API */
|
||||||
union
|
union {
|
||||||
{
|
|
||||||
NwGtpv2cInitialReqInfoT initialReqInfo;
|
NwGtpv2cInitialReqInfoT initialReqInfo;
|
||||||
NwGtpv2cTriggeredRspInfoT triggeredRspInfo;
|
NwGtpv2cTriggeredRspInfoT triggeredRspInfo;
|
||||||
NwGtpv2cTriggeredReqInfoT triggeredReqInfo;
|
NwGtpv2cTriggeredReqInfoT triggeredReqInfo;
|
||||||
@@ -347,10 +333,9 @@ typedef struct
|
|||||||
* Gtpv2c ULP entity definition
|
* Gtpv2c ULP entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv2cUlpHandleT hUlp;
|
NwGtpv2cUlpHandleT hUlp;
|
||||||
NwRcT (*ulpReqCallback) ( NW_IN NwGtpv2cUlpHandleT hUlp,
|
NwRcT (*ulpReqCallback) ( NW_IN NwGtpv2cUlpHandleT hUlp,
|
||||||
NW_IN NwGtpv2cUlpApiT *pUlpApi);
|
NW_IN NwGtpv2cUlpApiT *pUlpApi);
|
||||||
} NwGtpv2cUlpEntityT;
|
} NwGtpv2cUlpEntityT;
|
||||||
|
|
||||||
@@ -359,11 +344,10 @@ typedef struct
|
|||||||
* Gtpv2c UDP entity definition
|
* Gtpv2c UDP entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv2cUdpHandleT hUdp;
|
NwGtpv2cUdpHandleT hUdp;
|
||||||
NwRcT (*udpDataReqCallback) ( NW_IN NwGtpv2cUdpHandleT udpHandle,
|
NwRcT (*udpDataReqCallback) ( NW_IN NwGtpv2cUdpHandleT udpHandle,
|
||||||
NW_IN NwU8T* dataBuf,
|
NW_IN NwU8T* dataBuf,
|
||||||
NW_IN NwU32T dataSize,
|
NW_IN NwU32T dataSize,
|
||||||
NW_IN NwU32T peerIp,
|
NW_IN NwU32T peerIp,
|
||||||
NW_IN NwU32T peerPort);
|
NW_IN NwU32T peerPort);
|
||||||
@@ -373,15 +357,14 @@ typedef struct
|
|||||||
* Gtpv2c Memory Manager entity definition
|
* Gtpv2c Memory Manager entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv2cMemMgrHandleT hMemMgr;
|
NwGtpv2cMemMgrHandleT hMemMgr;
|
||||||
void* (*memAlloc)( NW_IN NwGtpv2cMemMgrHandleT hMemMgr,
|
void* (*memAlloc)( NW_IN NwGtpv2cMemMgrHandleT hMemMgr,
|
||||||
NW_IN NwU32T memSize,
|
NW_IN NwU32T memSize,
|
||||||
NW_IN NwCharT* fileName,
|
NW_IN NwCharT* fileName,
|
||||||
NW_IN NwU32T lineNumber);
|
NW_IN NwU32T lineNumber);
|
||||||
|
|
||||||
void (*memFree) ( NW_IN NwGtpv2cMemMgrHandleT hMemMgr,
|
void (*memFree) ( NW_IN NwGtpv2cMemMgrHandleT hMemMgr,
|
||||||
NW_IN void* hMem,
|
NW_IN void* hMem,
|
||||||
NW_IN NwCharT* fileName,
|
NW_IN NwCharT* fileName,
|
||||||
NW_IN NwU32T lineNumber);
|
NW_IN NwU32T lineNumber);
|
||||||
@@ -394,17 +377,16 @@ typedef struct
|
|||||||
* Gtpv2c Timer Manager entity definition
|
* Gtpv2c Timer Manager entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv2cTimerMgrHandleT tmrMgrHandle;
|
NwGtpv2cTimerMgrHandleT tmrMgrHandle;
|
||||||
NwRcT (*tmrStartCallback)( NW_IN NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
NwRcT (*tmrStartCallback)( NW_IN NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
||||||
NW_IN NwU32T timeoutSec,
|
NW_IN NwU32T timeoutSec,
|
||||||
NW_IN NwU32T timeoutUsec,
|
NW_IN NwU32T timeoutUsec,
|
||||||
NW_IN NwU32T tmrType,
|
NW_IN NwU32T tmrType,
|
||||||
NW_IN void* tmrArg,
|
NW_IN void* tmrArg,
|
||||||
NW_OUT NwGtpv2cTimerHandleT* tmrHandle);
|
NW_OUT NwGtpv2cTimerHandleT* tmrHandle);
|
||||||
|
|
||||||
NwRcT (*tmrStopCallback) ( NW_IN NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
NwRcT (*tmrStopCallback) ( NW_IN NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
||||||
NW_IN NwGtpv2cTimerHandleT tmrHandle);
|
NW_IN NwGtpv2cTimerHandleT tmrHandle);
|
||||||
} NwGtpv2cTimerMgrEntityT;
|
} NwGtpv2cTimerMgrEntityT;
|
||||||
|
|
||||||
@@ -412,10 +394,9 @@ typedef struct
|
|||||||
* Gtpv2c Log manager entity definition
|
* Gtpv2c Log manager entity definition
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwGtpv2cLogMgrHandleT logMgrHandle;
|
NwGtpv2cLogMgrHandleT logMgrHandle;
|
||||||
NwRcT (*logReqCallback) (NW_IN NwGtpv2cLogMgrHandleT logMgrHandle,
|
NwRcT (*logReqCallback) (NW_IN NwGtpv2cLogMgrHandleT logMgrHandle,
|
||||||
NW_IN NwU32T logLevel,
|
NW_IN NwU32T logLevel,
|
||||||
NW_IN NwCharT* filename,
|
NW_IN NwCharT* filename,
|
||||||
NW_IN NwU32T line,
|
NW_IN NwU32T line,
|
||||||
@@ -430,8 +411,8 @@ typedef struct
|
|||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Constructor. Initialize nw-gtpv2c stack instance.
|
Constructor. Initialize nw-gtpv2c stack instance.
|
||||||
|
|
||||||
@param[in,out] phGtpcStackHandle : Pointer to stack instance handle
|
@param[in,out] phGtpcStackHandle : Pointer to stack instance handle
|
||||||
@@ -440,7 +421,7 @@ extern "C" {
|
|||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cInitialize( NW_INOUT NwGtpv2cStackHandleT* phGtpcStackHandle);
|
nwGtpv2cInitialize( NW_INOUT NwGtpv2cStackHandleT* phGtpcStackHandle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Destructor. Destroy nw-gtpv2c stack instance .
|
Destructor. Destroy nw-gtpv2c stack instance .
|
||||||
|
|
||||||
@param[in] hGtpcStackHandle : Stack instance handle
|
@param[in] hGtpcStackHandle : Stack instance handle
|
||||||
@@ -449,7 +430,7 @@ nwGtpv2cInitialize( NW_INOUT NwGtpv2cStackHandleT* phGtpcStackHandle);
|
|||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cFinalize( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle);
|
nwGtpv2cFinalize( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set Configuration for the nw-gtpv2c stack.
|
Set Configuration for the nw-gtpv2c stack.
|
||||||
|
|
||||||
@param[in,out] phGtpcStackHandle : Pointer to stack handle
|
@param[in,out] phGtpcStackHandle : Pointer to stack handle
|
||||||
@@ -458,7 +439,7 @@ nwGtpv2cFinalize( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle);
|
|||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cConfigSet( NW_IN NwGtpv2cStackHandleT* phGtpcStackHandle, NW_IN NwGtpv2cStackConfigT* pConfig);
|
nwGtpv2cConfigSet( NW_IN NwGtpv2cStackHandleT* phGtpcStackHandle, NW_IN NwGtpv2cStackConfigT* pConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Get Configuration for the nw-gtpv2c stack.
|
Get Configuration for the nw-gtpv2c stack.
|
||||||
|
|
||||||
@param[in,out] phGtpcStackHandle : Pointer to stack handle
|
@param[in,out] phGtpcStackHandle : Pointer to stack handle
|
||||||
@@ -467,7 +448,7 @@ nwGtpv2cConfigSet( NW_IN NwGtpv2cStackHandleT* phGtpcStackHandle, NW_IN NwGtpv2c
|
|||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cConfigGet( NW_IN NwGtpv2cStackHandleT* phGtpcStackHandle, NW_OUT NwGtpv2cStackConfigT* pConfig);
|
nwGtpv2cConfigGet( NW_IN NwGtpv2cStackHandleT* phGtpcStackHandle, NW_OUT NwGtpv2cStackConfigT* pConfig);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set ULP entity for the stack.
|
Set ULP entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpcStackHandle : Stack handle
|
@param[in] hGtpcStackHandle : Stack handle
|
||||||
@@ -477,9 +458,9 @@ nwGtpv2cConfigGet( NW_IN NwGtpv2cStackHandleT* phGtpcStackHandle, NW_OUT NwGtpv2
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cSetUlpEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cSetUlpEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cUlpEntityT* pUlpEntity);
|
NW_IN NwGtpv2cUlpEntityT* pUlpEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set UDP entity for the stack.
|
Set UDP entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpcStackHandle : Stack handle
|
@param[in] hGtpcStackHandle : Stack handle
|
||||||
@@ -489,9 +470,9 @@ nwGtpv2cSetUlpEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cSetUdpEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cSetUdpEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cUdpEntityT* pUdpEntity);
|
NW_IN NwGtpv2cUdpEntityT* pUdpEntity);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set MemMgr entity for the stack.
|
Set MemMgr entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpcStackHandle : Stack handle
|
@param[in] hGtpcStackHandle : Stack handle
|
||||||
@@ -501,10 +482,10 @@ nwGtpv2cSetUdpEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cSetMemMgrEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cSetMemMgrEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cMemMgrEntityT* pMemMgr);
|
NW_IN NwGtpv2cMemMgrEntityT* pMemMgr);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set TmrMgr entity for the stack.
|
Set TmrMgr entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpcStackHandle : Stack handle
|
@param[in] hGtpcStackHandle : Stack handle
|
||||||
@@ -514,9 +495,9 @@ nwGtpv2cSetMemMgrEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cSetTimerMgrEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cSetTimerMgrEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cTimerMgrEntityT* pTmrMgr);
|
NW_IN NwGtpv2cTimerMgrEntityT* pTmrMgr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set LogMgr entity for the stack.
|
Set LogMgr entity for the stack.
|
||||||
|
|
||||||
@param[in] hGtpcStackHandle : Stack handle
|
@param[in] hGtpcStackHandle : Stack handle
|
||||||
@@ -526,9 +507,9 @@ nwGtpv2cSetTimerMgrEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cSetLogMgrEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cSetLogMgrEntity( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cLogMgrEntityT* pLogMgr);
|
NW_IN NwGtpv2cLogMgrEntityT* pLogMgr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Set log level for the stack.
|
Set log level for the stack.
|
||||||
|
|
||||||
@param[in] hGtpcStackHandle : Stack handle
|
@param[in] hGtpcStackHandle : Stack handle
|
||||||
@@ -552,12 +533,12 @@ nwGtpv2cSetLogLevel( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
@return NW_OK on success.
|
@return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cProcessUdpReq( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cProcessUdpReq( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwU8T* udpData,
|
NW_IN NwU8T* udpData,
|
||||||
NW_IN NwU32T udpDataLen,
|
NW_IN NwU32T udpDataLen,
|
||||||
NW_IN NwU16T peerPort,
|
NW_IN NwU16T peerPort,
|
||||||
NW_IN NwU32T peerIP);
|
NW_IN NwU32T peerIP);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Process Request from ULP entity.
|
Process Request from ULP entity.
|
||||||
@@ -569,7 +550,7 @@ nwGtpv2cProcessUdpReq( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cProcessUlpReq( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cProcessUlpReq( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cUlpApiT *ulpReq);
|
NW_IN NwGtpv2cUlpApiT *ulpReq);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. *
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv2cIe.h
|
* @file NwGtpv2cIe.h
|
||||||
* @brief This header file contains Information Element definitions for GTPv2c
|
* @brief This header file contains Information Element definitions for GTPv2c
|
||||||
* as per 3GPP TS 29274-930.
|
* as per 3GPP TS 29274-930.
|
||||||
@@ -130,14 +130,14 @@
|
|||||||
* G T P V 2 C C A U S E V A L U E D E F I N I T I O N S *
|
* G T P V 2 C C A U S E V A L U E D E F I N I T I O N S *
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
#define NW_GTPV2C_CAUSE_REQUEST_ACCEPTED (16)
|
#define NW_GTPV2C_CAUSE_REQUEST_ACCEPTED (16)
|
||||||
#define NW_GTPV2C_CAUSE_INVALID_LENGTH (67)
|
#define NW_GTPV2C_CAUSE_INVALID_LENGTH (67)
|
||||||
#define NW_GTPV2C_CAUSE_MANDATORY_IE_INCORRECT (69)
|
#define NW_GTPV2C_CAUSE_MANDATORY_IE_INCORRECT (69)
|
||||||
#define NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING (70)
|
#define NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING (70)
|
||||||
#define NW_GTPV2C_CAUSE_SYSTEM_FAILURE (72)
|
#define NW_GTPV2C_CAUSE_SYSTEM_FAILURE (72)
|
||||||
#define NW_GTPV2C_CAUSE_REQUEST_REJECTED (94)
|
#define NW_GTPV2C_CAUSE_REQUEST_REJECTED (94)
|
||||||
#define NW_GTPV2C_CAUSE_REMOTE_PEER_NOT_RESPONDING (100)
|
#define NW_GTPV2C_CAUSE_REMOTE_PEER_NOT_RESPONDING (100)
|
||||||
#define NW_GTPV2C_CAUSE_CONDITIONAL_IE_MISSING (103)
|
#define NW_GTPV2C_CAUSE_CONDITIONAL_IE_MISSING (103)
|
||||||
|
|
||||||
#define NW_GTPV2C_IE_INSTANCE_ZERO (0)
|
#define NW_GTPV2C_IE_INSTANCE_ZERO (0)
|
||||||
#define NW_GTPV2C_IE_INSTANCE_ONE (1)
|
#define NW_GTPV2C_IE_INSTANCE_ONE (1)
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
#include "NwTypes.h"
|
#include "NwTypes.h"
|
||||||
#include "NwGtpv2c.h"
|
#include "NwGtpv2c.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv2cMsg.h
|
* @file NwGtpv2cMsg.h
|
||||||
* @brief This file defines APIs for to build new outgoing gtpv2c messages and to parse incoming messages.
|
* @brief This file defines APIs for to build new outgoing gtpv2c messages and to parse incoming messages.
|
||||||
*/
|
*/
|
||||||
@@ -185,40 +185,35 @@ extern "C" {
|
|||||||
|
|
||||||
#pragma pack(1)
|
#pragma pack(1)
|
||||||
|
|
||||||
typedef struct NwGtpv2cIeTv1
|
typedef struct NwGtpv2cIeTv1 {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU16T l;
|
NwU16T l;
|
||||||
NwU8T i;
|
NwU8T i;
|
||||||
NwU8T v;
|
NwU8T v;
|
||||||
} NwGtpv2cIeTv1T;
|
} NwGtpv2cIeTv1T;
|
||||||
|
|
||||||
typedef struct NwGtpv2cIeTv2
|
typedef struct NwGtpv2cIeTv2 {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU16T l;
|
NwU16T l;
|
||||||
NwU8T i;
|
NwU8T i;
|
||||||
NwU16T v;
|
NwU16T v;
|
||||||
} NwGtpv2cIeTv2T;
|
} NwGtpv2cIeTv2T;
|
||||||
|
|
||||||
typedef struct NwGtpv2cIeTv4
|
typedef struct NwGtpv2cIeTv4 {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU16T l;
|
NwU16T l;
|
||||||
NwU8T i;
|
NwU8T i;
|
||||||
NwU32T v;
|
NwU32T v;
|
||||||
} NwGtpv2cIeTv4T;
|
} NwGtpv2cIeTv4T;
|
||||||
|
|
||||||
typedef struct NwGtpv2cIeTv8
|
typedef struct NwGtpv2cIeTv8 {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU16T l;
|
NwU16T l;
|
||||||
NwU8T i;
|
NwU8T i;
|
||||||
NwU64T v;
|
NwU64T v;
|
||||||
} NwGtpv2cIeTv8T;
|
} NwGtpv2cIeTv8T;
|
||||||
|
|
||||||
typedef struct NwGtpv2cIeTlv
|
typedef struct NwGtpv2cIeTlv {
|
||||||
{
|
|
||||||
NwU8T t;
|
NwU8T t;
|
||||||
NwU16T l;
|
NwU16T l;
|
||||||
NwU8T i;
|
NwU8T i;
|
||||||
@@ -227,16 +222,16 @@ typedef struct NwGtpv2cIeTlv
|
|||||||
#pragma pack()
|
#pragma pack()
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a gtpv2c message.
|
* Allocate a gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
||||||
* @param[in] teidPresent : TEID is present flag.
|
* @param[in] teidPresent : TEID is present flag.
|
||||||
* @param[in] msgType : Message type for this message.
|
* @param[in] msgType : Message type for this message.
|
||||||
* @param[in] teid : TEID for this message.
|
* @param[in] teid : TEID for this message.
|
||||||
* @param[in] seqNum : Sequence number for this message.
|
* @param[in] seqNum : Sequence number for this message.
|
||||||
* @param[out] phMsg : Pointer to message handle.
|
* @param[out] phMsg : Pointer to message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cMsgNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
@@ -247,363 +242,363 @@ nwGtpv2cMsgNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
NW_OUT NwGtpv2cMsgHandleT *phMsg);
|
NW_OUT NwGtpv2cMsgHandleT *phMsg);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a gtpv2c message from data buffer.
|
* Allocate a gtpv2c message from data buffer.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
||||||
* @param[in] pBuf: Buffer to be copied in this message.
|
* @param[in] pBuf: Buffer to be copied in this message.
|
||||||
* @param[in] bufLen: Buffer length to be copied in this message.
|
* @param[in] bufLen: Buffer length to be copied in this message.
|
||||||
* @param[out] phMsg : Pointer to message handle.
|
* @param[out] phMsg : Pointer to message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgFromBufferNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cMsgFromBufferNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwU8T* pBuf,
|
NW_IN NwU8T* pBuf,
|
||||||
NW_IN NwU32T bufLen,
|
NW_IN NwU32T bufLen,
|
||||||
NW_OUT NwGtpv2cMsgHandleT *phMsg);
|
NW_OUT NwGtpv2cMsgHandleT *phMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a gtpv2c message.
|
* Free a gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgDelete( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cMsgDelete( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cMsgHandleT hMsg);
|
NW_IN NwGtpv2cMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set TEID for gtpv2c message.
|
* Set TEID for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] teid: TEID value.
|
* @param[in] teid: TEID value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgSetTeid(NW_IN NwGtpv2cMsgHandleT hMsg, NwU32T teid);
|
nwGtpv2cMsgSetTeid(NW_IN NwGtpv2cMsgHandleT hMsg, NwU32T teid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set TEID present flag for gtpv2c message.
|
* Set TEID present flag for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] teidPesent: Flag boolean value.
|
* @param[in] teidPesent: Flag boolean value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgSetTeidPresent(NW_IN NwGtpv2cMsgHandleT hMsg, NwBoolT teidPresent);
|
nwGtpv2cMsgSetTeidPresent(NW_IN NwGtpv2cMsgHandleT hMsg, NwBoolT teidPresent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set sequence for gtpv2c message.
|
* Set sequence for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] seqNum: Flag boolean value.
|
* @param[in] seqNum: Flag boolean value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgSetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg, NwU32T seqNum);
|
nwGtpv2cMsgSetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg, NwU32T seqNum);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get TEID present for gtpv2c message.
|
* Get TEID present for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv2cMsgGetTeid(NW_IN NwGtpv2cMsgHandleT hMsg);
|
nwGtpv2cMsgGetTeid(NW_IN NwGtpv2cMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get TEID present for gtpv2c message.
|
* Get TEID present for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwBoolT
|
NwBoolT
|
||||||
nwGtpv2cMsgGetTeidPresent(NW_IN NwGtpv2cMsgHandleT hMsg);
|
nwGtpv2cMsgGetTeidPresent(NW_IN NwGtpv2cMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get sequence number for gtpv2c message.
|
* Get sequence number for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv2cMsgGetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg);
|
nwGtpv2cMsgGetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get msg lenght for gtpv2c message.
|
* Get msg lenght for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv2cMsgGetLength(NW_IN NwGtpv2cMsgHandleT hMsg);
|
nwGtpv2cMsgGetLength(NW_IN NwGtpv2cMsgHandleT hMsg);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a gtpv2c information element of length 1 to gtpv2c message.
|
* Add a gtpv2c information element of length 1 to gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] type : IE type.
|
* @param[in] type : IE type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[in] value : IE value.
|
* @param[in] value : IE value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU8T value);
|
NW_IN NwU8T value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a gtpv2c information element of length 2 to gtpv2c message.
|
* Add a gtpv2c information element of length 2 to gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] type : IE type.
|
* @param[in] type : IE type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[in] value : IE value.
|
* @param[in] value : IE value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeTV2(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeTV2(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU16T value);
|
NW_IN NwU16T value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a gtpv2c information element of length 4 to gtpv2c message.
|
* Add a gtpv2c information element of length 4 to gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] type : IE type.
|
* @param[in] type : IE type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[in] value : IE value.
|
* @param[in] value : IE value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeTV4(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeTV4(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU32T value);
|
NW_IN NwU32T value);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a gtpv2c information element of variable length to gtpv2c message.
|
* Add a gtpv2c information element of variable length to gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] type : IE type.
|
* @param[in] type : IE type.
|
||||||
* @param[in] length : IE length.
|
* @param[in] length : IE length.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[in] value : IE value.
|
* @param[in] value : IE value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIe(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIe(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU16T length,
|
NW_IN NwU16T length,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU8T* pVal);
|
NW_IN NwU8T* pVal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add CAUSE information element to gtpv2c message.
|
* Add CAUSE information element to gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[in] causeValue: Cause value.
|
* @param[in] causeValue: Cause value.
|
||||||
* @param[in] bitFlags: PDN Connetiion IE Error Flag, Bearer Context IE Error Flag, Cause Source Flag.
|
* @param[in] bitFlags: PDN Connetiion IE Error Flag, Bearer Context IE Error Flag, Cause Source Flag.
|
||||||
* @param[in] offendingIeType: Offending IE type.
|
* @param[in] offendingIeType: Offending IE type.
|
||||||
* @param[in] offendingIeInstance: Offending IE instance.
|
* @param[in] offendingIeInstance: Offending IE instance.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU8T causeValue,
|
NW_IN NwU8T causeValue,
|
||||||
NW_IN NwU8T bitFlags,
|
NW_IN NwU8T bitFlags,
|
||||||
NW_IN NwU8T offendingIeType,
|
NW_IN NwU8T offendingIeType,
|
||||||
NW_IN NwU8T offendingIeInstance);
|
NW_IN NwU8T offendingIeInstance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add F-TEID information element to gtpv2c message.
|
* Add F-TEID information element to gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[in] ifType : Interface Type.
|
* @param[in] ifType : Interface Type.
|
||||||
* @param[in] teidOrGreKey: TEID/ GRE Key
|
* @param[in] teidOrGreKey: TEID/ GRE Key
|
||||||
* @param[in] ipv4Addr : Ipv4 Address in Network Byte Order.
|
* @param[in] ipv4Addr : Ipv4 Address in Network Byte Order.
|
||||||
* @param[in] pIpv6Addr: Pointer to IPv6 Address in Network Byte Order.
|
* @param[in] pIpv6Addr: Pointer to IPv6 Address in Network Byte Order.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU8T ifType,
|
NW_IN NwU8T ifType,
|
||||||
NW_IN NwU32T teidOrGreKey,
|
NW_IN NwU32T teidOrGreKey,
|
||||||
NW_IN NwU32T ipv4Addr,
|
NW_IN NwU32T ipv4Addr,
|
||||||
NW_IN NwU8T* pIpv6Addr);
|
NW_IN NwU8T* pIpv6Addr);
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGroupedIeStart(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGroupedIeStart(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance);
|
NW_IN NwU8T instance);
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGroupedIeEnd(NW_IN NwGtpv2cMsgHandleT hMsg);
|
nwGtpv2cMsgGroupedIeEnd(NW_IN NwGtpv2cMsgHandleT hMsg);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if information element of type and instance is present
|
* Check if information element of type and instance is present
|
||||||
* in gtpv2c message.
|
* in gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] type : IE Type.
|
* @param[in] type : IE Type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @return NW_TRUE on success, NW_FALSE on failure.
|
* @return NW_TRUE on success, NW_FALSE on failure.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwBoolT
|
NwBoolT
|
||||||
nwGtpv2cMsgIsIePresent(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgIsIePresent(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance);
|
NW_IN NwU8T instance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an information element of type 'NwU8T' from gtpv2c message.
|
* Get an information element of type 'NwU8T' from gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] type : IE Type.
|
* @param[in] type : IE Type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[out] pVal : Pointer to value buffer.
|
* @param[out] pVal : Pointer to value buffer.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU8T* pVal);
|
NW_OUT NwU8T* pVal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an information element of type 'NwU16T' from gtpv2c message.
|
* Get an information element of type 'NwU16T' from gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] tyep : IE Type.
|
* @param[in] tyep : IE Type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[out] pVal : Pointer to value buffer.
|
* @param[out] pVal : Pointer to value buffer.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTV2(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTV2(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU16T* pVal);
|
NW_OUT NwU16T* pVal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an information element of type 'NwU32T' from gtpv2c message.
|
* Get an information element of type 'NwU32T' from gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] tyep : IE Type.
|
* @param[in] tyep : IE Type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[out] pVal : Pointer to value buffer.
|
* @param[out] pVal : Pointer to value buffer.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTV4(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTV4(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU32T* pVal);
|
NW_OUT NwU32T* pVal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an information element of type 'NwU64T' from gtpv2c message.
|
* Get an information element of type 'NwU64T' from gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] tyep : IE Type.
|
* @param[in] tyep : IE Type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[out] pVal : Pointer to IE value buffer.
|
* @param[out] pVal : Pointer to IE value buffer.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTV8(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTV8(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU64T* pVal);
|
NW_OUT NwU64T* pVal);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an information element of variable length from gtpv2c message.
|
* Get an information element of variable length from gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] tyep : IE Type.
|
* @param[in] tyep : IE Type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[in] maxLen : Maximum length of IE.
|
* @param[in] maxLen : Maximum length of IE.
|
||||||
* @param[out] pVal : Pointer to IE value buffer.
|
* @param[out] pVal : Pointer to IE value buffer.
|
||||||
* @param[out] pLen : Pointer to IE length buffer.
|
* @param[out] pLen : Pointer to IE length buffer.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTlv(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTlv(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU16T maxLen,
|
NW_IN NwU16T maxLen,
|
||||||
NW_OUT NwU8T* pVal,
|
NW_OUT NwU8T* pVal,
|
||||||
NW_OUT NwU16T* pLen);
|
NW_OUT NwU16T* pLen);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an information element of variable length from gtpv2c message.
|
* Get an information element of variable length from gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] tyep : IE Type.
|
* @param[in] tyep : IE Type.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[out] ppVal : Pointer to IE value buffer pointer.
|
* @param[out] ppVal : Pointer to IE value buffer pointer.
|
||||||
* @param[out] pLen : Pointer to IE length buffer.
|
* @param[out] pLen : Pointer to IE length buffer.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTlvP(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTlvP(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU8T** ppVal,
|
NW_OUT NwU8T** ppVal,
|
||||||
NW_OUT NwU16T* pLen);
|
NW_OUT NwU16T* pLen);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get F-TEID information element to gtpv2c message.
|
* Get F-TEID information element to gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Handle to gtpv2c message.
|
* @param[in] hMsg : Handle to gtpv2c message.
|
||||||
* @param[in] instance : IE instance.
|
* @param[in] instance : IE instance.
|
||||||
* @param[out] ifType : Interface Type.
|
* @param[out] ifType : Interface Type.
|
||||||
* @param[out] teidOrGreKey: TEID/ GRE Key
|
* @param[out] teidOrGreKey: TEID/ GRE Key
|
||||||
* @param[out] ipv4Addr : Ipv4 Address in Network Byte Order.
|
* @param[out] ipv4Addr : Ipv4 Address in Network Byte Order.
|
||||||
* @param[out] pIpv6Addr: Pointer to IPv6 Address in Network Byte Order.
|
* @param[out] pIpv6Addr: Pointer to IPv6 Address in Network Byte Order.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU8T* ifType,
|
NW_OUT NwU8T* ifType,
|
||||||
NW_OUT NwU32T* teidOrGreKey,
|
NW_OUT NwU32T* teidOrGreKey,
|
||||||
NW_OUT NwU32T* ipv4Addr,
|
NW_OUT NwU32T* ipv4Addr,
|
||||||
NW_OUT NwU8T* pIpv6Addr);
|
NW_OUT NwU8T* pIpv6Addr);
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU8T* causeValue,
|
NW_OUT NwU8T* causeValue,
|
||||||
NW_OUT NwU8T* flags,
|
NW_OUT NwU8T* flags,
|
||||||
NW_OUT NwU8T* offendingIeType,
|
NW_OUT NwU8T* offendingIeType,
|
||||||
NW_OUT NwU8T* offendingIeInstance);
|
NW_OUT NwU8T* offendingIeInstance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get msg type for gtpv2c message.
|
* Get msg type for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv2cMsgGetMsgType(NW_IN NwGtpv2cMsgHandleT hMsg);
|
nwGtpv2cMsgGetMsgType(NW_IN NwGtpv2cMsgHandleT hMsg);
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -39,13 +39,12 @@
|
|||||||
#ifndef __NW_GTPV2C_MSG_PARSER_H__
|
#ifndef __NW_GTPV2C_MSG_PARSER_H__
|
||||||
#define __NW_GTPV2C_MSG_PARSER_H__
|
#define __NW_GTPV2C_MSG_PARSER_H__
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwGtpv2cMsgParser.h
|
* @file NwGtpv2cMsgParser.h
|
||||||
* @brief This file defines APIs to parser gtpv2c messages.
|
* @brief This file defines APIs to parser gtpv2c messages.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwU16T msgType;
|
NwU16T msgType;
|
||||||
NwU16T mandatoryIeCount;
|
NwU16T mandatoryIeCount;
|
||||||
NwGtpv2cStackHandleT hStack;
|
NwGtpv2cStackHandleT hStack;
|
||||||
@@ -65,73 +64,73 @@ typedef struct
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a gtpv2c message Parser.
|
* Allocate a gtpv2c message Parser.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
||||||
* @param[in] msgType : Message type for this message parser.
|
* @param[in] msgType : Message type for this message parser.
|
||||||
* @param[out] pthiz : Pointer to message parser handle.
|
* @param[out] pthiz : Pointer to message parser handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cMsgParserNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwU8T msgType,
|
NW_IN NwU8T msgType,
|
||||||
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
||||||
NwU8T ieLength,
|
NwU8T ieLength,
|
||||||
NwU8T ieInstance,
|
NwU8T ieInstance,
|
||||||
NwU8T* ieValue,
|
NwU8T* ieValue,
|
||||||
void* ieReadCallbackArg),
|
void* ieReadCallbackArg),
|
||||||
NW_IN void* ieReadCallbackArg,
|
NW_IN void* ieReadCallbackArg,
|
||||||
NW_IN NwGtpv2cMsgParserT **pthiz);
|
NW_IN NwGtpv2cMsgParserT **pthiz);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a gtpv2c message parser.
|
* Free a gtpv2c message parser.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
||||||
* @param[in] thiz : Message parser handle.
|
* @param[in] thiz : Message parser handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserDelete( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cMsgParserDelete( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cMsgParserT* thiz);
|
NW_IN NwGtpv2cMsgParserT* thiz);
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserUpdateIe( NW_IN NwGtpv2cMsgParserT* thiz,
|
nwGtpv2cMsgParserUpdateIe( NW_IN NwGtpv2cMsgParserT* thiz,
|
||||||
NW_IN NwU8T ieType,
|
NW_IN NwU8T ieType,
|
||||||
NW_IN NwU8T ieInstance,
|
NW_IN NwU8T ieInstance,
|
||||||
NW_IN NwU8T iePresence,
|
NW_IN NwU8T iePresence,
|
||||||
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
||||||
NwU8T ieLength,
|
NwU8T ieLength,
|
||||||
NwU8T ieInstance,
|
NwU8T ieInstance,
|
||||||
NwU8T* ieValue,
|
NwU8T* ieValue,
|
||||||
void* ieReadCallbackArg),
|
void* ieReadCallbackArg),
|
||||||
NW_IN void* ieReadCallbackArg);
|
NW_IN void* ieReadCallbackArg);
|
||||||
|
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserUpdateIeReadCallback( NW_IN NwGtpv2cMsgParserT* thiz,
|
nwGtpv2cMsgParserUpdateIeReadCallback( NW_IN NwGtpv2cMsgParserT* thiz,
|
||||||
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
||||||
NwU8T ieLength,
|
NwU8T ieLength,
|
||||||
NwU8T ieInstance,
|
NwU8T ieInstance,
|
||||||
NwU8T* ieValue,
|
NwU8T* ieValue,
|
||||||
void* ieReadCallbackArg));
|
void* ieReadCallbackArg));
|
||||||
|
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserUpdateIeReadCallbackArg( NW_IN NwGtpv2cMsgParserT* thiz,
|
nwGtpv2cMsgParserUpdateIeReadCallbackArg( NW_IN NwGtpv2cMsgParserT* thiz,
|
||||||
NW_IN void* ieReadCallbackArg);
|
NW_IN void* ieReadCallbackArg);
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserAddIe( NW_IN NwGtpv2cMsgParserT* thiz,
|
nwGtpv2cMsgParserAddIe( NW_IN NwGtpv2cMsgParserT* thiz,
|
||||||
NW_IN NwU8T ieType,
|
NW_IN NwU8T ieType,
|
||||||
NW_IN NwU8T ieInstance,
|
NW_IN NwU8T ieInstance,
|
||||||
NW_IN NwU8T iePresence,
|
NW_IN NwU8T iePresence,
|
||||||
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
||||||
NwU8T ieLength,
|
NwU8T ieLength,
|
||||||
NwU8T ieInstance,
|
NwU8T ieInstance,
|
||||||
NwU8T* ieValue,
|
NwU8T* ieValue,
|
||||||
void* ieReadCallbackArg),
|
void* ieReadCallbackArg),
|
||||||
NW_IN void* ieReadCallbackArg);
|
NW_IN void* ieReadCallbackArg);
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -39,8 +39,8 @@
|
|||||||
|
|
||||||
#include "NwTypes.h"
|
#include "NwTypes.h"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwLog.h
|
* @file NwLog.h
|
||||||
* @brief This header file contains global shared logging definitions.
|
* @brief This header file contains global shared logging definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ extern "C" {
|
|||||||
#define NW_LOG_LEVEL_ALER (1) /**< action must be taken immediately*/
|
#define NW_LOG_LEVEL_ALER (1) /**< action must be taken immediately*/
|
||||||
#define NW_LOG_LEVEL_CRIT (2) /**< critical conditions */
|
#define NW_LOG_LEVEL_CRIT (2) /**< critical conditions */
|
||||||
#define NW_LOG_LEVEL_ERRO (3) /**< error conditions */
|
#define NW_LOG_LEVEL_ERRO (3) /**< error conditions */
|
||||||
#define NW_LOG_LEVEL_WARN (4) /**< warning conditions */
|
#define NW_LOG_LEVEL_WARN (4) /**< warning conditions */
|
||||||
#define NW_LOG_LEVEL_NOTI (5) /**< normal but signification condition */
|
#define NW_LOG_LEVEL_NOTI (5) /**< normal but signification condition */
|
||||||
#define NW_LOG_LEVEL_INFO (6) /**< informational */
|
#define NW_LOG_LEVEL_INFO (6) /**< informational */
|
||||||
#define NW_LOG_LEVEL_DEBG (7) /**< debug-level messages */
|
#define NW_LOG_LEVEL_DEBG (7) /**< debug-level messages */
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
#ifndef __NW_TYPES_H__
|
#ifndef __NW_TYPES_H__
|
||||||
#define __NW_TYPES_H__
|
#define __NW_TYPES_H__
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwTypes.h
|
* @file NwTypes.h
|
||||||
* @brief This header file contains basic type definitions.
|
* @brief This header file contains basic type definitions.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -37,13 +37,13 @@
|
|||||||
#define __NW_UTILS_H__
|
#define __NW_UTILS_H__
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwUtils.h
|
* @file NwUtils.h
|
||||||
* @brief This header file contains utility macro and function definitions.
|
* @brief This header file contains utility macro and function definitions.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define NW_ASSERT assert /**< Assertion */
|
#define NW_ASSERT assert /**< Assertion */
|
||||||
|
|
||||||
#define NW_CHK_NULL_PTR(_ptr) NW_ASSERT(_ptr != NULL) /**< Null pointer check */
|
#define NW_CHK_NULL_PTR(_ptr) NW_ASSERT(_ptr != NULL) /**< Null pointer check */
|
||||||
|
|
||||||
#define NW_HTONS(x) ( ( ((x) & 0xff00) >> 8 ) | ( ((x) & 0x00ff) << 8 ) )
|
#define NW_HTONS(x) ( ( ((x) & 0xff00) >> 8 ) | ( ((x) & 0x00ff) << 8 ) )
|
||||||
@@ -56,7 +56,7 @@
|
|||||||
( ( ((NwU64T)x) & 0x0000ff0000000000ULL ) >> 24 ) | ( ( ((NwU64T)x) & 0x000000ff00000000ULL ) >> 8 ) | \
|
( ( ((NwU64T)x) & 0x0000ff0000000000ULL ) >> 24 ) | ( ( ((NwU64T)x) & 0x000000ff00000000ULL ) >> 8 ) | \
|
||||||
( ( ((NwU64T)x) & 0x000000000000ff00ULL ) << 40 ) | ( ( ((NwU64T)x) & 0x00000000000000ffULL ) << 56 ) | \
|
( ( ((NwU64T)x) & 0x000000000000ff00ULL ) << 40 ) | ( ( ((NwU64T)x) & 0x00000000000000ffULL ) << 56 ) | \
|
||||||
( ( ((NwU64T)x) & 0x0000000000ff0000ULL ) << 24 ) | ( ( ((NwU64T)x) & 0x00000000ff000000ULL ) << 8 ) \
|
( ( ((NwU64T)x) & 0x0000000000ff0000ULL ) << 24 ) | ( ( ((NwU64T)x) & 0x00000000ff000000ULL ) << 8 ) \
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
#define NW_NTOHS NW_HTONS
|
#define NW_NTOHS NW_HTONS
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -73,18 +73,14 @@ nwGtpv2cMsgNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
|
|
||||||
NW_ASSERT(pStack);
|
NW_ASSERT(pStack);
|
||||||
|
|
||||||
if(gpGtpv2cMsgPool)
|
if(gpGtpv2cMsgPool) {
|
||||||
{
|
|
||||||
pMsg = gpGtpv2cMsgPool;
|
pMsg = gpGtpv2cMsgPool;
|
||||||
gpGtpv2cMsgPool = gpGtpv2cMsgPool->next;
|
gpGtpv2cMsgPool = gpGtpv2cMsgPool->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_GTPV2C_MALLOC(pStack, sizeof(NwGtpv2cMsgT), pMsg, NwGtpv2cMsgT*);
|
NW_GTPV2C_MALLOC(pStack, sizeof(NwGtpv2cMsgT), pMsg, NwGtpv2cMsgT*);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pMsg)
|
if(pMsg) {
|
||||||
{
|
|
||||||
pMsg->version = NW_GTP_VERSION;
|
pMsg->version = NW_GTP_VERSION;
|
||||||
pMsg->teidPresent = teidPresent;
|
pMsg->teidPresent = teidPresent;
|
||||||
pMsg->msgType = msgType;
|
pMsg->msgType = msgType;
|
||||||
@@ -105,27 +101,23 @@ nwGtpv2cMsgNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgFromBufferNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cMsgFromBufferNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwU8T* pBuf,
|
NW_IN NwU8T* pBuf,
|
||||||
NW_IN NwU32T bufLen,
|
NW_IN NwU32T bufLen,
|
||||||
NW_OUT NwGtpv2cMsgHandleT *phMsg)
|
NW_OUT NwGtpv2cMsgHandleT *phMsg)
|
||||||
{
|
{
|
||||||
NwGtpv2cStackT* pStack = (NwGtpv2cStackT*) hGtpcStackHandle;
|
NwGtpv2cStackT* pStack = (NwGtpv2cStackT*) hGtpcStackHandle;
|
||||||
NwGtpv2cMsgT *pMsg;
|
NwGtpv2cMsgT *pMsg;
|
||||||
|
|
||||||
NW_ASSERT(pStack);
|
NW_ASSERT(pStack);
|
||||||
|
|
||||||
if(gpGtpv2cMsgPool)
|
if(gpGtpv2cMsgPool) {
|
||||||
{
|
|
||||||
pMsg = gpGtpv2cMsgPool;
|
pMsg = gpGtpv2cMsgPool;
|
||||||
gpGtpv2cMsgPool = gpGtpv2cMsgPool->next;
|
gpGtpv2cMsgPool = gpGtpv2cMsgPool->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_GTPV2C_MALLOC(pStack, sizeof(NwGtpv2cMsgT), pMsg, NwGtpv2cMsgT*);
|
NW_GTPV2C_MALLOC(pStack, sizeof(NwGtpv2cMsgT), pMsg, NwGtpv2cMsgT*);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pMsg)
|
if(pMsg) {
|
||||||
{
|
|
||||||
*phMsg = (NwGtpv2cMsgHandleT) pMsg;
|
*phMsg = (NwGtpv2cMsgHandleT) pMsg;
|
||||||
memcpy(pMsg->msgBuf, pBuf, bufLen);
|
memcpy(pMsg->msgBuf, pBuf, bufLen);
|
||||||
pMsg->msgLen = bufLen;
|
pMsg->msgLen = bufLen;
|
||||||
@@ -137,8 +129,7 @@ nwGtpv2cMsgFromBufferNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
pMsg->msgType = *(pBuf);
|
pMsg->msgType = *(pBuf);
|
||||||
pBuf += 3;
|
pBuf += 3;
|
||||||
|
|
||||||
if(pMsg->teidPresent)
|
if(pMsg->teidPresent) {
|
||||||
{
|
|
||||||
pMsg->teid = ntohl(*((NwU32T*)(pBuf)));
|
pMsg->teid = ntohl(*((NwU32T*)(pBuf)));
|
||||||
pBuf += 4;
|
pBuf += 4;
|
||||||
}
|
}
|
||||||
@@ -150,6 +141,7 @@ nwGtpv2cMsgFromBufferNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
NW_LOG(pStack, NW_LOG_LEVEL_DEBG, "Created message %p!", pMsg);
|
NW_LOG(pStack, NW_LOG_LEVEL_DEBG, "Created message %p!", pMsg);
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,82 +158,82 @@ nwGtpv2cMsgDelete( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set TEID for gtpv2c message.
|
* Set TEID for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] teid: TEID value.
|
* @param[in] teid: TEID value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgSetTeid(NW_IN NwGtpv2cMsgHandleT hMsg, NwU32T teid)
|
nwGtpv2cMsgSetTeid(NW_IN NwGtpv2cMsgHandleT hMsg, NwU32T teid)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
thiz->teid = teid;
|
thiz->teid = teid;
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set TEID present flag for gtpv2c message.
|
* Set TEID present flag for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] teidPesent: Flag boolean value.
|
* @param[in] teidPesent: Flag boolean value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgSetTeidPresent(NW_IN NwGtpv2cMsgHandleT hMsg, NwBoolT teidPresent)
|
nwGtpv2cMsgSetTeidPresent(NW_IN NwGtpv2cMsgHandleT hMsg, NwBoolT teidPresent)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
thiz->teidPresent = teidPresent;
|
thiz->teidPresent = teidPresent;
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set sequence for gtpv2c message.
|
* Set sequence for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
* @param[in] seqNum: Flag boolean value.
|
* @param[in] seqNum: Flag boolean value.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgSetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg, NwU32T seqNum)
|
nwGtpv2cMsgSetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg, NwU32T seqNum)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
thiz->seqNum = seqNum;
|
thiz->seqNum = seqNum;
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get TEID present for gtpv2c message.
|
* Get TEID present for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv2cMsgGetTeid(NW_IN NwGtpv2cMsgHandleT hMsg)
|
nwGtpv2cMsgGetTeid(NW_IN NwGtpv2cMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
return (thiz->teid);
|
return (thiz->teid);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get TEID present for gtpv2c message.
|
* Get TEID present for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwBoolT
|
NwBoolT
|
||||||
nwGtpv2cMsgGetTeidPresent(NW_IN NwGtpv2cMsgHandleT hMsg)
|
nwGtpv2cMsgGetTeidPresent(NW_IN NwGtpv2cMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
return (thiz->teidPresent);
|
return (thiz->teidPresent);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get sequence number for gtpv2c message.
|
* Get sequence number for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv2cMsgGetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg)
|
nwGtpv2cMsgGetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg)
|
||||||
@@ -250,11 +242,11 @@ nwGtpv2cMsgGetSeqNumber(NW_IN NwGtpv2cMsgHandleT hMsg)
|
|||||||
return (thiz->seqNum);
|
return (thiz->seqNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get msg type for gtpv2c message.
|
* Get msg type for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv2cMsgGetMsgType(NW_IN NwGtpv2cMsgHandleT hMsg)
|
nwGtpv2cMsgGetMsgType(NW_IN NwGtpv2cMsgHandleT hMsg)
|
||||||
@@ -263,11 +255,11 @@ nwGtpv2cMsgGetMsgType(NW_IN NwGtpv2cMsgHandleT hMsg)
|
|||||||
return (thiz->msgType);
|
return (thiz->msgType);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get msg type for gtpv2c message.
|
* Get msg type for gtpv2c message.
|
||||||
*
|
*
|
||||||
* @param[in] hMsg : Message handle.
|
* @param[in] hMsg : Message handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwU32T
|
NwU32T
|
||||||
nwGtpv2cMsgGetLength(NW_IN NwGtpv2cMsgHandleT hMsg)
|
nwGtpv2cMsgGetLength(NW_IN NwGtpv2cMsgHandleT hMsg)
|
||||||
@@ -278,10 +270,10 @@ nwGtpv2cMsgGetLength(NW_IN NwGtpv2cMsgHandleT hMsg)
|
|||||||
|
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU8T value)
|
NW_IN NwU8T value)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTv1T *pIe;
|
NwGtpv2cIeTv1T *pIe;
|
||||||
@@ -299,10 +291,10 @@ nwGtpv2cMsgAddIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeTV2(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeTV2(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU16T value)
|
NW_IN NwU16T value)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTv2T *pIe;
|
NwGtpv2cIeTv2T *pIe;
|
||||||
@@ -320,10 +312,10 @@ nwGtpv2cMsgAddIeTV2(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeTV4(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeTV4(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU32T value)
|
NW_IN NwU32T value)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTv4T *pIe;
|
NwGtpv2cIeTv4T *pIe;
|
||||||
@@ -341,11 +333,11 @@ nwGtpv2cMsgAddIeTV4(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIe(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIe(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU16T length,
|
NW_IN NwU16T length,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU8T* pVal)
|
NW_IN NwU8T* pVal)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTlvT *pIe;
|
NwGtpv2cIeTlvT *pIe;
|
||||||
@@ -363,9 +355,9 @@ nwGtpv2cMsgAddIe(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGroupedIeStart(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGroupedIeStart(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance)
|
NW_IN NwU8T instance)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTlvT *pIe;
|
NwGtpv2cIeTlvT *pIe;
|
||||||
@@ -386,11 +378,11 @@ nwGtpv2cMsgGroupedIeStart(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGroupedIeEnd(NW_IN NwGtpv2cMsgHandleT hMsg)
|
nwGtpv2cMsgGroupedIeEnd(NW_IN NwGtpv2cMsgHandleT hMsg)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *pMsg = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTlvT *pIe;
|
NwGtpv2cIeTlvT *pIe;
|
||||||
|
|
||||||
NW_ASSERT(pMsg->groupedIeEncodeStack.top > 0);
|
NW_ASSERT(pMsg->groupedIeEncodeStack.top > 0);
|
||||||
|
|
||||||
pMsg->groupedIeEncodeStack.top--;
|
pMsg->groupedIeEncodeStack.top--;
|
||||||
@@ -402,7 +394,7 @@ nwGtpv2cMsgGroupedIeEnd(NW_IN NwGtpv2cMsgHandleT hMsg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU8T causeValue,
|
NW_IN NwU8T causeValue,
|
||||||
NW_IN NwU8T bitFlags,
|
NW_IN NwU8T bitFlags,
|
||||||
@@ -414,8 +406,7 @@ nwGtpv2cMsgAddIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
causeBuf[0] = causeValue;
|
causeBuf[0] = causeValue;
|
||||||
causeBuf[1] = bitFlags;
|
causeBuf[1] = bitFlags;
|
||||||
|
|
||||||
if(offendingIeType)
|
if(offendingIeType) {
|
||||||
{
|
|
||||||
causeBuf[2] = offendingIeType;
|
causeBuf[2] = offendingIeType;
|
||||||
causeBuf[3] = 0;
|
causeBuf[3] = 0;
|
||||||
causeBuf[4] = 0;
|
causeBuf[4] = 0;
|
||||||
@@ -426,12 +417,12 @@ nwGtpv2cMsgAddIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgAddIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgAddIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU8T ifType,
|
NW_IN NwU8T ifType,
|
||||||
NW_IN NwU32T teidOrGreKey,
|
NW_IN NwU32T teidOrGreKey,
|
||||||
NW_IN NwU32T ipv4Addr,
|
NW_IN NwU32T ipv4Addr,
|
||||||
NW_IN NwU8T* pIpv6Addr)
|
NW_IN NwU8T* pIpv6Addr)
|
||||||
{
|
{
|
||||||
|
|
||||||
NwU8T fteidBuf[32];
|
NwU8T fteidBuf[32];
|
||||||
@@ -440,188 +431,209 @@ nwGtpv2cMsgAddIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
fteidBuf[0] = (ifType & 0x1F);
|
fteidBuf[0] = (ifType & 0x1F);
|
||||||
pFteidBuf++;
|
pFteidBuf++;
|
||||||
|
|
||||||
*((NwU32T*)(pFteidBuf)) = htonl((teidOrGreKey));
|
*((NwU32T*)(pFteidBuf)) = htonl((teidOrGreKey));
|
||||||
pFteidBuf += 4;
|
pFteidBuf += 4;
|
||||||
|
|
||||||
if(ipv4Addr)
|
if(ipv4Addr) {
|
||||||
{
|
|
||||||
fteidBuf[0] |= (0x01 << 7);
|
fteidBuf[0] |= (0x01 << 7);
|
||||||
*((NwU32T*)(pFteidBuf)) = htonl(ipv4Addr);
|
*((NwU32T*)(pFteidBuf)) = htonl(ipv4Addr);
|
||||||
pFteidBuf += 4;
|
pFteidBuf += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pIpv6Addr)
|
if(pIpv6Addr) {
|
||||||
{
|
|
||||||
fteidBuf[0] |= (0x01 << 6);
|
fteidBuf[0] |= (0x01 << 6);
|
||||||
memcpy((pFteidBuf), pIpv6Addr, 16);
|
memcpy((pFteidBuf), pIpv6Addr, 16);
|
||||||
pFteidBuf += 16;
|
pFteidBuf += 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (nwGtpv2cMsgAddIe(hMsg, NW_GTPV2C_IE_FTEID, (pFteidBuf - fteidBuf), instance, fteidBuf));
|
return (nwGtpv2cMsgAddIe(hMsg, NW_GTPV2C_IE_FTEID, (pFteidBuf - fteidBuf), instance, fteidBuf));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
NwBoolT
|
NwBoolT
|
||||||
nwGtpv2cMsgIsIePresent(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgIsIePresent(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance)
|
NW_IN NwU8T instance)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
|
|
||||||
if((NwGtpv2cIeTv1T*) thiz->pIe[type][instance])
|
if((NwGtpv2cIeTv1T*) thiz->pIe[type][instance])
|
||||||
return NW_TRUE;
|
return NW_TRUE;
|
||||||
return NW_FALSE;
|
|
||||||
|
return NW_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTV1(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU8T* pVal)
|
NW_OUT NwU8T* pVal)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTv1T *pIe;
|
NwGtpv2cIeTv1T *pIe;
|
||||||
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
if(thiz->isIeValid[type][instance])
|
|
||||||
{
|
if(thiz->isIeValid[type][instance]) {
|
||||||
pIe = (NwGtpv2cIeTv1T*) thiz->pIe[type][instance];
|
pIe = (NwGtpv2cIeTv1T*) thiz->pIe[type][instance];
|
||||||
|
|
||||||
if(ntohs(pIe->l) != 0x01)
|
if(ntohs(pIe->l) != 0x01)
|
||||||
return NW_GTPV2C_IE_INCORRECT;
|
return NW_GTPV2C_IE_INCORRECT;
|
||||||
|
|
||||||
if(pVal) *pVal = pIe->v;
|
if(pVal) *pVal = pIe->v;
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_GTPV2C_IE_MISSING;
|
return NW_GTPV2C_IE_MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTV2( NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTV2( NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU16T* pVal)
|
NW_OUT NwU16T* pVal)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTv2T *pIe;
|
NwGtpv2cIeTv2T *pIe;
|
||||||
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
if(thiz->isIeValid[type][instance])
|
|
||||||
{
|
if(thiz->isIeValid[type][instance]) {
|
||||||
pIe = (NwGtpv2cIeTv2T*) thiz->pIe[type][instance];
|
pIe = (NwGtpv2cIeTv2T*) thiz->pIe[type][instance];
|
||||||
|
|
||||||
if(ntohs(pIe->l) != 0x02)
|
if(ntohs(pIe->l) != 0x02)
|
||||||
return NW_GTPV2C_IE_INCORRECT;
|
return NW_GTPV2C_IE_INCORRECT;
|
||||||
|
|
||||||
if(pVal) *pVal = ntohs(pIe->v);
|
if(pVal) *pVal = ntohs(pIe->v);
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_GTPV2C_IE_MISSING;
|
return NW_GTPV2C_IE_MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTV4( NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTV4( NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU32T* pVal)
|
NW_OUT NwU32T* pVal)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTv4T *pIe;
|
NwGtpv2cIeTv4T *pIe;
|
||||||
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
if(thiz->isIeValid[type][instance])
|
|
||||||
{
|
if(thiz->isIeValid[type][instance]) {
|
||||||
pIe = (NwGtpv2cIeTv4T*) thiz->pIe[type][instance];
|
pIe = (NwGtpv2cIeTv4T*) thiz->pIe[type][instance];
|
||||||
|
|
||||||
if(ntohs(pIe->l) != 0x04)
|
if(ntohs(pIe->l) != 0x04)
|
||||||
return NW_GTPV2C_IE_INCORRECT;
|
return NW_GTPV2C_IE_INCORRECT;
|
||||||
|
|
||||||
if(pVal) *pVal = ntohl(pIe->v);
|
if(pVal) *pVal = ntohl(pIe->v);
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_GTPV2C_IE_MISSING;
|
return NW_GTPV2C_IE_MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTV8( NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTV8( NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU64T* pVal)
|
NW_OUT NwU64T* pVal)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTv8T *pIe;
|
NwGtpv2cIeTv8T *pIe;
|
||||||
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
if(thiz->isIeValid[type][instance])
|
|
||||||
{
|
if(thiz->isIeValid[type][instance]) {
|
||||||
pIe = (NwGtpv2cIeTv8T*) thiz->pIe[type][instance];
|
pIe = (NwGtpv2cIeTv8T*) thiz->pIe[type][instance];
|
||||||
|
|
||||||
if(ntohs(pIe->l) != 0x08)
|
if(ntohs(pIe->l) != 0x08)
|
||||||
return NW_GTPV2C_IE_INCORRECT;
|
return NW_GTPV2C_IE_INCORRECT;
|
||||||
|
|
||||||
if(pVal) *pVal = NW_NTOHLL((pIe->v));
|
if(pVal) *pVal = NW_NTOHLL((pIe->v));
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Cannot retrieve IE of type %u instance %u !", type, instance);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Cannot retrieve IE of type %u instance %u !", type, instance);
|
||||||
return NW_GTPV2C_IE_MISSING;
|
return NW_GTPV2C_IE_MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTlv( NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTlv( NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_IN NwU16T maxLen,
|
NW_IN NwU16T maxLen,
|
||||||
NW_OUT NwU8T* pVal,
|
NW_OUT NwU8T* pVal,
|
||||||
NW_OUT NwU16T* pLen)
|
NW_OUT NwU16T* pLen)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTlvT *pIe;
|
NwGtpv2cIeTlvT *pIe;
|
||||||
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
if(thiz->isIeValid[type][instance])
|
|
||||||
{
|
if(thiz->isIeValid[type][instance]) {
|
||||||
pIe = (NwGtpv2cIeTlvT*) thiz->pIe[type][instance];
|
pIe = (NwGtpv2cIeTlvT*) thiz->pIe[type][instance];
|
||||||
if(ntohs(pIe->l) <= maxLen)
|
|
||||||
{
|
if(ntohs(pIe->l) <= maxLen) {
|
||||||
if(pVal) memcpy(pVal, ((NwU8T*) pIe) + 4, ntohs(pIe->l));
|
if(pVal) memcpy(pVal, ((NwU8T*) pIe) + 4, ntohs(pIe->l));
|
||||||
|
|
||||||
if(pLen) *pLen = ntohs(pIe->l);
|
if(pLen) *pLen = ntohs(pIe->l);
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_GTPV2C_IE_MISSING;
|
return NW_GTPV2C_IE_MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeTlvP( NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeTlvP( NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T type,
|
NW_IN NwU8T type,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU8T** ppVal,
|
NW_OUT NwU8T** ppVal,
|
||||||
NW_OUT NwU16T* pLen)
|
NW_OUT NwU16T* pLen)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTlvT *pIe;
|
NwGtpv2cIeTlvT *pIe;
|
||||||
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
if(thiz->isIeValid[type][instance])
|
|
||||||
{
|
if(thiz->isIeValid[type][instance]) {
|
||||||
pIe = (NwGtpv2cIeTlvT*) thiz->pIe[type][instance];
|
pIe = (NwGtpv2cIeTlvT*) thiz->pIe[type][instance];
|
||||||
|
|
||||||
if(ppVal) *ppVal = ((NwU8T*) pIe) + 4;
|
if(ppVal) *ppVal = ((NwU8T*) pIe) + 4;
|
||||||
|
|
||||||
if(pLen) *pLen = ntohs(pIe->l);
|
if(pLen) *pLen = ntohs(pIe->l);
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_GTPV2C_IE_MISSING;
|
return NW_GTPV2C_IE_MISSING;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU8T* causeValue,
|
NW_OUT NwU8T* causeValue,
|
||||||
NW_OUT NwU8T* flags,
|
NW_OUT NwU8T* flags,
|
||||||
NW_OUT NwU8T* offendingIeType,
|
NW_OUT NwU8T* offendingIeType,
|
||||||
NW_OUT NwU8T* offendingIeInstance)
|
NW_OUT NwU8T* offendingIeInstance)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTlvT *pIe;
|
NwGtpv2cIeTlvT *pIe;
|
||||||
|
|
||||||
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
if(thiz->isIeValid[NW_GTPV2C_IE_CAUSE][instance])
|
|
||||||
{
|
if(thiz->isIeValid[NW_GTPV2C_IE_CAUSE][instance]) {
|
||||||
pIe = (NwGtpv2cIeTlvT*) thiz->pIe[NW_GTPV2C_IE_CAUSE][instance];
|
pIe = (NwGtpv2cIeTlvT*) thiz->pIe[NW_GTPV2C_IE_CAUSE][instance];
|
||||||
*causeValue = *((NwU8T*)(((NwU8T*)pIe) + 4));
|
*causeValue = *((NwU8T*)(((NwU8T*)pIe) + 4));
|
||||||
*flags = *((NwU8T*)(((NwU8T*)pIe) + 5));
|
*flags = *((NwU8T*)(((NwU8T*)pIe) + 5));
|
||||||
if(pIe->l == 6)
|
|
||||||
{
|
if(pIe->l == 6) {
|
||||||
*offendingIeType = *((NwU8T*)(((NwU8T*)pIe) + 6));
|
*offendingIeType = *((NwU8T*)(((NwU8T*)pIe) + 6));
|
||||||
*offendingIeType = *((NwU8T*)(((NwU8T*)pIe) + 8));
|
*offendingIeType = *((NwU8T*)(((NwU8T*)pIe) + 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -629,35 +641,34 @@ nwGtpv2cMsgGetIeCause(NW_IN NwGtpv2cMsgHandleT hMsg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgGetIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
nwGtpv2cMsgGetIeFteid(NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_IN NwU8T instance,
|
NW_IN NwU8T instance,
|
||||||
NW_OUT NwU8T* ifType,
|
NW_OUT NwU8T* ifType,
|
||||||
NW_OUT NwU32T* teidOrGreKey,
|
NW_OUT NwU32T* teidOrGreKey,
|
||||||
NW_OUT NwU32T* ipv4Addr,
|
NW_OUT NwU32T* ipv4Addr,
|
||||||
NW_OUT NwU8T* pIpv6Addr)
|
NW_OUT NwU8T* pIpv6Addr)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
NwGtpv2cMsgT *thiz = (NwGtpv2cMsgT*) hMsg;
|
||||||
NwGtpv2cIeTlvT *pIe;
|
NwGtpv2cIeTlvT *pIe;
|
||||||
|
|
||||||
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(instance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
|
|
||||||
if(thiz->isIeValid[NW_GTPV2C_IE_FTEID][instance])
|
if(thiz->isIeValid[NW_GTPV2C_IE_FTEID][instance]) {
|
||||||
{
|
pIe = (NwGtpv2cIeTlvT*) thiz->pIe[NW_GTPV2C_IE_FTEID][instance];
|
||||||
pIe = (NwGtpv2cIeTlvT*) thiz->pIe[NW_GTPV2C_IE_FTEID][instance];
|
|
||||||
NwU8T flags;
|
NwU8T flags;
|
||||||
NwU8T* pIeValue = ((NwU8T*) pIe) + 4;
|
NwU8T* pIeValue = ((NwU8T*) pIe) + 4;
|
||||||
flags = (*pIeValue) & 0xE0;
|
flags = (*pIeValue) & 0xE0;
|
||||||
*ifType = (*pIeValue) & 0x1F;
|
*ifType = (*pIeValue) & 0x1F;
|
||||||
pIeValue += 1;
|
pIeValue += 1;
|
||||||
|
|
||||||
*teidOrGreKey = ntohl(*((NwU32T*)(pIeValue)));
|
*teidOrGreKey = ntohl(*((NwU32T*)(pIeValue)));
|
||||||
pIeValue += 4;
|
pIeValue += 4;
|
||||||
|
|
||||||
if(flags & 0x80)
|
if(flags & 0x80) {
|
||||||
{
|
|
||||||
*ipv4Addr = ntohl(*((NwU32T*)(pIeValue)));
|
*ipv4Addr = ntohl(*((NwU32T*)(pIeValue)));
|
||||||
pIeValue += 4;
|
pIeValue += 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -680,14 +691,16 @@ nwGtpv2cMsgHexDump(NwGtpv2cMsgHandleT hMsg, FILE* fp)
|
|||||||
char hexstr[ 16*3 + 5] = {0};
|
char hexstr[ 16*3 + 5] = {0};
|
||||||
char charstr[16*1 + 5] = {0};
|
char charstr[16*1 + 5] = {0};
|
||||||
fprintf((FILE*)fp, "\n");
|
fprintf((FILE*)fp, "\n");
|
||||||
for(n=1;n<=size;n++) {
|
|
||||||
|
for(n=1; n<=size; n++) {
|
||||||
if (n%16 == 1) {
|
if (n%16 == 1) {
|
||||||
/* store address for this line */
|
/* store address for this line */
|
||||||
snprintf(addrstr, sizeof(addrstr), "%.4lx",
|
snprintf(addrstr, sizeof(addrstr), "%.4lx",
|
||||||
((unsigned long)p-(unsigned long)data) );
|
((unsigned long)p-(unsigned long)data) );
|
||||||
}
|
}
|
||||||
|
|
||||||
c = *p;
|
c = *p;
|
||||||
|
|
||||||
if (isalnum(c) == 0) {
|
if (isalnum(c) == 0) {
|
||||||
c = '.';
|
c = '.';
|
||||||
}
|
}
|
||||||
@@ -699,6 +712,7 @@ nwGtpv2cMsgHexDump(NwGtpv2cMsgHandleT hMsg, FILE* fp)
|
|||||||
/* store char str (for right side) */
|
/* store char str (for right side) */
|
||||||
snprintf(bytestr, sizeof(bytestr), "%c", c);
|
snprintf(bytestr, sizeof(bytestr), "%c", c);
|
||||||
strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
|
strncat(charstr, bytestr, sizeof(charstr)-strlen(charstr)-1);
|
||||||
|
|
||||||
if(n%16 == 0) {
|
if(n%16 == 0) {
|
||||||
/* line completed */
|
/* line completed */
|
||||||
fprintf((FILE*)fp, "[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
|
fprintf((FILE*)fp, "[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
|
||||||
@@ -709,6 +723,7 @@ nwGtpv2cMsgHexDump(NwGtpv2cMsgHandleT hMsg, FILE* fp)
|
|||||||
strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1);
|
strncat(hexstr, " ", sizeof(hexstr)-strlen(hexstr)-1);
|
||||||
strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
|
strncat(charstr, " ", sizeof(charstr)-strlen(charstr)-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
p++; /* next byte */
|
p++; /* next byte */
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,6 +732,7 @@ nwGtpv2cMsgHexDump(NwGtpv2cMsgHandleT hMsg, FILE* fp)
|
|||||||
fprintf((FILE*)fp, "[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
|
fprintf((FILE*)fp, "[%4.4s] %-50.50s %s\n", addrstr, hexstr, charstr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf((FILE*)fp, "\n");
|
fprintf((FILE*)fp, "\n");
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
@@ -729,6 +745,6 @@ nwGtpv2cMsgHexDump(NwGtpv2cMsgHandleT hMsg, FILE* fp)
|
|||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* E N D O F F I L E *
|
* E N D O F F I L E *
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -49,8 +49,7 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
typedef struct NwGtpv2cMsgIeInfo
|
typedef struct NwGtpv2cMsgIeInfo {
|
||||||
{
|
|
||||||
NwU8T ieType;
|
NwU8T ieType;
|
||||||
NwU8T ieMinLength;
|
NwU8T ieMinLength;
|
||||||
NwU8T ieInstance;
|
NwU8T ieInstance;
|
||||||
@@ -59,8 +58,7 @@ typedef struct NwGtpv2cMsgIeInfo
|
|||||||
} NwGtpv2cMsgIeInfoT;
|
} NwGtpv2cMsgIeInfoT;
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT createSessionReqBearerCtxtTobeCreatedIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT createSessionReqBearerCtxtTobeCreatedIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_EBI , 1, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL},
|
{ NW_GTPV2C_IE_EBI , 1, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL},
|
||||||
{ NW_GTPV2C_IE_BEARER_TFT , 0, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL},
|
{ NW_GTPV2C_IE_BEARER_TFT , 0, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL},
|
||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},
|
||||||
@@ -69,15 +67,14 @@ NwGtpv2cMsgIeInfoT createSessionReqBearerCtxtTobeCreatedIeInfoTbl[] =
|
|||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_THREE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_THREE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},
|
||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_FOUR , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_FOUR , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},
|
||||||
{ NW_GTPV2C_IE_BEARER_LEVEL_QOS, 18, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL},
|
{ NW_GTPV2C_IE_BEARER_LEVEL_QOS, 18, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL},
|
||||||
// { NW_GTPV2C_IE_IMSI , 0, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},
|
// { NW_GTPV2C_IE_IMSI , 0, NW_GTPV2C_IE_INSTANCE_ZERO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL},
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT createSessionReqBearerCtxtTobeRemovedIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT createSessionReqBearerCtxtTobeRemovedIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_IMSI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
{ NW_GTPV2C_IE_IMSI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
@@ -85,17 +82,15 @@ NwGtpv2cMsgIeInfoT createSessionReqBearerCtxtTobeRemovedIeInfoTbl[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT echoRspIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT echoRspIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_RECOVERY , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
|
{ NW_GTPV2C_IE_RECOVERY , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY, NULL},
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT createSessionReqIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT createSessionReqIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
||||||
{ NW_GTPV2C_IE_MSISDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
{ NW_GTPV2C_IE_MSISDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
||||||
{ NW_GTPV2C_IE_MEI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
{ NW_GTPV2C_IE_MEI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
||||||
@@ -128,8 +123,7 @@ NwGtpv2cMsgIeInfoT createSessionReqIeInfoTbl[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT modifyBearerReqIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT modifyBearerReqIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_MEI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_MEI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_SERVING_NETWORK, 3, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
{ NW_GTPV2C_IE_SERVING_NETWORK, 3, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL},
|
||||||
{ NW_GTPV2C_IE_ULI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_ULI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
@@ -145,8 +139,7 @@ NwGtpv2cMsgIeInfoT modifyBearerReqIeInfoTbl[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT deleteSessionReqIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT deleteSessionReqIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_EBI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_EBI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_ULI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_ULI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
@@ -160,8 +153,7 @@ NwGtpv2cMsgIeInfoT deleteSessionReqIeInfoTbl[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT createSessionRspIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT createSessionRspIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_PAA , 5, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_PAA , 5, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_APN_RESTRICTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_APN_RESTRICTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
@@ -177,8 +169,7 @@ NwGtpv2cMsgIeInfoT createSessionRspIeInfoTbl[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT modifyBearerRspIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT modifyBearerRspIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_PAA , 5, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_PAA , 5, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_APN_RESTRICTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_APN_RESTRICTION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
@@ -192,8 +183,7 @@ NwGtpv2cMsgIeInfoT modifyBearerRspIeInfoTbl[] =
|
|||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT deleteSessionRspIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT deleteSessionRspIeInfoTbl[] = {
|
||||||
{
|
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_RECOVERY , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_RECOVERY , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_PCO , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_PCO , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
@@ -205,165 +195,156 @@ NwGtpv2cMsgIeInfoT deleteSessionRspIeInfoTbl[] =
|
|||||||
|
|
||||||
/* Message sent over s10 interface */
|
/* Message sent over s10 interface */
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT identificationReqIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT identificationReqIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_GUTI , 6, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_GUTI , 6, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_COMPLETE_REQUEST_MESSAGE, 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_COMPLETE_REQUEST_MESSAGE, 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_SERVING_NETWORK, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_SERVING_NETWORK, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT identificationRspIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT identificationRspIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_MM_CONTEXT , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_MM_CONTEXT , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT contextReqIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT contextReqIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_GUTI , 5, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_GUTI , 5, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_ULI , 7, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_ULI , 7, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_PTMSI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_PTMSI , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_COMPLETE_REQUEST_MESSAGE, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_COMPLETE_REQUEST_MESSAGE, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_UDP_SOURCE_PORT_NUMBER, 9, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_UDP_SOURCE_PORT_NUMBER, 9, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_RAT_TYPE , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_RAT_TYPE , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
{ NW_GTPV2C_IE_HOP_COUNTER , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_HOP_COUNTER , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
{ NW_GTPV2C_IE_SERVING_NETWORK, 3, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_SERVING_NETWORK, 3, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_LDN , 3, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_LDN , 3, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT contextRspIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT contextRspIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_MM_CONTEXT , 4, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_MM_CONTEXT , 4, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_PDN_CONNECTION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PDN_CONNECTION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_FQDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_FQDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_IP_ADDRESS , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_IP_ADDRESS , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_IP_ADDRESS , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_IP_ADDRESS , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL , NULL },
|
{ NW_GTPV2C_IE_RFSP_INDEX , 2, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_RFSP_INDEX , 2, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_RFSP_INDEX , 2, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_RFSP_INDEX , 2, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_UE_TIME_ZONE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_UE_TIME_ZONE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_LDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_LDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT contextAckIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT contextAckIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT forwardRelocationReqIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT forwardRelocationReqIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_IMSI , 8, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_PDN_CONNECTION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_PDN_CONNECTION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_FQDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_FQDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_MM_CONTEXT , 4, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_MM_CONTEXT , 4, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_TARGET_IDENTIFICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_TARGET_IDENTIFICATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_IP_ADDRESS , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_IP_ADDRESS , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_IP_ADDRESS , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_IP_ADDRESS , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_SOURCE_IDENTIFICATION, 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_SOURCE_IDENTIFICATION, 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_SELECTED_PLMN_ID, 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_SELECTED_PLMN_ID, 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_RECOVERY , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_RECOVERY , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_TRACE_INFORMATION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_RFSP_INDEX , 2, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_RFSP_INDEX , 2, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_RFSP_INDEX , 2, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_RFSP_INDEX , 2, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_CSG_ID , 4, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_CSG_ID , 4, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_CSG_MEMBERSHIP_INDICATION, 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_CSG_MEMBERSHIP_INDICATION, 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_UE_TIME_ZONE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_UE_TIME_ZONE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_LDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_LDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
{ NW_GTPV2C_IE_ADDITIONAL_MM_CTXT_FOR_SRVCC,0,NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_ADDITIONAL_MM_CTXT_FOR_SRVCC,0,NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_ADDITIONAL_FLAGS_FOR_SRVCC, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_ADDITIONAL_FLAGS_FOR_SRVCC, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_MSISDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_MSISDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL_OPTIONAL, NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0 }
|
{ 0, 0, 0 }
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT forwardRelocationRspIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT forwardRelocationRspIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_FTEID , 9, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_BEARER_CONTEXT , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_BEARER_CONTEXT , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_BEARER_CONTEXT , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_BEARER_CONTEXT , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_BEARER_CONTEXT , 0, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_BEARER_CONTEXT , 0, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_ONE , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CONTAINER , 1, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_F_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_TWO , NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_LDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_LDN , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT forwardRelocationCompleteNtfIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT forwardRelocationCompleteNtfIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
||||||
{ NW_GTPV2C_IE_INDICATION , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_CONDITIONAL, NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static
|
static
|
||||||
NwGtpv2cMsgIeInfoT forwardRelocationCompleteAckIeInfoTbl[] =
|
NwGtpv2cMsgIeInfoT forwardRelocationCompleteAckIeInfoTbl[] = {
|
||||||
{
|
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
||||||
{ NW_GTPV2C_IE_CAUSE , 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_MANDATORY , NULL },
|
{ NW_GTPV2C_IE_RECOVERY , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_RECOVERY , 1, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
||||||
{ NW_GTPV2C_IE_PRIVATE_EXTENSION, 0, NW_GTPV2C_IE_INSTANCE_ZERO, NW_GTPV2C_IE_PRESENCE_OPTIONAL , NULL },
|
|
||||||
|
|
||||||
/* Do not add below this */
|
/* Do not add below this */
|
||||||
{ 0, 0, 0}
|
{ 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
@@ -373,16 +354,18 @@ NwGtpv2cMsgIeInfoT forwardRelocationCompleteAckIeInfoTbl[] =
|
|||||||
static NwU32T
|
static NwU32T
|
||||||
nwGtpv2cMsgGroupedIeCount(NwGtpv2cMsgIeInfoT *pMsgIeInfo)
|
nwGtpv2cMsgGroupedIeCount(NwGtpv2cMsgIeInfoT *pMsgIeInfo)
|
||||||
{
|
{
|
||||||
NwU32T count = 0;
|
NwU32T count = 0;
|
||||||
NwGtpv2cMsgIeInfoT *pGroupedIeInfo = pMsgIeInfo;
|
NwGtpv2cMsgIeInfoT *pGroupedIeInfo = pMsgIeInfo;
|
||||||
while (pGroupedIeInfo++) {
|
|
||||||
if (pGroupedIeInfo->ieType == 0) {
|
while (pGroupedIeInfo++) {
|
||||||
break;
|
if (pGroupedIeInfo->ieType == 0) {
|
||||||
}
|
break;
|
||||||
count ++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return count;
|
count ++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NwRcT
|
static NwRcT
|
||||||
@@ -391,52 +374,53 @@ nwGtpv2cMsgIeParseInfoUpdate(NwGtpv2cMsgIeParseInfoT *thiz,
|
|||||||
{
|
{
|
||||||
NwU32T i, j;
|
NwU32T i, j;
|
||||||
|
|
||||||
for (i = 0; pMsgIeInfo[i].ieType; i++)
|
for (i = 0; pMsgIeInfo[i].ieType; i++) {
|
||||||
{
|
|
||||||
if (pMsgIeInfo[i].pGroupedIeInfo) {
|
if (pMsgIeInfo[i].pGroupedIeInfo) {
|
||||||
NwGtpv2cGroupedIeParseInfoT *pMsgIeParseInfo;
|
NwGtpv2cGroupedIeParseInfoT *pMsgIeParseInfo;
|
||||||
|
|
||||||
NW_GTPV2C_MALLOC(thiz->hStack, sizeof(NwGtpv2cGroupedIeParseInfoT),
|
NW_GTPV2C_MALLOC(thiz->hStack, sizeof(NwGtpv2cGroupedIeParseInfoT),
|
||||||
pMsgIeParseInfo, NwGtpv2cGroupedIeParseInfoT*);
|
pMsgIeParseInfo, NwGtpv2cGroupedIeParseInfoT*);
|
||||||
|
|
||||||
pMsgIeParseInfo->groupedIeType = pMsgIeInfo[i].ieType;
|
pMsgIeParseInfo->groupedIeType = pMsgIeInfo[i].ieType;
|
||||||
pMsgIeParseInfo->hStack = thiz->hStack;
|
pMsgIeParseInfo->hStack = thiz->hStack;
|
||||||
|
|
||||||
for (j = 0; pMsgIeInfo[i].pGroupedIeInfo[j].ieType; j++) {
|
for (j = 0; pMsgIeInfo[i].pGroupedIeInfo[j].ieType; j++) {
|
||||||
pMsgIeParseInfo->ieParseInfo[pMsgIeInfo[i].pGroupedIeInfo[j].ieType][pMsgIeInfo[i].pGroupedIeInfo[j].ieInstance].ieMinLength =
|
pMsgIeParseInfo->ieParseInfo[pMsgIeInfo[i].pGroupedIeInfo[j].ieType][pMsgIeInfo[i].pGroupedIeInfo[j].ieInstance].ieMinLength =
|
||||||
pMsgIeInfo[i].pGroupedIeInfo[j].ieMinLength;
|
pMsgIeInfo[i].pGroupedIeInfo[j].ieMinLength;
|
||||||
pMsgIeParseInfo->ieParseInfo[pMsgIeInfo[i].pGroupedIeInfo[j].ieType][pMsgIeInfo[i].pGroupedIeInfo[j].ieInstance].iePresence =
|
pMsgIeParseInfo->ieParseInfo[pMsgIeInfo[i].pGroupedIeInfo[j].ieType][pMsgIeInfo[i].pGroupedIeInfo[j].ieInstance].iePresence =
|
||||||
pMsgIeInfo[i].pGroupedIeInfo[j].iePresence;
|
pMsgIeInfo[i].pGroupedIeInfo[j].iePresence;
|
||||||
|
|
||||||
if(pMsgIeInfo[i].pGroupedIeInfo[j].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
if(pMsgIeInfo[i].pGroupedIeInfo[j].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
||||||
pMsgIeParseInfo->mandatoryIeCount++;
|
pMsgIeParseInfo->mandatoryIeCount++;
|
||||||
}
|
}
|
||||||
thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance].pGroupedIeInfo = pMsgIeParseInfo;
|
|
||||||
|
thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance].pGroupedIeInfo = pMsgIeParseInfo;
|
||||||
} else {
|
} else {
|
||||||
thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance].pGroupedIeInfo = NULL;
|
thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance].pGroupedIeInfo = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance].iePresence = pMsgIeInfo[i].iePresence;
|
thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance].iePresence = pMsgIeInfo[i].iePresence;
|
||||||
thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance].ieMinLength = pMsgIeInfo[i].ieMinLength;
|
thiz->ieParseInfo[pMsgIeInfo[i].ieType][pMsgIeInfo[i].ieInstance].ieMinLength = pMsgIeInfo[i].ieMinLength;
|
||||||
|
|
||||||
if(pMsgIeInfo[i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
if(pMsgIeInfo[i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
||||||
thiz->mandatoryIeCount++;
|
thiz->mandatoryIeCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static NwRcT
|
static NwRcT
|
||||||
nwGtpv2cMsgGroupedIeParse(NW_IN NwGtpv2cGroupedIeParseInfoT* thiz,
|
nwGtpv2cMsgGroupedIeParse(NW_IN NwGtpv2cGroupedIeParseInfoT* thiz,
|
||||||
NW_IN NwU8T ieType,
|
NW_IN NwU8T ieType,
|
||||||
NW_IN NwU16T ieLength,
|
NW_IN NwU16T ieLength,
|
||||||
NW_IN NwU8T ieInstance,
|
NW_IN NwU8T ieInstance,
|
||||||
NW_IN NwU8T *pIeValue)
|
NW_IN NwU8T *pIeValue)
|
||||||
{
|
{
|
||||||
NW_ASSERT(thiz);
|
NW_ASSERT(thiz);
|
||||||
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received grouped IE %u with instance %u of length %u in msg-type %u!",
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received grouped IE %u with instance %u of length %u in msg-type %u!",
|
||||||
ieType, ieInstance, ieLength, thiz->groupedIeType);
|
ieType, ieInstance, ieLength, thiz->groupedIeType);
|
||||||
|
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -454,121 +438,117 @@ nwGtpv2cMsgIeParseInfoNew(NwGtpv2cStackHandleT hStack, NwU8T msgType)
|
|||||||
{
|
{
|
||||||
NwRcT rc;
|
NwRcT rc;
|
||||||
NwGtpv2cMsgIeParseInfoT *thiz;
|
NwGtpv2cMsgIeParseInfoT *thiz;
|
||||||
|
|
||||||
NW_GTPV2C_MALLOC(hStack, sizeof(NwGtpv2cMsgIeParseInfoT), thiz, NwGtpv2cMsgIeParseInfoT*);
|
NW_GTPV2C_MALLOC(hStack, sizeof(NwGtpv2cMsgIeParseInfoT), thiz, NwGtpv2cMsgIeParseInfoT*);
|
||||||
|
|
||||||
if(thiz)
|
if(thiz) {
|
||||||
{
|
|
||||||
memset(thiz, 0, sizeof(NwGtpv2cMsgIeParseInfoT));
|
memset(thiz, 0, sizeof(NwGtpv2cMsgIeParseInfoT));
|
||||||
|
|
||||||
thiz->hStack = hStack;
|
thiz->hStack = hStack;
|
||||||
thiz->msgType = msgType;
|
thiz->msgType = msgType;
|
||||||
|
|
||||||
switch(msgType)
|
switch(msgType) {
|
||||||
{
|
case NW_GTP_ECHO_RSP: {
|
||||||
case NW_GTP_ECHO_RSP:
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, echoRspIeInfoTbl);
|
||||||
{
|
NW_ASSERT(NW_OK == rc);
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, echoRspIeInfoTbl);
|
}
|
||||||
NW_ASSERT(NW_OK == rc);
|
break;
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_CREATE_SESSION_REQ:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, createSessionReqIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_CREATE_SESSION_RSP:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, createSessionRspIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_DELETE_SESSION_REQ:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteSessionReqIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_DELETE_SESSION_RSP:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteSessionRspIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_MODIFY_BEARER_REQ:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, modifyBearerReqIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_MODIFY_BEARER_RSP:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, modifyBearerRspIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_FORWARD_RELOCATION_REQ:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationReqIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_FORWARD_RELOCATION_RSP:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationRspIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_FORWARD_RELOCATION_COMPLETE_NTF:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationCompleteNtfIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_FORWARD_RELOCATION_COMPLETE_ACK:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationCompleteAckIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_CONTEXT_REQ:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextReqIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_CONTEXT_RSP:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextRspIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_CONTEXT_ACK:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextAckIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_IDENTIFICATION_REQ:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, identificationReqIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case NW_GTP_IDENTIFICATION_RSP:
|
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, identificationRspIeInfoTbl);
|
|
||||||
NW_ASSERT(NW_OK == rc);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
case NW_GTP_CREATE_SESSION_REQ: {
|
||||||
{
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, createSessionReqIeInfoTbl);
|
||||||
free(thiz);
|
NW_ASSERT(NW_OK == rc);
|
||||||
thiz = NULL;
|
}
|
||||||
}
|
break;
|
||||||
break;
|
|
||||||
|
case NW_GTP_CREATE_SESSION_RSP: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, createSessionRspIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_DELETE_SESSION_REQ: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteSessionReqIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_DELETE_SESSION_RSP: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, deleteSessionRspIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_MODIFY_BEARER_REQ: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, modifyBearerReqIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_MODIFY_BEARER_RSP: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, modifyBearerRspIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_FORWARD_RELOCATION_REQ: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationReqIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_FORWARD_RELOCATION_RSP: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationRspIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_FORWARD_RELOCATION_COMPLETE_NTF: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationCompleteNtfIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_FORWARD_RELOCATION_COMPLETE_ACK: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, forwardRelocationCompleteAckIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_CONTEXT_REQ: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextReqIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_CONTEXT_RSP: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextRspIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_CONTEXT_ACK: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, contextAckIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_IDENTIFICATION_REQ: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, identificationReqIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NW_GTP_IDENTIFICATION_RSP: {
|
||||||
|
rc = nwGtpv2cMsgIeParseInfoUpdate(thiz, identificationRspIeInfoTbl);
|
||||||
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default: {
|
||||||
|
free(thiz);
|
||||||
|
thiz = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -588,14 +568,14 @@ nwGtpv2cMsgIeParseInfoDelete(NwGtpv2cMsgIeParseInfoT* thiz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Parse message
|
* Parse message
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
||||||
NW_IN NwGtpv2cMsgHandleT hMsg,
|
NW_IN NwGtpv2cMsgHandleT hMsg,
|
||||||
NW_INOUT NwGtpv2cErrorT *pError)
|
NW_INOUT NwGtpv2cErrorT *pError)
|
||||||
{
|
{
|
||||||
NwRcT rc = NW_OK;
|
NwRcT rc = NW_OK;
|
||||||
NwU16T mandatoryIeCount =0;
|
NwU16T mandatoryIeCount =0;
|
||||||
@@ -614,8 +594,7 @@ nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
|||||||
//memset(pMsg->pIe, 0, sizeof(NwU8T*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
|
//memset(pMsg->pIe, 0, sizeof(NwU8T*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
|
||||||
memset(pMsg->isIeValid, (NW_FALSE), sizeof(NwU8T) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
|
memset(pMsg->isIeValid, (NW_FALSE), sizeof(NwU8T) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
|
||||||
|
|
||||||
while (pIeBufStart < pIeBufEnd)
|
while (pIeBufStart < pIeBufEnd) {
|
||||||
{
|
|
||||||
pIe = (NwGtpv2cIeTlvT*) pIeBufStart;
|
pIe = (NwGtpv2cIeTlvT*) pIeBufStart;
|
||||||
ieType = pIe->t;
|
ieType = pIe->t;
|
||||||
ieLength = ntohs(pIe->l);
|
ieLength = ntohs(pIe->l);
|
||||||
@@ -624,8 +603,8 @@ nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
|||||||
NW_ASSERT(NW_GTPV2C_IE_INSTANCE_MAXIMUM >= ieInstance);
|
NW_ASSERT(NW_GTPV2C_IE_INSTANCE_MAXIMUM >= ieInstance);
|
||||||
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received IE %u with instance %u of length %u in msg-type %u!", ieType, ieInstance, ieLength, thiz->msgType);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received IE %u with instance %u of length %u in msg-type %u!", ieType, ieInstance, ieLength, thiz->msgType);
|
||||||
if(pIeBufStart + 4 + ieLength > pIeBufEnd)
|
|
||||||
{
|
if(pIeBufStart + 4 + ieLength > pIeBufEnd) {
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Invalid length for IE of type %u and instance %u!", ieType, ieInstance);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Invalid length for IE of type %u and instance %u!", ieType, ieInstance);
|
||||||
pError->cause = NW_GTPV2C_CAUSE_INVALID_LENGTH;
|
pError->cause = NW_GTPV2C_CAUSE_INVALID_LENGTH;
|
||||||
pError->offendingIe.type = ieType;
|
pError->offendingIe.type = ieType;
|
||||||
@@ -633,18 +612,13 @@ nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
|||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((thiz->ieParseInfo[ieType][ieInstance].iePresence))
|
if((thiz->ieParseInfo[ieType][ieInstance].iePresence)) {
|
||||||
{
|
if((ieLength < (thiz->ieParseInfo[ieType][ieInstance].ieMinLength))) {
|
||||||
if((ieLength < (thiz->ieParseInfo[ieType][ieInstance].ieMinLength)))
|
if(thiz->ieParseInfo[ieType][ieInstance].iePresence == NW_GTPV2C_IE_PRESENCE_OPTIONAL) {
|
||||||
{
|
|
||||||
if(thiz->ieParseInfo[ieType][ieInstance].iePresence == NW_GTPV2C_IE_PRESENCE_OPTIONAL)
|
|
||||||
{
|
|
||||||
/* Ignore TLV */
|
/* Ignore TLV */
|
||||||
pIeBufStart += (ieLength + 4);
|
pIeBufStart += (ieLength + 4);
|
||||||
continue;
|
continue;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_INCORRECT;
|
pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_INCORRECT;
|
||||||
pError->offendingIe.type = ieType;
|
pError->offendingIe.type = ieType;
|
||||||
pError->offendingIe.instance = ieInstance;
|
pError->offendingIe.instance = ieInstance;
|
||||||
@@ -653,28 +627,27 @@ nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(pMsg->isIeValid[ieType][ieInstance] == NW_TRUE)
|
if(pMsg->isIeValid[ieType][ieInstance] == NW_TRUE) {
|
||||||
{
|
/*
|
||||||
/*
|
* If an information element is repeated in a GTP signalling
|
||||||
* If an information element is repeated in a GTP signalling
|
* message in which repetition of the information element is
|
||||||
* message in which repetition of the information element is
|
* not specified, only the contents of the information element
|
||||||
* not specified, only the contents of the information element
|
* appearing first shall be handled and all subsequent repetitions
|
||||||
* appearing first shall be handled and all subsequent repetitions
|
* of the information element shall be ignored.
|
||||||
* of the information element shall be ignored.
|
|
||||||
* TODO: Add handling for IEs for which repetition is allowed.
|
* TODO: Add handling for IEs for which repetition is allowed.
|
||||||
*/
|
*/
|
||||||
pIeBufStart += (ieLength + 4);
|
pIeBufStart += (ieLength + 4);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
pMsg->pIe[ieType][ieInstance] = (NwU8T*) pIeBufStart;
|
pMsg->pIe[ieType][ieInstance] = (NwU8T*) pIeBufStart;
|
||||||
pMsg->isIeValid[ieType][ieInstance] = NW_TRUE;
|
pMsg->isIeValid[ieType][ieInstance] = NW_TRUE;
|
||||||
|
|
||||||
if(thiz->ieParseInfo[ieType][ieInstance].pGroupedIeInfo)
|
if(thiz->ieParseInfo[ieType][ieInstance].pGroupedIeInfo) {
|
||||||
{
|
|
||||||
/* Parse the grouped IE */
|
/* Parse the grouped IE */
|
||||||
rc = nwGtpv2cMsgGroupedIeParse(thiz->ieParseInfo[ieType][ieInstance].pGroupedIeInfo, ieType, ieLength, ieInstance, ((NwU8T*) pIe) + 4);
|
rc = nwGtpv2cMsgGroupedIeParse(thiz->ieParseInfo[ieType][ieInstance].pGroupedIeInfo, ieType, ieLength, ieInstance, ((NwU8T*) pIe) + 4);
|
||||||
if (rc != NW_OK)
|
|
||||||
{
|
if (rc != NW_OK) {
|
||||||
pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_INCORRECT;
|
pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_INCORRECT;
|
||||||
pError->offendingIe.type = ieType;
|
pError->offendingIe.type = ieType;
|
||||||
pError->offendingIe.instance = ieInstance;
|
pError->offendingIe.instance = ieInstance;
|
||||||
@@ -683,29 +656,21 @@ nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thiz->ieParseInfo[ieType][ieInstance].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
if(thiz->ieParseInfo[ieType][ieInstance].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY) {
|
||||||
{
|
|
||||||
mandatoryIeCount++;
|
mandatoryIeCount++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "Unexpected IE %u with instance %u of length %u received in msg %u!", ieType, ieInstance, ieLength, thiz->msgType);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "Unexpected IE %u with instance %u of length %u received in msg %u!", ieType, ieInstance, ieLength, thiz->msgType);
|
||||||
}
|
}
|
||||||
|
|
||||||
pIeBufStart += (ieLength + 4);
|
pIeBufStart += (ieLength + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((NW_OK == rc) && (mandatoryIeCount != thiz->mandatoryIeCount))
|
if((NW_OK == rc) && (mandatoryIeCount != thiz->mandatoryIeCount)) {
|
||||||
{
|
for(ieType = 0; ieType < NW_GTPV2C_IE_TYPE_MAXIMUM; ieType++) {
|
||||||
for(ieType = 0; ieType < NW_GTPV2C_IE_TYPE_MAXIMUM; ieType++)
|
for(ieInstance = 0; ieInstance < NW_GTPV2C_IE_INSTANCE_MAXIMUM; ieInstance++) {
|
||||||
{
|
if(thiz->ieParseInfo[ieType][ieInstance].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY) {
|
||||||
for(ieInstance = 0; ieInstance < NW_GTPV2C_IE_INSTANCE_MAXIMUM; ieInstance++)
|
if(pMsg->isIeValid[ieType][ieInstance] == NW_FALSE) {
|
||||||
{
|
|
||||||
if(thiz->ieParseInfo[ieType][ieInstance].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
|
||||||
{
|
|
||||||
if(pMsg->isIeValid[ieType][ieInstance] == NW_FALSE)
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Mandatory IE of type %u and instance %u missing in msg type %u", ieType, ieInstance, pMsg->msgType);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Mandatory IE of type %u and instance %u missing in msg type %u", ieType, ieInstance, pMsg->msgType);
|
||||||
pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING;
|
pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING;
|
||||||
pError->offendingIe.type = ieType;
|
pError->offendingIe.type = ieType;
|
||||||
@@ -715,6 +680,7 @@ nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_CRIT, "Unknown mandatory IE missing. Msg parser formed incorrectly!");
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_CRIT, "Unknown mandatory IE missing. Msg parser formed incorrectly!");
|
||||||
pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING;
|
pError->cause = NW_GTPV2C_CAUSE_MANDATORY_IE_MISSING;
|
||||||
pError->offendingIe.type = 0;
|
pError->offendingIe.type = 0;
|
||||||
@@ -732,6 +698,6 @@ nwGtpv2cMsgIeParse(NW_IN NwGtpv2cMsgIeParseInfoT* thiz,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* E N D O F F I L E *
|
* E N D O F F I L E *
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -44,30 +44,30 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate a gtpv2c message Parser.
|
* Allocate a gtpv2c message Parser.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
||||||
* @param[in] msgType : Message type for this message parser.
|
* @param[in] msgType : Message type for this message parser.
|
||||||
* @param[out] pthiz : Pointer to message parser handle.
|
* @param[out] pthiz : Pointer to message parser handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cMsgParserNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwU8T msgType,
|
NW_IN NwU8T msgType,
|
||||||
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
||||||
NwU8T ieLength,
|
NwU8T ieLength,
|
||||||
NwU8T ieInstance,
|
NwU8T ieInstance,
|
||||||
NwU8T* ieValue,
|
NwU8T* ieValue,
|
||||||
void* ieReadCallbackArg),
|
void* ieReadCallbackArg),
|
||||||
NW_IN void* ieReadCallbackArg,
|
NW_IN void* ieReadCallbackArg,
|
||||||
NW_IN NwGtpv2cMsgParserT **pthiz)
|
NW_IN NwGtpv2cMsgParserT **pthiz)
|
||||||
{
|
{
|
||||||
NwGtpv2cMsgParserT* thiz;
|
NwGtpv2cMsgParserT* thiz;
|
||||||
// NW_GTPV2C_MALLOC(hGtpcStackHandle, sizeof(NwGtpv2cMsgParserT), thiz, NwGtpv2cMsgParserT*);
|
// NW_GTPV2C_MALLOC(hGtpcStackHandle, sizeof(NwGtpv2cMsgParserT), thiz, NwGtpv2cMsgParserT*);
|
||||||
thiz = (NwGtpv2cMsgParserT*) malloc (sizeof(NwGtpv2cMsgParserT));
|
thiz = (NwGtpv2cMsgParserT*) malloc (sizeof(NwGtpv2cMsgParserT));
|
||||||
if(thiz)
|
|
||||||
{
|
if(thiz) {
|
||||||
memset(thiz, 0, sizeof(NwGtpv2cMsgParserT));
|
memset(thiz, 0, sizeof(NwGtpv2cMsgParserT));
|
||||||
thiz->msgType = msgType;
|
thiz->msgType = msgType;
|
||||||
thiz->hStack = hGtpcStackHandle;
|
thiz->hStack = hGtpcStackHandle;
|
||||||
@@ -76,19 +76,20 @@ nwGtpv2cMsgParserNew( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
thiz->ieReadCallbackArg = ieReadCallbackArg;
|
thiz->ieReadCallbackArg = ieReadCallbackArg;
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free a gtpv2c message parser.
|
* Free a gtpv2c message parser.
|
||||||
*
|
*
|
||||||
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
* @param[in] hGtpcStackHandle : gtpv2c stack handle.
|
||||||
* @param[in] thiz : Message parser handle.
|
* @param[in] thiz : Message parser handle.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserDelete( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
nwGtpv2cMsgParserDelete( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
||||||
NW_IN NwGtpv2cMsgParserT* thiz)
|
NW_IN NwGtpv2cMsgParserT* thiz)
|
||||||
{
|
{
|
||||||
NW_GTPV2C_FREE(hGtpcStackHandle, thiz);
|
NW_GTPV2C_FREE(hGtpcStackHandle, thiz);
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
@@ -96,29 +97,29 @@ nwGtpv2cMsgParserDelete( NW_IN NwGtpv2cStackHandleT hGtpcStackHandle,
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserUpdateIeReadCallback( NW_IN NwGtpv2cMsgParserT* thiz,
|
nwGtpv2cMsgParserUpdateIeReadCallback( NW_IN NwGtpv2cMsgParserT* thiz,
|
||||||
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
||||||
NwU8T ieLength,
|
NwU8T ieLength,
|
||||||
NwU8T ieInstance,
|
NwU8T ieInstance,
|
||||||
NwU8T* ieValue,
|
NwU8T* ieValue,
|
||||||
void* ieReadCallbackArg))
|
void* ieReadCallbackArg))
|
||||||
{
|
{
|
||||||
if(thiz)
|
if(thiz) {
|
||||||
{
|
|
||||||
thiz->ieReadCallback = ieReadCallback;
|
thiz->ieReadCallback = ieReadCallback;
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserUpdateIeReadCallbackArg( NW_IN NwGtpv2cMsgParserT* thiz,
|
nwGtpv2cMsgParserUpdateIeReadCallbackArg( NW_IN NwGtpv2cMsgParserT* thiz,
|
||||||
NW_IN void* ieReadCallbackArg)
|
NW_IN void* ieReadCallbackArg)
|
||||||
{
|
{
|
||||||
if(thiz)
|
if(thiz) {
|
||||||
{
|
|
||||||
thiz->ieReadCallbackArg = ieReadCallbackArg;
|
thiz->ieReadCallbackArg = ieReadCallbackArg;
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,29 +128,26 @@ nwGtpv2cMsgParserAddIe( NW_IN NwGtpv2cMsgParserT* thiz,
|
|||||||
NW_IN NwU8T ieType,
|
NW_IN NwU8T ieType,
|
||||||
NW_IN NwU8T ieInstance,
|
NW_IN NwU8T ieInstance,
|
||||||
NW_IN NwU8T iePresence,
|
NW_IN NwU8T iePresence,
|
||||||
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
||||||
NwU8T ieLength,
|
NwU8T ieLength,
|
||||||
NwU8T ieInstance,
|
NwU8T ieInstance,
|
||||||
NwU8T* ieValue,
|
NwU8T* ieValue,
|
||||||
void* ieReadCallbackArg),
|
void* ieReadCallbackArg),
|
||||||
NW_IN void* ieReadCallbackArg)
|
NW_IN void* ieReadCallbackArg)
|
||||||
{
|
{
|
||||||
NW_ASSERT(thiz);
|
NW_ASSERT(thiz);
|
||||||
if(thiz->ieParseInfo[ieType][ieInstance].iePresence == 0)
|
|
||||||
{
|
if(thiz->ieParseInfo[ieType][ieInstance].iePresence == 0) {
|
||||||
NW_ASSERT(ieInstance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
NW_ASSERT(ieInstance <= NW_GTPV2C_IE_INSTANCE_MAXIMUM);
|
||||||
|
|
||||||
thiz->ieParseInfo[ieType][ieInstance].ieReadCallback = ieReadCallback;
|
thiz->ieParseInfo[ieType][ieInstance].ieReadCallback = ieReadCallback;
|
||||||
thiz->ieParseInfo[ieType][ieInstance].ieReadCallbackArg = ieReadCallbackArg;
|
thiz->ieParseInfo[ieType][ieInstance].ieReadCallbackArg = ieReadCallbackArg;
|
||||||
thiz->ieParseInfo[ieType][ieInstance].iePresence = iePresence;
|
thiz->ieParseInfo[ieType][ieInstance].iePresence = iePresence;
|
||||||
|
|
||||||
if (iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
if (iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY) {
|
||||||
{
|
|
||||||
thiz->mandatoryIeCount++;
|
thiz->mandatoryIeCount++;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Cannot add IE to parser for type %u and instance %u. IE info already exists!", ieType, ieInstance);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Cannot add IE to parser for type %u and instance %u. IE info already exists!", ieType, ieInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,26 +156,24 @@ nwGtpv2cMsgParserAddIe( NW_IN NwGtpv2cMsgParserT* thiz,
|
|||||||
|
|
||||||
NwRcT
|
NwRcT
|
||||||
nwGtpv2cMsgParserUpdateIe( NW_IN NwGtpv2cMsgParserT* thiz,
|
nwGtpv2cMsgParserUpdateIe( NW_IN NwGtpv2cMsgParserT* thiz,
|
||||||
NW_IN NwU8T ieType,
|
NW_IN NwU8T ieType,
|
||||||
NW_IN NwU8T ieInstance,
|
NW_IN NwU8T ieInstance,
|
||||||
NW_IN NwU8T iePresence,
|
NW_IN NwU8T iePresence,
|
||||||
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
NW_IN NwRcT (*ieReadCallback) (NwU8T ieType,
|
||||||
NwU8T ieLength,
|
NwU8T ieLength,
|
||||||
NwU8T ieInstance,
|
NwU8T ieInstance,
|
||||||
NwU8T* ieValue,
|
NwU8T* ieValue,
|
||||||
void* ieReadCallbackArg),
|
void* ieReadCallbackArg),
|
||||||
NW_IN void* ieReadCallbackArg)
|
NW_IN void* ieReadCallbackArg)
|
||||||
{
|
{
|
||||||
NW_ASSERT(thiz);
|
NW_ASSERT(thiz);
|
||||||
if(thiz->ieParseInfo[ieType][ieInstance].iePresence)
|
|
||||||
{
|
if(thiz->ieParseInfo[ieType][ieInstance].iePresence) {
|
||||||
thiz->ieParseInfo[ieType][ieInstance].ieReadCallback = ieReadCallback;
|
thiz->ieParseInfo[ieType][ieInstance].ieReadCallback = ieReadCallback;
|
||||||
thiz->ieParseInfo[ieType][ieInstance].ieReadCallbackArg = ieReadCallbackArg;
|
thiz->ieParseInfo[ieType][ieInstance].ieReadCallbackArg = ieReadCallbackArg;
|
||||||
|
|
||||||
thiz->ieParseInfo[ieType][ieInstance].iePresence = iePresence;
|
thiz->ieParseInfo[ieType][ieInstance].iePresence = iePresence;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Cannot update IE info for type %u and instance %u. IE info does not exist!", ieType, ieInstance);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Cannot update IE info for type %u and instance %u. IE info does not exist!", ieType, ieInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -211,86 +207,66 @@ nwGtpv2cMsgParserRun( NW_IN NwGtpv2cMsgParserT *thiz,
|
|||||||
memset(thiz->pIe, 0, sizeof(NwU8T*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
|
memset(thiz->pIe, 0, sizeof(NwU8T*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
|
||||||
memset(pMsg->pIe, 0, sizeof(NwU8T*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
|
memset(pMsg->pIe, 0, sizeof(NwU8T*) * (NW_GTPV2C_IE_TYPE_MAXIMUM) * (NW_GTPV2C_IE_INSTANCE_MAXIMUM));
|
||||||
|
|
||||||
while (pIeStart < pIeEnd)
|
while (pIeStart < pIeEnd) {
|
||||||
{
|
|
||||||
pIe = (NwGtpv2cIeTlvT*) pIeStart;
|
pIe = (NwGtpv2cIeTlvT*) pIeStart;
|
||||||
ieLength = ntohs(pIe->l);
|
ieLength = ntohs(pIe->l);
|
||||||
|
|
||||||
if(pIeStart + 4 + ieLength > pIeEnd)
|
if(pIeStart + 4 + ieLength > pIeEnd) {
|
||||||
{
|
|
||||||
*pOffendingIeType = pIe->t;
|
*pOffendingIeType = pIe->t;
|
||||||
*pOffendingIeLength = pIe->l;
|
*pOffendingIeLength = pIe->l;
|
||||||
*pOffendingIeInstance = pIe->i;
|
*pOffendingIeInstance = pIe->i;
|
||||||
return NW_GTPV2C_MSG_MALFORMED;
|
return NW_GTPV2C_MSG_MALFORMED;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((thiz->ieParseInfo[pIe->t][pIe->i].iePresence))
|
if((thiz->ieParseInfo[pIe->t][pIe->i].iePresence)) {
|
||||||
{
|
|
||||||
thiz->pIe[pIe->t][pIe->i] = (NwU8T*) pIeStart;
|
thiz->pIe[pIe->t][pIe->i] = (NwU8T*) pIeStart;
|
||||||
pMsg->pIe[pIe->t][pIe->i] = (NwU8T*) pIeStart;
|
pMsg->pIe[pIe->t][pIe->i] = (NwU8T*) pIeStart;
|
||||||
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received IE %u of length %u!", pIe->t, ieLength);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received IE %u of length %u!", pIe->t, ieLength);
|
||||||
if((thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallback) != NULL )
|
|
||||||
{
|
if((thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallback) != NULL ) {
|
||||||
rc = thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallback(pIe->t, ieLength, pIe->i, pIeStart + 4, thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallbackArg);
|
rc = thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallback(pIe->t, ieLength, pIe->i, pIeStart + 4, thiz->ieParseInfo[pIe->t][pIe->i].ieReadCallbackArg);
|
||||||
|
|
||||||
if(NW_OK == rc)
|
if(NW_OK == rc) {
|
||||||
{
|
if(thiz->ieParseInfo[pIe->t][pIe->i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
||||||
if(thiz->ieParseInfo[pIe->t][pIe->i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
|
||||||
mandatoryIeCount++;
|
mandatoryIeCount++;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Error while parsing IE %u with instance %u and length %u!", pIe->t, pIe->i, ieLength);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Error while parsing IE %u with instance %u and length %u!", pIe->t, pIe->i, ieLength);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
if((thiz->ieReadCallback) != NULL ) {
|
||||||
{
|
|
||||||
if((thiz->ieReadCallback) != NULL )
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received IE %u of length %u!", pIe->t, ieLength);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_DEBG, "Received IE %u of length %u!", pIe->t, ieLength);
|
||||||
rc = thiz->ieReadCallback(pIe->t, ieLength, pIe->i, pIeStart + 4, thiz->ieReadCallbackArg);
|
rc = thiz->ieReadCallback(pIe->t, ieLength, pIe->i, pIeStart + 4, thiz->ieReadCallbackArg);
|
||||||
|
|
||||||
if(NW_OK == rc)
|
if(NW_OK == rc) {
|
||||||
{
|
if(thiz->ieParseInfo[pIe->t][pIe->i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
||||||
if(thiz->ieParseInfo[pIe->t][pIe->i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
|
||||||
mandatoryIeCount++;
|
mandatoryIeCount++;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Error while parsing IE %u of length %u!", pIe->t, ieLength);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_ERRO, "Error while parsing IE %u of length %u!", pIe->t, ieLength);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "No parse method defined for received IE type %u of length %u in message %u!", pIe->t, ieLength, thiz->msgType);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "No parse method defined for received IE type %u of length %u in message %u!", pIe->t, ieLength, thiz->msgType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "Unexpected IE %u of length %u received in msg %u!", pIe->t, ieLength, thiz->msgType);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "Unexpected IE %u of length %u received in msg %u!", pIe->t, ieLength, thiz->msgType);
|
||||||
}
|
}
|
||||||
|
|
||||||
pIeStart += (ieLength + 4);
|
pIeStart += (ieLength + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
if((NW_OK == rc) && (mandatoryIeCount != thiz->mandatoryIeCount))
|
if((NW_OK == rc) && (mandatoryIeCount != thiz->mandatoryIeCount)) {
|
||||||
{
|
|
||||||
NwU16T t, i;
|
NwU16T t, i;
|
||||||
*pOffendingIeType = 0;
|
*pOffendingIeType = 0;
|
||||||
*pOffendingIeInstance = 0;
|
*pOffendingIeInstance = 0;
|
||||||
*pOffendingIeLength = 0;
|
*pOffendingIeLength = 0;
|
||||||
for(t = 0; t < NW_GTPV2C_IE_TYPE_MAXIMUM; t++)
|
|
||||||
{
|
for(t = 0; t < NW_GTPV2C_IE_TYPE_MAXIMUM; t++) {
|
||||||
for(i = 0; i < NW_GTPV2C_IE_INSTANCE_MAXIMUM; i++)
|
for(i = 0; i < NW_GTPV2C_IE_INSTANCE_MAXIMUM; i++) {
|
||||||
{
|
if(thiz->ieParseInfo[t][i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY) {
|
||||||
if(thiz->ieParseInfo[t][i].iePresence == NW_GTPV2C_IE_PRESENCE_MANDATORY)
|
if(thiz->pIe[t][i] == NULL) {
|
||||||
{
|
|
||||||
if(thiz->pIe[t][i] == NULL)
|
|
||||||
{
|
|
||||||
*pOffendingIeType = t;
|
*pOffendingIeType = t;
|
||||||
*pOffendingIeInstance = i;
|
*pOffendingIeInstance = i;
|
||||||
return NW_GTPV2C_MANDATORY_IE_MISSING;
|
return NW_GTPV2C_MANDATORY_IE_MISSING;
|
||||||
@@ -298,6 +274,7 @@ nwGtpv2cMsgParserRun( NW_IN NwGtpv2cMsgParserT *thiz,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "Unknown mandatory IE missing. Parser formed incorrectly! %u:%u", mandatoryIeCount, thiz->mandatoryIeCount);
|
NW_LOG(thiz->hStack, NW_LOG_LEVEL_WARN, "Unknown mandatory IE missing. Parser formed incorrectly! %u:%u", mandatoryIeCount, thiz->mandatoryIeCount);
|
||||||
return NW_GTPV2C_MANDATORY_IE_MISSING;
|
return NW_GTPV2C_MANDATORY_IE_MISSING;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -69,11 +69,11 @@ nwGtpv2cTrxnSendMsgRetransmission(NwGtpv2cTrxnT* thiz)
|
|||||||
|
|
||||||
NW_ASSERT(thiz->pMsg);
|
NW_ASSERT(thiz->pMsg);
|
||||||
|
|
||||||
rc = thiz->pStack->udp.udpDataReqCallback(thiz->pStack->udp.hUdp,
|
rc = thiz->pStack->udp.udpDataReqCallback(thiz->pStack->udp.hUdp,
|
||||||
thiz->pMsg->msgBuf,
|
thiz->pMsg->msgBuf,
|
||||||
thiz->pMsg->msgLen,
|
thiz->pMsg->msgLen,
|
||||||
thiz->peerIp,
|
thiz->peerIp,
|
||||||
thiz->peerPort);
|
thiz->peerPort);
|
||||||
|
|
||||||
thiz->maxRetries--;
|
thiz->maxRetries--;
|
||||||
|
|
||||||
@@ -97,15 +97,12 @@ nwGtpv2cTrxnPeerRspWaitTimeout(void* arg)
|
|||||||
|
|
||||||
thiz->hRspTmr = 0;
|
thiz->hRspTmr = 0;
|
||||||
|
|
||||||
if(thiz->maxRetries)
|
if(thiz->maxRetries) {
|
||||||
{
|
|
||||||
rc = nwGtpv2cTrxnSendMsgRetransmission(thiz);
|
rc = nwGtpv2cTrxnSendMsgRetransmission(thiz);
|
||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
|
||||||
rc = nwGtpv2cStartTimer(thiz->pStack, thiz->t3Timer, 0, NW_GTPV2C_TMR_TYPE_ONE_SHOT, nwGtpv2cTrxnPeerRspWaitTimeout, thiz, &thiz->hRspTmr);
|
rc = nwGtpv2cStartTimer(thiz->pStack, thiz->t3Timer, 0, NW_GTPV2C_TMR_TYPE_ONE_SHOT, nwGtpv2cTrxnPeerRspWaitTimeout, thiz, &thiz->hRspTmr);
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NwGtpv2cUlpApiT ulpApi;
|
NwGtpv2cUlpApiT ulpApi;
|
||||||
|
|
||||||
ulpApi.hMsg = 0;
|
ulpApi.hMsg = 0;
|
||||||
@@ -121,6 +118,7 @@ nwGtpv2cTrxnPeerRspWaitTimeout(void* arg)
|
|||||||
|
|
||||||
rc = pStack->ulp.ulpReqCallback(pStack->ulp.hUlp, &ulpApi);
|
rc = pStack->ulp.ulpReqCallback(pStack->ulp.hUlp, &ulpApi);
|
||||||
}
|
}
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -152,7 +150,7 @@ nwGtpv2cTrxnDuplicateRequestWaitTimeout(void* arg)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Start timer to wait for rsp of a req message
|
* Start timer to wait for rsp of a req message
|
||||||
*
|
*
|
||||||
* @param[in] thiz : Pointer to transaction
|
* @param[in] thiz : Pointer to transaction
|
||||||
* @param[in] timeoutCallbackFunc : Timeout handler callback function.
|
* @param[in] timeoutCallbackFunc : Timeout handler callback function.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
@@ -210,27 +208,23 @@ nwGtpv2cTrxnStopPeerRspTimer(NwGtpv2cTrxnT* thiz)
|
|||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*
|
*
|
||||||
* @param[in] thiz : Pointer to stack
|
* @param[in] thiz : Pointer to stack
|
||||||
* @param[out] ppTrxn : Pointer to pointer to Trxn object.
|
* @param[out] ppTrxn : Pointer to pointer to Trxn object.
|
||||||
* @return NW_OK on success.
|
* @return NW_OK on success.
|
||||||
*/
|
*/
|
||||||
NwGtpv2cTrxnT*
|
NwGtpv2cTrxnT*
|
||||||
nwGtpv2cTrxnNew( NW_IN NwGtpv2cStackT* thiz)
|
nwGtpv2cTrxnNew( NW_IN NwGtpv2cStackT* thiz)
|
||||||
{
|
{
|
||||||
NwGtpv2cTrxnT *pTrxn;
|
NwGtpv2cTrxnT *pTrxn;
|
||||||
|
|
||||||
if(gpGtpv2cTrxnPool)
|
if(gpGtpv2cTrxnPool) {
|
||||||
{
|
|
||||||
pTrxn = gpGtpv2cTrxnPool;
|
pTrxn = gpGtpv2cTrxnPool;
|
||||||
gpGtpv2cTrxnPool = gpGtpv2cTrxnPool->next;
|
gpGtpv2cTrxnPool = gpGtpv2cTrxnPool->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_GTPV2C_MALLOC(thiz, sizeof(NwGtpv2cTrxnT), pTrxn, NwGtpv2cTrxnT*);
|
NW_GTPV2C_MALLOC(thiz, sizeof(NwGtpv2cTrxnT), pTrxn, NwGtpv2cTrxnT*);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTrxn)
|
if (pTrxn) {
|
||||||
{
|
|
||||||
pTrxn->pStack = thiz;
|
pTrxn->pStack = thiz;
|
||||||
pTrxn->pMsg = NULL;
|
pTrxn->pMsg = NULL;
|
||||||
pTrxn->maxRetries = 2;
|
pTrxn->maxRetries = 2;
|
||||||
@@ -239,6 +233,7 @@ nwGtpv2cTrxnNew( NW_IN NwGtpv2cStackT* thiz)
|
|||||||
|
|
||||||
/* Increment sequence number */
|
/* Increment sequence number */
|
||||||
thiz->seqNum++;
|
thiz->seqNum++;
|
||||||
|
|
||||||
if(thiz->seqNum == 0x800000)
|
if(thiz->seqNum == 0x800000)
|
||||||
thiz->seqNum = 0;
|
thiz->seqNum = 0;
|
||||||
|
|
||||||
@@ -252,28 +247,24 @@ nwGtpv2cTrxnNew( NW_IN NwGtpv2cStackT* thiz)
|
|||||||
/**
|
/**
|
||||||
* Overloaded Constructor
|
* Overloaded Constructor
|
||||||
*
|
*
|
||||||
* @param[in] thiz : Pointer to stack.
|
* @param[in] thiz : Pointer to stack.
|
||||||
* @param[in] seqNum : Sequence number for this transaction.
|
* @param[in] seqNum : Sequence number for this transaction.
|
||||||
* @return Pointer to Trxn object.
|
* @return Pointer to Trxn object.
|
||||||
*/
|
*/
|
||||||
NwGtpv2cTrxnT*
|
NwGtpv2cTrxnT*
|
||||||
nwGtpv2cTrxnWithSeqNumNew( NW_IN NwGtpv2cStackT* thiz,
|
nwGtpv2cTrxnWithSeqNumNew( NW_IN NwGtpv2cStackT* thiz,
|
||||||
NW_IN NwU32T seqNum)
|
NW_IN NwU32T seqNum)
|
||||||
{
|
{
|
||||||
NwGtpv2cTrxnT *pTrxn;
|
NwGtpv2cTrxnT *pTrxn;
|
||||||
|
|
||||||
if(gpGtpv2cTrxnPool)
|
if(gpGtpv2cTrxnPool) {
|
||||||
{
|
|
||||||
pTrxn = gpGtpv2cTrxnPool;
|
pTrxn = gpGtpv2cTrxnPool;
|
||||||
gpGtpv2cTrxnPool = gpGtpv2cTrxnPool->next;
|
gpGtpv2cTrxnPool = gpGtpv2cTrxnPool->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_GTPV2C_MALLOC(thiz, sizeof(NwGtpv2cTrxnT), pTrxn, NwGtpv2cTrxnT*);
|
NW_GTPV2C_MALLOC(thiz, sizeof(NwGtpv2cTrxnT), pTrxn, NwGtpv2cTrxnT*);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTrxn)
|
if (pTrxn) {
|
||||||
{
|
|
||||||
pTrxn->pStack = thiz;
|
pTrxn->pStack = thiz;
|
||||||
pTrxn->pMsg = NULL;
|
pTrxn->pMsg = NULL;
|
||||||
pTrxn->maxRetries = 2;
|
pTrxn->maxRetries = 2;
|
||||||
@@ -288,10 +279,10 @@ nwGtpv2cTrxnWithSeqNumNew( NW_IN NwGtpv2cStackT* thiz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Another overloaded constructor. Create transaction as outstanding
|
* Another overloaded constructor. Create transaction as outstanding
|
||||||
* RX transaction for detecting duplicated requests.
|
* RX transaction for detecting duplicated requests.
|
||||||
*
|
*
|
||||||
* @param[in] thiz : Pointer to stack.
|
* @param[in] thiz : Pointer to stack.
|
||||||
* @param[in] teidLocal : Trxn teid.
|
* @param[in] teidLocal : Trxn teid.
|
||||||
* @param[in] peerIp : Peer Ip address.
|
* @param[in] peerIp : Peer Ip address.
|
||||||
* @param[in] peerPort : Peer Ip port.
|
* @param[in] peerPort : Peer Ip port.
|
||||||
@@ -301,26 +292,22 @@ nwGtpv2cTrxnWithSeqNumNew( NW_IN NwGtpv2cStackT* thiz,
|
|||||||
|
|
||||||
NwGtpv2cTrxnT*
|
NwGtpv2cTrxnT*
|
||||||
nwGtpv2cTrxnOutstandingRxNew( NW_IN NwGtpv2cStackT* thiz,
|
nwGtpv2cTrxnOutstandingRxNew( NW_IN NwGtpv2cStackT* thiz,
|
||||||
NW_IN NwU32T teidLocal,
|
NW_IN NwU32T teidLocal,
|
||||||
NW_IN NwU32T peerIp,
|
NW_IN NwU32T peerIp,
|
||||||
NW_IN NwU32T peerPort,
|
NW_IN NwU32T peerPort,
|
||||||
NW_IN NwU32T seqNum)
|
NW_IN NwU32T seqNum)
|
||||||
{
|
{
|
||||||
NwRcT rc;
|
NwRcT rc;
|
||||||
NwGtpv2cTrxnT *pTrxn, *pCollision;
|
NwGtpv2cTrxnT *pTrxn, *pCollision;
|
||||||
|
|
||||||
if(gpGtpv2cTrxnPool)
|
if(gpGtpv2cTrxnPool) {
|
||||||
{
|
|
||||||
pTrxn = gpGtpv2cTrxnPool;
|
pTrxn = gpGtpv2cTrxnPool;
|
||||||
gpGtpv2cTrxnPool = gpGtpv2cTrxnPool->next;
|
gpGtpv2cTrxnPool = gpGtpv2cTrxnPool->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_GTPV2C_MALLOC(thiz, sizeof(NwGtpv2cTrxnT), pTrxn, NwGtpv2cTrxnT*);
|
NW_GTPV2C_MALLOC(thiz, sizeof(NwGtpv2cTrxnT), pTrxn, NwGtpv2cTrxnT*);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pTrxn)
|
if (pTrxn) {
|
||||||
{
|
|
||||||
pTrxn->pStack = thiz;
|
pTrxn->pStack = thiz;
|
||||||
pTrxn->maxRetries = 2;
|
pTrxn->maxRetries = 2;
|
||||||
pTrxn->t3Timer = 2;
|
pTrxn->t3Timer = 2;
|
||||||
@@ -332,18 +319,17 @@ nwGtpv2cTrxnOutstandingRxNew( NW_IN NwGtpv2cStackT* thiz,
|
|||||||
|
|
||||||
pCollision = RB_INSERT(NwGtpv2cOutstandingRxSeqNumTrxnMap, &(thiz->outstandingRxSeqNumMap), pTrxn);
|
pCollision = RB_INSERT(NwGtpv2cOutstandingRxSeqNumTrxnMap, &(thiz->outstandingRxSeqNumMap), pTrxn);
|
||||||
|
|
||||||
if(pCollision)
|
if(pCollision) {
|
||||||
{
|
|
||||||
NW_LOG(thiz, NW_LOG_LEVEL_WARN, "Duplicate request message received for seq num 0x%x!",
|
NW_LOG(thiz, NW_LOG_LEVEL_WARN, "Duplicate request message received for seq num 0x%x!",
|
||||||
(NwU32T) seqNum);
|
(NwU32T) seqNum);
|
||||||
|
|
||||||
/* Case of duplicate request message from peer. Retransmit response. */
|
/* Case of duplicate request message from peer. Retransmit response. */
|
||||||
if(pCollision->pMsg)
|
if(pCollision->pMsg) {
|
||||||
{
|
rc = pCollision->pStack->udp.udpDataReqCallback(pCollision->pStack->udp.hUdp,
|
||||||
rc = pCollision->pStack->udp.udpDataReqCallback(pCollision->pStack->udp.hUdp,
|
pCollision->pMsg->msgBuf,
|
||||||
pCollision->pMsg->msgBuf,
|
pCollision->pMsg->msgLen,
|
||||||
pCollision->pMsg->msgLen,
|
pCollision->peerIp,
|
||||||
pCollision->peerIp,
|
pCollision->peerPort);
|
||||||
pCollision->peerPort);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = nwGtpv2cTrxnDelete(&pTrxn);
|
rc = nwGtpv2cTrxnDelete(&pTrxn);
|
||||||
@@ -374,14 +360,12 @@ nwGtpv2cTrxnDelete( NW_INOUT NwGtpv2cTrxnT **pthiz)
|
|||||||
|
|
||||||
pStack = thiz->pStack;
|
pStack = thiz->pStack;
|
||||||
|
|
||||||
if(thiz->hRspTmr)
|
if(thiz->hRspTmr) {
|
||||||
{
|
|
||||||
rc = nwGtpv2cTrxnStopPeerRspTimer(thiz);
|
rc = nwGtpv2cTrxnStopPeerRspTimer(thiz);
|
||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thiz->pMsg)
|
if(thiz->pMsg) {
|
||||||
{
|
|
||||||
rc = nwGtpv2cMsgDelete((NwGtpv2cStackHandleT)pStack, (NwGtpv2cMsgHandleT)thiz->pMsg);
|
rc = nwGtpv2cMsgDelete((NwGtpv2cStackHandleT)pStack, (NwGtpv2cMsgHandleT)thiz->pMsg);
|
||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
}
|
}
|
||||||
@@ -400,6 +384,6 @@ nwGtpv2cTrxnDelete( NW_INOUT NwGtpv2cTrxnT **pthiz)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*
|
/*--------------------------------------------------------------------------*
|
||||||
* E N D O F F I L E *
|
* E N D O F F I L E *
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
/*----------------------------------------------------------------------------*
|
/*----------------------------------------------------------------------------*
|
||||||
* *
|
* *
|
||||||
* n w - g t p v 2 c *
|
* n w - g t p v 2 c *
|
||||||
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
* G P R S T u n n e l i n g P r o t o c o l v 2 c S t a c k *
|
||||||
* *
|
* *
|
||||||
* *
|
* *
|
||||||
@@ -52,23 +52,20 @@ nwGtpv2cTunnelNew(struct NwGtpv2cStack *pStack, NwU32T teid, NwU32T ipv4AddrRemo
|
|||||||
{
|
{
|
||||||
NwGtpv2cTunnelT* thiz;
|
NwGtpv2cTunnelT* thiz;
|
||||||
|
|
||||||
if(gpGtpv2cTunnelPool)
|
if(gpGtpv2cTunnelPool) {
|
||||||
{
|
|
||||||
thiz = gpGtpv2cTunnelPool;
|
thiz = gpGtpv2cTunnelPool;
|
||||||
gpGtpv2cTunnelPool = gpGtpv2cTunnelPool->next;
|
gpGtpv2cTunnelPool = gpGtpv2cTunnelPool->next;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
NW_GTPV2C_MALLOC(pStack, sizeof(NwGtpv2cTunnelT), thiz, NwGtpv2cTunnelT*);
|
NW_GTPV2C_MALLOC(pStack, sizeof(NwGtpv2cTunnelT), thiz, NwGtpv2cTunnelT*);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(thiz)
|
if(thiz) {
|
||||||
{
|
|
||||||
memset(thiz, 0, sizeof(NwGtpv2cTunnelT));
|
memset(thiz, 0, sizeof(NwGtpv2cTunnelT));
|
||||||
thiz->teid = teid;
|
thiz->teid = teid;
|
||||||
thiz->ipv4AddrRemote = ipv4AddrRemote;
|
thiz->ipv4AddrRemote = ipv4AddrRemote;
|
||||||
thiz->hUlpTunnel = hUlpTunnel;
|
thiz->hUlpTunnel = hUlpTunnel;
|
||||||
}
|
}
|
||||||
|
|
||||||
return thiz;
|
return thiz;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwEgtPingMain.c
|
* @file NwEgtPingMain.c
|
||||||
* @brief This is a program demostrating usage of nw-gtpv2c library for eGTP ping.
|
* @brief This is a program demostrating usage of nw-gtpv2c library for eGTP ping.
|
||||||
*/
|
*/
|
||||||
@@ -23,14 +23,13 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static
|
static
|
||||||
NwCharT* gLogLevelStr[] = {"EMER", "ALER", "CRIT", "ERRO", "WARN", "NOTI", "INFO", "DEBG"};
|
NwCharT* gLogLevelStr[] = {"EMER", "ALER", "CRIT", "ERRO", "WARN", "NOTI", "INFO", "DEBG"};
|
||||||
|
|
||||||
|
|
||||||
typedef struct NwEgtPingS
|
typedef struct NwEgtPingS {
|
||||||
{
|
|
||||||
NwU8T localIpStr[20];
|
NwU8T localIpStr[20];
|
||||||
NwU8T targetIpStr[20];
|
NwU8T targetIpStr[20];
|
||||||
NwU32T pingInterval;
|
NwU32T pingInterval;
|
||||||
@@ -47,7 +46,8 @@ static NwEgtPingT egtPing;
|
|||||||
void nwEgtPingHandleSignal(int sigNum)
|
void nwEgtPingHandleSignal(int sigNum)
|
||||||
{
|
{
|
||||||
printf("\n--- %s ("NW_IPV4_ADDR") EGTPING statistics --- ", egtPing.targetIpStr, NW_IPV4_ADDR_FORMAT(inet_addr(egtPing.targetIpStr)));
|
printf("\n--- %s ("NW_IPV4_ADDR") EGTPING statistics --- ", egtPing.targetIpStr, NW_IPV4_ADDR_FORMAT(inet_addr(egtPing.targetIpStr)));
|
||||||
printf("\n%u requests sent, %u response received, %d%% packet loss \n\n", udpObj.packetsSent, udpObj.packetsRcvd, (udpObj.packetsSent ? 100 * (udpObj.packetsSent - udpObj.packetsRcvd ) / udpObj.packetsSent : 0) );
|
printf("\n%u requests sent, %u response received, %d%% packet loss \n\n", udpObj.packetsSent, udpObj.packetsRcvd,
|
||||||
|
(udpObj.packetsSent ? 100 * (udpObj.packetsSent - udpObj.packetsRcvd ) / udpObj.packetsSent : 0) );
|
||||||
exit(sigNum);
|
exit(sigNum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,50 +82,45 @@ nwEgtPingParseCmdLineOpts(int argc, char* argv[])
|
|||||||
|
|
||||||
if( (argc == 2) &&
|
if( (argc == 2) &&
|
||||||
((strcmp("--help", argv[i]) == 0)
|
((strcmp("--help", argv[i]) == 0)
|
||||||
|| (strcmp(argv[i], "-h") == 0)))
|
|| (strcmp(argv[i], "-h") == 0)))
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
|
|
||||||
while( i < argc - 1)
|
while( i < argc - 1) {
|
||||||
{
|
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG, "Processing cmdline arg %s", argv[i]);
|
NW_LOG(NW_LOG_LEVEL_DEBG, "Processing cmdline arg %s", argv[i]);
|
||||||
|
|
||||||
if((strcmp("--local-ip", argv[i]) == 0)
|
if((strcmp("--local-ip", argv[i]) == 0)
|
||||||
|| (strcmp(argv[i], "-l") == 0))
|
|| (strcmp(argv[i], "-l") == 0)) {
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(i >= (argc - 1))
|
if(i >= (argc - 1))
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
|
|
||||||
strcpy(egtPing.localIpStr, (argv[i]));
|
strcpy(egtPing.localIpStr, (argv[i]));
|
||||||
|
|
||||||
}
|
} else if((strcmp("--interval", argv[i]) == 0)
|
||||||
else if((strcmp("--interval", argv[i]) == 0)
|
|| (strcmp(argv[i], "-i") == 0)) {
|
||||||
|| (strcmp(argv[i], "-i") == 0))
|
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(i >= (argc - 1))
|
if(i >= (argc - 1))
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
|
|
||||||
egtPing.pingInterval = atoi(argv[i]);
|
egtPing.pingInterval = atoi(argv[i]);
|
||||||
|
|
||||||
}
|
} else if((strcmp("--count", argv[i]) == 0)
|
||||||
else if((strcmp("--count", argv[i]) == 0)
|
|| (strcmp(argv[i], "-c") == 0)) {
|
||||||
|| (strcmp(argv[i], "-c") == 0))
|
|
||||||
{
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
if(i >= (argc - 1))
|
if(i >= (argc - 1))
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
|
|
||||||
egtPing.pingCount = atoi(argv[i]);
|
egtPing.pingCount = atoi(argv[i]);
|
||||||
}
|
} else if((strcmp("--help", argv[i]) == 0)
|
||||||
else if((strcmp("--help", argv[i]) == 0)
|
|| (strcmp(argv[i], "-h") == 0)) {
|
||||||
|| (strcmp(argv[i], "-h") == 0))
|
|
||||||
{
|
|
||||||
rc = NW_FAILURE;
|
rc = NW_FAILURE;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
return NW_FAILURE;
|
return NW_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -135,12 +130,12 @@ nwEgtPingParseCmdLineOpts(int argc, char* argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* T H E M A I N F U N C T I O N
|
* T H E M A I N F U N C T I O N
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
NwRcT rc;
|
NwRcT rc;
|
||||||
NwU32T logLevel;
|
NwU32T logLevel;
|
||||||
NwU8T* logLevelStr;
|
NwU8T* logLevelStr;
|
||||||
|
|
||||||
@@ -154,20 +149,16 @@ int main(int argc, char* argv[])
|
|||||||
printf("EGTPING 0.1, Copyright (C) 2011 Amit Chawre.\n");
|
printf("EGTPING 0.1, Copyright (C) 2011 Amit Chawre.\n");
|
||||||
rc = nwEgtPingParseCmdLineOpts(argc, argv);
|
rc = nwEgtPingParseCmdLineOpts(argc, argv);
|
||||||
|
|
||||||
if(rc != NW_OK)
|
if(rc != NW_OK) {
|
||||||
{
|
|
||||||
rc = nwEgtPingHelp();
|
rc = nwEgtPingHelp();
|
||||||
exit(rc);
|
exit(rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
logLevelStr = getenv ("NW_LOG_LEVEL");
|
logLevelStr = getenv ("NW_LOG_LEVEL");
|
||||||
|
|
||||||
if(logLevelStr == NULL)
|
if(logLevelStr == NULL) {
|
||||||
{
|
|
||||||
logLevel = NW_LOG_LEVEL_INFO;
|
logLevel = NW_LOG_LEVEL_INFO;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
if(strncmp(logLevelStr, "EMER",4) == 0)
|
if(strncmp(logLevelStr, "EMER",4) == 0)
|
||||||
logLevel = NW_LOG_LEVEL_EMER;
|
logLevel = NW_LOG_LEVEL_EMER;
|
||||||
else if(strncmp(logLevelStr, "ALER",4) == 0)
|
else if(strncmp(logLevelStr, "ALER",4) == 0)
|
||||||
@@ -193,7 +184,7 @@ int main(int argc, char* argv[])
|
|||||||
NW_EVT_INIT();
|
NW_EVT_INIT();
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Initialize Log Manager
|
* Initialize Log Manager
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
nwMiniLogMgrInit(nwMiniLogMgrGetInstance(), logLevel);
|
nwMiniLogMgrInit(nwMiniLogMgrGetInstance(), logLevel);
|
||||||
|
|
||||||
@@ -202,8 +193,7 @@ int main(int argc, char* argv[])
|
|||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
rc = nwGtpv2cInitialize(&hGtpv2cStack);
|
rc = nwGtpv2cInitialize(&hGtpv2cStack);
|
||||||
|
|
||||||
if(rc != NW_OK)
|
if(rc != NW_OK) {
|
||||||
{
|
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "Failed to create gtpv2c stack instance. Error '%u' occured", rc);
|
NW_LOG(NW_LOG_LEVEL_ERRO, "Failed to create gtpv2c stack instance. Error '%u' occured", rc);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
@@ -211,7 +201,7 @@ int main(int argc, char* argv[])
|
|||||||
rc = nwGtpv2cSetLogLevel(hGtpv2cStack, logLevel);
|
rc = nwGtpv2cSetLogLevel(hGtpv2cStack, logLevel);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Set up Ulp Entity
|
* Set up Ulp Entity
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
rc = nwGtpv2cUlpInit(&ulpObj, hGtpv2cStack, egtPing.localIpStr);
|
rc = nwGtpv2cUlpInit(&ulpObj, hGtpv2cStack, egtPing.localIpStr);
|
||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
@@ -223,7 +213,7 @@ int main(int argc, char* argv[])
|
|||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Set up Udp Entity
|
* Set up Udp Entity
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
rc = nwGtpv2cUdpInit(&udpObj, hGtpv2cStack, egtPing.localIpStr);
|
rc = nwGtpv2cUdpInit(&udpObj, hGtpv2cStack, egtPing.localIpStr);
|
||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
@@ -235,7 +225,7 @@ int main(int argc, char* argv[])
|
|||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Set up Log Entity
|
* Set up Log Entity
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
tmrMgr.tmrMgrHandle = 0;
|
tmrMgr.tmrMgrHandle = 0;
|
||||||
tmrMgr.tmrStartCallback = nwTimerStart;
|
tmrMgr.tmrStartCallback = nwTimerStart;
|
||||||
@@ -245,7 +235,7 @@ int main(int argc, char* argv[])
|
|||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Set up Log Entity
|
* Set up Log Entity
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
logMgr.logMgrHandle = (NwGtpv2cLogMgrHandleT) nwMiniLogMgrGetInstance();
|
logMgr.logMgrHandle = (NwGtpv2cLogMgrHandleT) nwMiniLogMgrGetInstance();
|
||||||
logMgr.logReqCallback = nwMiniLogMgrLogRequest;
|
logMgr.logReqCallback = nwMiniLogMgrLogRequest;
|
||||||
@@ -257,21 +247,21 @@ int main(int argc, char* argv[])
|
|||||||
* Send Message Request to Gtpv2c Stack Instance
|
* Send Message Request to Gtpv2c Stack Instance
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
NW_LOG(NW_LOG_LEVEL_NOTI, "EGTPING %s ("NW_IPV4_ADDR")", egtPing.targetIpStr, NW_IPV4_ADDR_FORMAT(inet_addr(egtPing.targetIpStr)));
|
NW_LOG(NW_LOG_LEVEL_NOTI, "EGTPING %s ("NW_IPV4_ADDR")", egtPing.targetIpStr, NW_IPV4_ADDR_FORMAT(inet_addr(egtPing.targetIpStr)));
|
||||||
rc = nwGtpv2cUlpPing(&ulpObj,
|
rc = nwGtpv2cUlpPing(&ulpObj,
|
||||||
inet_addr(egtPing.targetIpStr),
|
inet_addr(egtPing.targetIpStr),
|
||||||
egtPing.pingCount,
|
egtPing.pingCount,
|
||||||
egtPing.pingInterval,
|
egtPing.pingInterval,
|
||||||
2,
|
2,
|
||||||
3);
|
3);
|
||||||
NW_ASSERT(NW_OK == rc);
|
NW_ASSERT(NW_OK == rc);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Install signal handler
|
* Install signal handler
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
signal(SIGINT, nwEgtPingHandleSignal);
|
signal(SIGINT, nwEgtPingHandleSignal);
|
||||||
|
|
||||||
/*---------------------------------------------------------------------------
|
/*---------------------------------------------------------------------------
|
||||||
* Event loop
|
* Event loop
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
NW_EVT_LOOP();
|
NW_EVT_LOOP();
|
||||||
@@ -281,8 +271,8 @@ int main(int argc, char* argv[])
|
|||||||
* Destroy Gtpv2c Stack Instance
|
* Destroy Gtpv2c Stack Instance
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
rc = nwGtpv2cFinalize(hGtpv2cStack);
|
rc = nwGtpv2cFinalize(hGtpv2cStack);
|
||||||
if(rc != NW_OK)
|
|
||||||
{
|
if(rc != NW_OK) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "Failed to finalize gtpv2c stack instance. Error '%u' occured", rc);
|
NW_LOG(NW_LOG_LEVEL_ERRO, "Failed to finalize gtpv2c stack instance. Error '%u' occured", rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,9 +29,9 @@
|
|||||||
|
|
||||||
#ifndef __NW_EVT_H__
|
#ifndef __NW_EVT_H__
|
||||||
#define __NW_EVT_H__
|
#define __NW_EVT_H__
|
||||||
/**
|
/**
|
||||||
* @file NwEvt.h
|
* @file NwEvt.h
|
||||||
* @brief
|
* @brief
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef __WITH_LIBEVENT__
|
#ifdef __WITH_LIBEVENT__
|
||||||
@@ -60,9 +60,8 @@ typedef struct event NwEventT;
|
|||||||
|
|
||||||
/* HACK : Defining dummy values for compilation!*/
|
/* HACK : Defining dummy values for compilation!*/
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
int __tbd;
|
||||||
int __tbd;
|
|
||||||
} NwEventT;
|
} NwEventT;
|
||||||
|
|
||||||
#define NW_EVT_READ (0)
|
#define NW_EVT_READ (0)
|
||||||
@@ -71,9 +70,9 @@ typedef struct
|
|||||||
#define NW_TMR_CALLBACK(__cbFunc) __cbFunc(void *arg)
|
#define NW_TMR_CALLBACK(__cbFunc) __cbFunc(void *arg)
|
||||||
|
|
||||||
|
|
||||||
#define NW_EVT_INIT() do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
#define NW_EVT_INIT() do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
||||||
#define NW_EVT_LOOP() do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
#define NW_EVT_LOOP() do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
||||||
#define NW_EVENT_ADD(...) do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
#define NW_EVENT_ADD(...) do { printf("error: Event library not defined!\n"); exit (0); } while(0)
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* *
|
* *
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file hello-world.c
|
* @file hello-world.c
|
||||||
* @brief This file contains example of a minimalistic log manager entity.
|
* @brief This file contains example of a minimalistic log manager entity.
|
||||||
*/
|
*/
|
||||||
@@ -21,7 +21,7 @@
|
|||||||
|
|
||||||
#include "NwMiniLogMgrEntity.h"
|
#include "NwMiniLogMgrEntity.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -52,18 +52,19 @@ NwRcT nwMiniLogMgrSetLogLevel(NwMiniLogMgrT* thiz, NwU32T logLevel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT nwMiniLogMgrLogRequest (NwGtpv2cLogMgrHandleT hLogMgr,
|
NwRcT nwMiniLogMgrLogRequest (NwGtpv2cLogMgrHandleT hLogMgr,
|
||||||
NwU32T logLevel,
|
NwU32T logLevel,
|
||||||
NwCharT* file,
|
NwCharT* file,
|
||||||
NwU32T line,
|
NwU32T line,
|
||||||
NwCharT* logStr)
|
NwCharT* logStr)
|
||||||
{
|
{
|
||||||
NwMiniLogMgrT* thiz = (NwMiniLogMgrT*) hLogMgr;
|
NwMiniLogMgrT* thiz = (NwMiniLogMgrT*) hLogMgr;
|
||||||
|
|
||||||
if(thiz->logLevel >= logLevel)
|
if(thiz->logLevel >= logLevel)
|
||||||
//printf("NWEGTPSTK %s - %s <%s,%u>\n", gLogLevelStr[logLevel], logStr, basename(file), line);
|
//printf("NWEGTPSTK %s - %s <%s,%u>\n", gLogLevelStr[logLevel], logStr, basename(file), line);
|
||||||
return NW_OK;
|
return NW_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* *
|
* *
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file hello-world.c
|
* @file hello-world.c
|
||||||
* @brief This file contains example of a minimalistic log manager entity.
|
* @brief This file contains example of a minimalistic log manager entity.
|
||||||
*/
|
*/
|
||||||
@@ -18,7 +18,7 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __NW_MINI_LOG_MGR_H__
|
#ifndef __NW_MINI_LOG_MGR_H__
|
||||||
#define __NW_MINI_LOG_MGR_H__
|
#define __NW_MINI_LOG_MGR_H__
|
||||||
@@ -33,11 +33,10 @@
|
|||||||
} \
|
} \
|
||||||
} while(0)
|
} while(0)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MiniLogMgr Class Definition
|
* MiniLogMgr Class Definition
|
||||||
*/
|
*/
|
||||||
typedef struct NwMiniLogMgr
|
typedef struct NwMiniLogMgr {
|
||||||
{
|
|
||||||
NwU8T logLevel; /*< Log level */
|
NwU8T logLevel; /*< Log level */
|
||||||
} NwMiniLogMgrT;
|
} NwMiniLogMgrT;
|
||||||
|
|
||||||
@@ -50,27 +49,27 @@ typedef struct NwMiniLogMgr
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get global singleton MiniLogMgr instance
|
* Get global singleton MiniLogMgr instance
|
||||||
*/
|
*/
|
||||||
NwMiniLogMgrT* nwMiniLogMgrGetInstance();
|
NwMiniLogMgrT* nwMiniLogMgrGetInstance();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize MiniLogMgr
|
* Initialize MiniLogMgr
|
||||||
* @param thiz : Pointer to global singleton MiniLogMgr instance
|
* @param thiz : Pointer to global singleton MiniLogMgr instance
|
||||||
* @param logLevel : Log Level
|
* @param logLevel : Log Level
|
||||||
*/
|
*/
|
||||||
NwRcT nwMiniLogMgrInit(NwMiniLogMgrT* thiz, NwU32T logLevel );
|
NwRcT nwMiniLogMgrInit(NwMiniLogMgrT* thiz, NwU32T logLevel );
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set MiniLogMgr log level
|
* Set MiniLogMgr log level
|
||||||
* @param thiz : Pointer to global singleton MiniLogMgr instance
|
* @param thiz : Pointer to global singleton MiniLogMgr instance
|
||||||
* @param logLevel : Log Level
|
* @param logLevel : Log Level
|
||||||
*/
|
*/
|
||||||
NwRcT nwMiniLogMgrSetLogLevel(NwMiniLogMgrT* thiz, NwU32T logLevel);
|
NwRcT nwMiniLogMgrSetLogLevel(NwMiniLogMgrT* thiz, NwU32T logLevel);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Process log request from stack
|
* Process log request from stack
|
||||||
* @param thiz : Pointer to global singleton MiniLogMgr instance
|
* @param thiz : Pointer to global singleton MiniLogMgr instance
|
||||||
* @param logLevel : Log Level
|
* @param logLevel : Log Level
|
||||||
* @param file : Filename
|
* @param file : Filename
|
||||||
@@ -78,12 +77,12 @@ NwRcT nwMiniLogMgrSetLogLevel(NwMiniLogMgrT* thiz, NwU32T logLevel);
|
|||||||
* @param logStr : Log string
|
* @param logStr : Log string
|
||||||
*/
|
*/
|
||||||
NwRcT nwMiniLogMgrLogRequest (NwGtpv2cLogMgrHandleT logMgrHandle,
|
NwRcT nwMiniLogMgrLogRequest (NwGtpv2cLogMgrHandleT logMgrHandle,
|
||||||
NwU32T logLevel,
|
NwU32T logLevel,
|
||||||
NwCharT* file,
|
NwCharT* file,
|
||||||
NwU32T line,
|
NwU32T line,
|
||||||
NwCharT* logStr);
|
NwCharT* logStr);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* *
|
* *
|
||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwMiniTmrMgrEntity.c
|
* @file NwMiniTmrMgrEntity.c
|
||||||
* @brief This file ontains example of a minimalistic timer manager entity.
|
* @brief This file ontains example of a minimalistic timer manager entity.
|
||||||
*/
|
*/
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -55,11 +55,11 @@ NW_TMR_CALLBACK(nwGtpv2cNodeHandleStackTimerTimeout)
|
|||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
NwRcT nwTimerStart( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
NwRcT nwTimerStart( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
||||||
NwU32T timeoutSec,
|
NwU32T timeoutSec,
|
||||||
NwU32T timeoutUsec,
|
NwU32T timeoutUsec,
|
||||||
NwU32T tmrType,
|
NwU32T tmrType,
|
||||||
void* timeoutArg,
|
void* timeoutArg,
|
||||||
NwGtpv2cTimerHandleT* hTmr)
|
NwGtpv2cTimerHandleT* hTmr)
|
||||||
{
|
{
|
||||||
NwRcT rc = NW_OK;
|
NwRcT rc = NW_OK;
|
||||||
NwGtpv2cNodeTmrT *pTmr;
|
NwGtpv2cNodeTmrT *pTmr;
|
||||||
@@ -85,7 +85,7 @@ NwRcT nwTimerStart( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT nwTimerStop( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
NwRcT nwTimerStop( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
||||||
NwGtpv2cTimerHandleT hTmr)
|
NwGtpv2cTimerHandleT hTmr)
|
||||||
{
|
{
|
||||||
evtimer_del(&(((NwGtpv2cNodeTmrT*)hTmr)->ev));
|
evtimer_del(&(((NwGtpv2cNodeTmrT*)hTmr)->ev));
|
||||||
free((void*)hTmr);
|
free((void*)hTmr);
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwMiniTmrMgrEntity.c
|
* @file NwMiniTmrMgrEntity.c
|
||||||
* @brief This file ontains example of a minimalistic timer manager entity.
|
* @brief This file ontains example of a minimalistic timer manager entity.
|
||||||
*/
|
*/
|
||||||
@@ -19,18 +19,16 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __NW_MINI_TMR_MGR_H__
|
#ifndef __NW_MINI_TMR_MGR_H__
|
||||||
#define __NW_MINI_TMR_MGR_H__
|
#define __NW_MINI_TMR_MGR_H__
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwU8T _tbd;
|
NwU8T _tbd;
|
||||||
} NwGtpv2cNodeTmrMgrT;
|
} NwGtpv2cNodeTmrMgrT;
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwEventT ev;
|
NwEventT ev;
|
||||||
void* timeoutArg;
|
void* timeoutArg;
|
||||||
} NwGtpv2cNodeTmrT;
|
} NwGtpv2cNodeTmrT;
|
||||||
@@ -41,15 +39,15 @@ extern "C" {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
NwRcT nwTimerStart( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
NwRcT nwTimerStart( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
||||||
NwU32T timeoutSec,
|
NwU32T timeoutSec,
|
||||||
NwU32T timeoutUsec,
|
NwU32T timeoutUsec,
|
||||||
NwU32T tmrType,
|
NwU32T tmrType,
|
||||||
void* timeoutArg,
|
void* timeoutArg,
|
||||||
NwGtpv2cTimerHandleT* hTmr);
|
NwGtpv2cTimerHandleT* hTmr);
|
||||||
|
|
||||||
|
|
||||||
NwRcT nwTimerStop( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
NwRcT nwTimerStop( NwGtpv2cTimerMgrHandleT tmrMgrHandle,
|
||||||
NwGtpv2cTimerHandleT hTmr);
|
NwGtpv2cTimerHandleT hTmr);
|
||||||
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwMiniUdpEntity.c
|
* @file NwMiniUdpEntity.c
|
||||||
* @brief This file contains example of a minimalistic ULP entity.
|
* @brief This file contains example of a minimalistic ULP entity.
|
||||||
*/
|
*/
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define MAX_UDP_PAYLOAD_LEN (4096)
|
#define MAX_UDP_PAYLOAD_LEN (4096)
|
||||||
|
|
||||||
@@ -56,39 +56,38 @@ void NW_EVT_CALLBACK(nwUdpDataIndicationCallbackData)
|
|||||||
peerLen = sizeof(peer);
|
peerLen = sizeof(peer);
|
||||||
|
|
||||||
bytesRead = recvfrom(fd, udpBuf, MAX_UDP_PAYLOAD_LEN , 0, (struct sockaddr *) &peer,(socklen_t*) &peerLen);
|
bytesRead = recvfrom(fd, udpBuf, MAX_UDP_PAYLOAD_LEN , 0, (struct sockaddr *) &peer,(socklen_t*) &peerLen);
|
||||||
if(bytesRead > 0)
|
|
||||||
{
|
if(bytesRead > 0) {
|
||||||
thiz->packetsRcvd++;
|
thiz->packetsRcvd++;
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG, "Received UDP message of size %u from peer %u.%u.%u.%u:%u", bytesRead,
|
NW_LOG(NW_LOG_LEVEL_DEBG, "Received UDP message of size %u from peer %u.%u.%u.%u:%u", bytesRead,
|
||||||
(peer.sin_addr.s_addr & 0x000000ff),
|
(peer.sin_addr.s_addr & 0x000000ff),
|
||||||
(peer.sin_addr.s_addr & 0x0000ff00) >> 8,
|
(peer.sin_addr.s_addr & 0x0000ff00) >> 8,
|
||||||
(peer.sin_addr.s_addr & 0x00ff0000) >> 16,
|
(peer.sin_addr.s_addr & 0x00ff0000) >> 16,
|
||||||
(peer.sin_addr.s_addr & 0xff000000) >> 24,
|
(peer.sin_addr.s_addr & 0xff000000) >> 24,
|
||||||
ntohs(peer.sin_port));
|
ntohs(peer.sin_port));
|
||||||
rc = nwGtpv2cProcessUdpReq(thiz->hGtpv2cStack, udpBuf, bytesRead, ntohs(peer.sin_port), ntohl(peer.sin_addr.s_addr));
|
rc = nwGtpv2cProcessUdpReq(thiz->hGtpv2cStack, udpBuf, bytesRead, ntohs(peer.sin_port), ntohl(peer.sin_addr.s_addr));
|
||||||
}
|
} else {
|
||||||
else
|
switch (errno) {
|
||||||
{
|
|
||||||
switch (errno)
|
|
||||||
{
|
|
||||||
|
|
||||||
case ENETUNREACH:
|
case ENETUNREACH:
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "Network not reachable", errno, strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "Network not reachable", errno, strerror(errno));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EHOSTUNREACH:
|
case EHOSTUNREACH:
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "Host not reachable", errno, strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "Host not reachable", errno, strerror(errno));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ECONNREFUSED:
|
case ECONNREFUSED:
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "Port not reachable", errno, strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "Port not reachable", errno, strerror(errno));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
nwGtpv2cUdpReset(thiz);
|
nwGtpv2cUdpReset(thiz);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,15 +96,14 @@ void NW_EVT_CALLBACK(nwUdpDataIndicationCallbackData)
|
|||||||
* Public functions
|
* Public functions
|
||||||
*--------------------------------------------------------------------------*/
|
*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
NwRcT nwGtpv2cUdpInit(NwGtpv2cNodeUdpT* thiz, NwGtpv2cStackHandleT hGtpv2cStack, NwU8T* ipAddrStr)
|
NwRcT nwGtpv2cUdpInit(NwGtpv2cNodeUdpT* thiz, NwGtpv2cStackHandleT hGtpv2cStack, NwU8T* ipAddrStr)
|
||||||
{
|
{
|
||||||
int sd;
|
int sd;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
|
|
||||||
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (sd < 0)
|
if (sd < 0) {
|
||||||
{
|
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
@@ -115,15 +113,14 @@ NwRcT nwGtpv2cUdpInit(NwGtpv2cNodeUdpT* thiz, NwGtpv2cStackHandleT hGtpv2cStack,
|
|||||||
addr.sin_addr.s_addr = (strlen(ipAddrStr) ? inet_addr(ipAddrStr) : INADDR_ANY);
|
addr.sin_addr.s_addr = (strlen(ipAddrStr) ? inet_addr(ipAddrStr) : INADDR_ANY);
|
||||||
memset(addr.sin_zero, '\0', sizeof (addr.sin_zero));
|
memset(addr.sin_zero, '\0', sizeof (addr.sin_zero));
|
||||||
|
|
||||||
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
{
|
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "Error - %s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "Error - %s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
yes = 1;
|
yes = 1;
|
||||||
if (setsockopt(sd, SOL_IP, IP_RECVERR, &yes, sizeof(yes)))
|
|
||||||
{
|
if (setsockopt(sd, SOL_IP, IP_RECVERR, &yes, sizeof(yes))) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
@@ -152,8 +149,7 @@ NwRcT nwGtpv2cUdpReset(NwGtpv2cNodeUdpT* thiz)
|
|||||||
|
|
||||||
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
sd = socket(AF_INET, SOCK_DGRAM, 0);
|
||||||
|
|
||||||
if (sd < 0)
|
if (sd < 0) {
|
||||||
{
|
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
@@ -163,15 +159,14 @@ NwRcT nwGtpv2cUdpReset(NwGtpv2cNodeUdpT* thiz)
|
|||||||
addr.sin_addr.s_addr = (thiz->ipv4Addr);
|
addr.sin_addr.s_addr = (thiz->ipv4Addr);
|
||||||
memset(addr.sin_zero, '\0', sizeof (addr.sin_zero));
|
memset(addr.sin_zero, '\0', sizeof (addr.sin_zero));
|
||||||
|
|
||||||
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
if(bind(sd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
|
||||||
{
|
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
yes = 1;
|
yes = 1;
|
||||||
if (setsockopt(sd, SOL_IP, IP_RECVERR, &yes, sizeof(yes)))
|
|
||||||
{
|
if (setsockopt(sd, SOL_IP, IP_RECVERR, &yes, sizeof(yes))) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "%s", strerror(errno));
|
||||||
NW_ASSERT(0);
|
NW_ASSERT(0);
|
||||||
}
|
}
|
||||||
@@ -184,21 +179,21 @@ NwRcT nwGtpv2cUdpReset(NwGtpv2cNodeUdpT* thiz)
|
|||||||
}
|
}
|
||||||
|
|
||||||
NwRcT nwGtpv2cUdpDataReq(NwGtpv2cUdpHandleT udpHandle,
|
NwRcT nwGtpv2cUdpDataReq(NwGtpv2cUdpHandleT udpHandle,
|
||||||
NwU8T* dataBuf,
|
NwU8T* dataBuf,
|
||||||
NwU32T dataSize,
|
NwU32T dataSize,
|
||||||
NwU32T peerIp,
|
NwU32T peerIp,
|
||||||
NwU32T peerPort)
|
NwU32T peerPort)
|
||||||
{
|
{
|
||||||
struct sockaddr_in peerAddr;
|
struct sockaddr_in peerAddr;
|
||||||
NwS32T bytesSent;
|
NwS32T bytesSent;
|
||||||
NwGtpv2cNodeUdpT* thiz = (NwGtpv2cNodeUdpT*) udpHandle;
|
NwGtpv2cNodeUdpT* thiz = (NwGtpv2cNodeUdpT*) udpHandle;
|
||||||
|
|
||||||
NW_LOG(NW_LOG_LEVEL_DEBG, "Sending %u bytes of data to %u.%u.%u.%u:%u", dataSize,
|
NW_LOG(NW_LOG_LEVEL_DEBG, "Sending %u bytes of data to %u.%u.%u.%u:%u", dataSize,
|
||||||
(peerIp & 0xff000000) >> 24,
|
(peerIp & 0xff000000) >> 24,
|
||||||
(peerIp & 0x00ff0000) >> 16,
|
(peerIp & 0x00ff0000) >> 16,
|
||||||
(peerIp & 0x0000ff00) >> 8,
|
(peerIp & 0x0000ff00) >> 8,
|
||||||
(peerIp & 0x000000ff),
|
(peerIp & 0x000000ff),
|
||||||
peerPort);
|
peerPort);
|
||||||
|
|
||||||
peerAddr.sin_family = AF_INET;
|
peerAddr.sin_family = AF_INET;
|
||||||
peerAddr.sin_port = htons(peerPort);
|
peerAddr.sin_port = htons(peerPort);
|
||||||
@@ -206,12 +201,10 @@ NwRcT nwGtpv2cUdpDataReq(NwGtpv2cUdpHandleT udpHandle,
|
|||||||
memset(peerAddr.sin_zero, '\0', sizeof (peerAddr.sin_zero));
|
memset(peerAddr.sin_zero, '\0', sizeof (peerAddr.sin_zero));
|
||||||
|
|
||||||
bytesSent = sendto (thiz->hSocket, dataBuf, dataSize, 0, (struct sockaddr *) &peerAddr, sizeof(peerAddr));
|
bytesSent = sendto (thiz->hSocket, dataBuf, dataSize, 0, (struct sockaddr *) &peerAddr, sizeof(peerAddr));
|
||||||
if(bytesSent < 0)
|
|
||||||
{
|
if(bytesSent < 0) {
|
||||||
NW_LOG(NW_LOG_LEVEL_ERRO, "sendto - %s", strerror(errno));
|
NW_LOG(NW_LOG_LEVEL_ERRO, "sendto - %s", strerror(errno));
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
thiz->packetsSent++;
|
thiz->packetsSent++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
*----------------------------------------------------------------------------*/
|
*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file NwMiniUdpEntity.c
|
* @file NwMiniUdpEntity.c
|
||||||
* @brief This file contains example of a minimalistic ULP entity.
|
* @brief This file contains example of a minimalistic ULP entity.
|
||||||
*/
|
*/
|
||||||
@@ -19,13 +19,12 @@
|
|||||||
|
|
||||||
#ifndef NW_ASSERT
|
#ifndef NW_ASSERT
|
||||||
#define NW_ASSERT assert
|
#define NW_ASSERT assert
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef __NW_MINI_UDP_ENTITY_H__
|
#ifndef __NW_MINI_UDP_ENTITY_H__
|
||||||
#define __NW_MINI_UDP_ENTITY_H__
|
#define __NW_MINI_UDP_ENTITY_H__
|
||||||
|
|
||||||
typedef struct
|
typedef struct {
|
||||||
{
|
|
||||||
NwU32T ipv4Addr;
|
NwU32T ipv4Addr;
|
||||||
NwU32T hSocket;
|
NwU32T hSocket;
|
||||||
NwEventT ev;
|
NwEventT ev;
|
||||||
@@ -43,10 +42,10 @@ NwRcT nwGtpv2cUdpInit(NwGtpv2cNodeUdpT* thiz, NwGtpv2cStackHandleT hGtpv2cStack,
|
|||||||
NwRcT nwGtpv2cUdpDestroy(NwGtpv2cNodeUdpT* thiz);
|
NwRcT nwGtpv2cUdpDestroy(NwGtpv2cNodeUdpT* thiz);
|
||||||
|
|
||||||
NwRcT nwGtpv2cUdpDataReq(NwGtpv2cUdpHandleT udpHandle,
|
NwRcT nwGtpv2cUdpDataReq(NwGtpv2cUdpHandleT udpHandle,
|
||||||
NwU8T* dataBuf,
|
NwU8T* dataBuf,
|
||||||
NwU32T dataSize,
|
NwU32T dataSize,
|
||||||
NwU32T peerIp,
|
NwU32T peerIp,
|
||||||
NwU32T peerPort);
|
NwU32T peerPort);
|
||||||
|
|
||||||
NwRcT nwGtpv2cUdpReset(NwGtpv2cNodeUdpT* thiz);
|
NwRcT nwGtpv2cUdpReset(NwGtpv2cNodeUdpT* thiz);
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user