Files
openairinterface5g/openair3/NAS/UE/UEprocess.c
T
Robert Schmidt 0b91791f67 Use (std) bool instead of custom bool types
OAI is riddled with boolean_t, FALSE, TRUE, etc. This makes no sense, as
there is a standard bool type, and could lead to nasty bugs if a
definition of a bool is non-standard (0 == false, true == !false). This
commit removes all non-standard bools in the whole project.
2022-06-27 10:07:48 +02:00

409 lines
15 KiB
C

/*
* Licensed to the OpenAirInterface (OAI) Software Alliance under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The OpenAirInterface Software Alliance licenses this file to You under
* the OAI Public License, Version 1.1 (the "License"); you may not use this file
* except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.openairinterface.org/?page_id=698
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*-------------------------------------------------------------------------------
* For more information about the OpenAirInterface (OAI) Software Alliance:
* contact@openairinterface.org
*/
/*****************************************************************************
Source UEprocess.c
Version 0.1
Date 2012/02/27
Product NAS stack
Subsystem UE NAS main process
Author Frederic Maurel
Description Implements the Non-Access Stratum protocol for Evolved Packet
system (EPS) running at the User Equipment side.
*****************************************************************************/
#include "commonDef.h"
#include "nas_log.h"
#include "nas_timer.h"
#include "user_api.h"
#include "network_api.h"
#include "nas_user.h"
#include "nas_network.h"
#include "nas_parser.h"
#include "user_defs.h"
#include <stdlib.h> // exit
#include <poll.h> // poll
#include <string.h> // memset
#include <signal.h> // sigaction
#include <pthread.h>
/****************************************************************************/
/**************** E X T E R N A L D E F I N I T I O N S ****************/
/****************************************************************************/
/****************************************************************************/
/******************* L O C A L D E F I N I T I O N S *******************/
/****************************************************************************/
#define NAS_SLEEP_TIMEOUT 1000 /* 1 second */
static void *_nas_user_mngr(void *);
static void *_nas_network_mngr(void *);
static int _nas_set_signal_handler(int signal, void (handler)(int));
static void _nas_signal_handler(int signal);
static void _nas_clean(user_api_id_t *user_api_id, int net_fd);
uint8_t usim_test = 0;
// FIXME user must be set up with right itti message instance
// FIXME allocate user and initialize its fields
nas_user_t *user = NULL;
/****************************************************************************/
/****************** E X P O R T E D F U N C T I O N S ******************/
/****************************************************************************/
/****************************************************************************/
int main(int argc, const char *argv[])
{
// FIXME allocate and put it in user
user_api_id_t *user_api_id = NULL;
/*
* Get the command line options
*/
if (nas_parser_get_options (argc, argv) != RETURNok) {
nas_parser_print_usage (FIRMWARE_VERSION);
exit (EXIT_FAILURE);
}
/*
* Initialize logging trace utility
*/
nas_log_init (nas_parser_get_trace_level ());
const char *uhost = nas_parser_get_user_host ();
const char *uport = nas_parser_get_user_port ();
const char *devpath = nas_parser_get_device_path ();
const char *devparams = nas_parser_get_device_params ();
const char *nhost = nas_parser_get_network_host ();
const char *nport = nas_parser_get_network_port ();
LOG_TRACE (INFO,
"UE-MAIN - %s -ueid %d -uhost %s -uport %s -nhost %s -nport %s -dev %s -params %s -trace 0x%x",
argv[0], nas_parser_get_ueid (), uhost, uport, nhost, nport, devpath, devparams,
nas_parser_get_trace_level ());
/*
* Initialize the User interface
*/
if (user_api_initialize (user_api_id, uhost, uport, devpath, devparams) != RETURNok) {
LOG_TRACE (ERROR, "UE-MAIN - user_api_initialize() failed");
exit (EXIT_FAILURE);
}
int user_fd = user_api_get_fd (user_api_id);
/*
* Initialize the Network interface
*/
if (network_api_initialize (nhost, nport) != RETURNok) {
LOG_TRACE (ERROR, "UE-MAIN - network_api_initialize() failed");
user_api_close (user_api_id);
exit (EXIT_FAILURE);
}
int network_fd = network_api_get_fd ();
/*
* Initialize the NAS contexts
*/
nas_user_initialize (user, &user_api_emm_callback, &user_api_esm_callback,
FIRMWARE_VERSION);
nas_network_initialize ();
/*
* Initialize NAS timer handlers
*/
nas_timer_init ();
/*
* Set up signal handlers
*/
(void) _nas_set_signal_handler (SIGINT, _nas_signal_handler);
(void) _nas_set_signal_handler (SIGTERM, _nas_signal_handler);
/*
* Start thread use to manage the user connection endpoint
*/
pthread_t user_mngr;
threadCreate (&user_mngr, , _nas_user_mngr, &user_fd, "UE-nas", -1, OAI_PRIORITY_RT_LOW) ;
/*
* Start thread use to manage the network connection endpoint
*/
pthread_t network_mngr;
threadCreate (&network_mngr, _nas_network_mngr,
&network_fd, "UE-nas-mgr", -1, OAI_PRIORITY_RT_LOW) ;
/*
* Suspend execution of the main process until all connection
* endpoints are still active
*/
while ((user_fd != -1) && (network_fd != -1)) {
poll (NULL, 0, NAS_SLEEP_TIMEOUT);
user_fd = user_api_get_fd (user_api_id);
network_fd = network_api_get_fd ();
}
/* Termination cleanup */
_nas_clean (user_api_id, network_fd);
LOG_TRACE
(WARNING, "UE-MAIN - NAS main process exited");
}
/****************************************************************************/
/********************* L O C A L F U N C T I O N S *********************/
/****************************************************************************/
/****************************************************************************
** **
** Name: _nas_user_mngr() **
** **
** Description: Manages the connection endpoint use to communicate with **
** the user application layer **
** **
** Inputs: fd: The descriptor of the user connection end-point **
** Others: None **
** **
** Outputs: Return: None **
** Others: None **
** **
***************************************************************************/
static void *_nas_user_mngr(void *args)
{
LOG_FUNC_IN;
pthread_setname_np( pthread_self(), "nas_user_mngr");
bool exit_loop = false;
int *fd = (int *) args;
LOG_TRACE (INFO, "UE-MAIN - User connection manager started (%d)", *fd);
/* User receiving loop */
while (!exit_loop) {
exit_loop = nas_user_receive_and_process(user, NULL);
}
/* Close the connection to the user application layer */
user_api_close (user->user_api_id);
LOG_TRACE (WARNING, "UE-MAIN - "
"The user connection endpoint manager exited");
LOG_FUNC_RETURN(NULL);
}
/****************************************************************************
** **
** Name: _nas_network_mngr() **
** **
** Description: Manages the connection endpoint use to communicate with **
** the network sublayer **
** **
** Inputs: fd: The descriptor of the network connection endpoint **
** Others: None **
** **
** Outputs: Return: None **
** Others: None **
** **
***************************************************************************/
static void *_nas_network_mngr(void *args)
{
LOG_FUNC_IN;
int ret_code;
int network_message_id;
int bytes;
int *fd = (int *) args;
LOG_TRACE (INFO, "UE-MAIN - Network connection manager started (%d)", *fd);
/* Network receiving loop */
while (true) {
/* Read the network data message */
bytes = network_api_read_data (*fd);
if (bytes == RETURNerror) {
/* Failed to read data from the network sublayer;
* exit from the receiving loop */
LOG_TRACE (ERROR, "UE-MAIN - "
"Failed to read data from the network sublayer");
break;
}
if (bytes == 0) {
/* A signal was caught before any data were available */
continue;
}
/* Decode the network data message */
network_message_id = network_api_decode_data (bytes);
if (network_message_id == RETURNerror) {
/* Failed to decode data read from the network sublayer */
continue;
}
/* Process the network data message */
ret_code = nas_network_process_data (user, network_message_id,
network_api_get_data ());
if (ret_code != RETURNok) {
/* The network data message has not been successfully
* processed */
LOG_TRACE
(WARNING, "UE-MAIN - "
"The network procedure call 0x%x failed",
network_message_id);
}
}
/* Close the connection to the network sublayer */
network_api_close (*fd);
LOG_TRACE (WARNING, "UE-MAIN - "
"The network connection endpoint manager exited");
LOG_FUNC_RETURN(NULL);
}
/****************************************************************************
** **
** Name: _nas_set_signal_handler() **
** **
** Description: Set up a signal handler **
** **
** Inputs: signal: Signal number **
** handler: Signal handler **
** Others: None **
** **
** Outputs: Return: RETURNerror, RETURNok **
** Others: None **
** **
***************************************************************************/
static int _nas_set_signal_handler(int signal, void (handler)(int))
{
LOG_FUNC_IN;
struct sigaction act;
/* Initialize signal set */
(void) memset (&act, 0, sizeof(act));
(void) sigfillset (&act.sa_mask);
(void) sigdelset (&act.sa_mask, SIGHUP);
(void) sigdelset (&act.sa_mask, SIGINT);
(void) sigdelset (&act.sa_mask, SIGTERM);
(void) sigdelset (&act.sa_mask, SIGILL);
(void) sigdelset (&act.sa_mask, SIGTRAP);
(void) sigdelset (&act.sa_mask, SIGIOT);
#ifndef LINUX
(void) sigdelset (&act.sa_mask, SIGEMT);
#endif
(void) sigdelset (&act.sa_mask, SIGFPE);
(void) sigdelset (&act.sa_mask, SIGBUS);
(void) sigdelset (&act.sa_mask, SIGSEGV);
(void) sigdelset (&act.sa_mask, SIGSYS);
/* Initialize signal handler */
act.sa_handler = handler;
if (sigaction (signal, &act, 0) < 0) {
return RETURNerror;
}
LOG_TRACE (INFO, "UE-MAIN - Handler successfully set for signal %d", signal);
LOG_FUNC_RETURN(RETURNok);
}
/****************************************************************************
** **
** Name: _nas_signal_handler() **
** **
** Description: Signal handler **
** **
** Inputs: signal: Signal number **
** Others: None **
** **
** Outputs: Return: None **
** Others: None **
** **
***************************************************************************/
static void _nas_signal_handler(int signal)
{
LOG_FUNC_IN;
LOG_TRACE (WARNING, "UE-MAIN - Signal %d received", signal);
// FIXME acces to global
_nas_clean (user->user_api_id, network_api_get_fd ());
exit (EXIT_SUCCESS);
LOG_FUNC_OUT
;
}
/****************************************************************************
** **
** Name: _nas_clean() **
** **
** Description: Performs termination cleanup **
** **
** Inputs: usr_fd: User's connection file descriptor **
** net_fd: Network's connection file descriptor **
** Others: None **
** **
** Outputs: Return: None **
** Others: None **
** **
***************************************************************************/
static void _nas_clean(user_api_id_t *user_api_id, int net_fd)
{
LOG_FUNC_IN;
LOG_TRACE (INFO, "UE-MAIN - Perform EMM and ESM cleanup");
// FIXME nas_network_cleanup depends on nas_user_t
// Why this program should interfere like that with oaisim ?
//nas_network_cleanup ();
LOG_TRACE (INFO, "UE-MAIN - "
"Closing user connection %d and network connection %d",
user_api_get_fd (user_api_id), net_fd);
user_api_close (user_api_id);
network_api_close (net_fd);
LOG_FUNC_OUT
;
}