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.
675 lines
21 KiB
C
675 lines
21 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
|
|
*/
|
|
|
|
/*****************************************************************************
|
|
Eurecom OpenAirInterface 3
|
|
Copyright(c) 2012 Eurecom
|
|
|
|
Source as_simulator.c
|
|
|
|
Version 0.1
|
|
|
|
Date 2013/04/11
|
|
|
|
Product Access-Stratum sublayer simulator
|
|
|
|
Subsystem Main process
|
|
|
|
Author Frederic Maurel
|
|
|
|
Description Implements the Access-Stratum simulator operating between
|
|
the Non-Access-Stratum running in the UE at the user side
|
|
and the Non-Access-Stratum running in the MME at the network
|
|
side for testing purpose.
|
|
|
|
*****************************************************************************/
|
|
|
|
#include "as_simulator_parser.h"
|
|
|
|
#include "as_data.h"
|
|
#include "as_process.h"
|
|
|
|
#include "commonDef.h"
|
|
#include "socket.h"
|
|
|
|
#include "nas_log.h"
|
|
|
|
#include <stdio.h> // printf, perror, snprintf
|
|
#include <errno.h> // errno
|
|
#include <netdb.h> // gai_strerror
|
|
#include <stdlib.h> // exit
|
|
#include <string.h> // memset
|
|
#include <poll.h> // poll
|
|
#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 SLEEP_TIMEOUT 1000 /* 1 second */
|
|
|
|
#define AS_SIMULATOR_NO_TRANSFER (0)
|
|
#define AS_SIMULATOR_TRANSFER_TO_UE (1 << 0)
|
|
#define AS_SIMULATOR_TRANSFER_TO_MME (1 << 1)
|
|
|
|
/*
|
|
* Direction of the message to be transfered to the UE NAS process
|
|
*/
|
|
static uint8_t _as_simulator_ue_transfer = AS_SIMULATOR_NO_TRANSFER;
|
|
|
|
/*
|
|
* Direction of the message to be transfered to the MME NAS process
|
|
*/
|
|
static uint8_t _as_simulator_mme_transfer = AS_SIMULATOR_NO_TRANSFER;
|
|
|
|
/*
|
|
* Size of the message to be transfered to the UE NAS process
|
|
*/
|
|
static int _as_simulator_ue_size = 0;
|
|
|
|
/*
|
|
* Size of the message to be transfered to the MME NAS process
|
|
*/
|
|
static int _as_simulator_mme_size = 0;
|
|
|
|
/*
|
|
* String buffer used to send/receive messages to/from the UE NAS process
|
|
*/
|
|
#define AS_SIMULATOR_UE_BUFFER_SIZE 1024
|
|
static char _as_simulator_ue_buffer [AS_SIMULATOR_UE_BUFFER_SIZE];
|
|
|
|
/*
|
|
* String buffer used to send/receive messages to/from the MME NAS process
|
|
*/
|
|
#define AS_SIMULATOR_MME_BUFFER_SIZE 1024
|
|
static char _as_simulator_mme_buffer [AS_SIMULATOR_MME_BUFFER_SIZE];
|
|
|
|
/*
|
|
* The connection endpoint used for communication with the UE NAS process
|
|
*/
|
|
static socket_id_t * _as_simulator_ue_sid = NULL;
|
|
|
|
/*
|
|
* The connection endpoint used for communication with the MME NAS process
|
|
*/
|
|
static socket_id_t * _as_simulator_mme_sid = NULL;
|
|
|
|
/*
|
|
* UE NAS process connection manager's running indicator
|
|
*/
|
|
static bool _as_simulator_ue_is_running = false;
|
|
|
|
/*
|
|
* MME NAS process connection manager's running indicator
|
|
*/
|
|
static bool _as_simulator_mme_is_running = false;
|
|
|
|
static int _set_signal_handler(int signal, void (handler)(int));
|
|
static void _signal_handler(int signal_number);
|
|
|
|
static void* _as_simulator_ue_mngr(void*);
|
|
static void* _as_simulator_mme_mngr(void*);
|
|
|
|
static int _as_simulator_ue_process(int msg_id, as_message_t* msg);
|
|
static int _as_simulator_mme_process(int msg_id, as_message_t* msg);
|
|
|
|
/****************************************************************************/
|
|
/****************** E X P O R T E D F U N C T I O N S ******************/
|
|
/****************************************************************************/
|
|
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* RRC simulator main process
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
int main (int argc, const char* argv[])
|
|
{
|
|
/*
|
|
* Get the command line options
|
|
*/
|
|
if ( as_simulator_parser_get_options(argc, argv) != RETURNok ) {
|
|
as_simulator_parser_print_usage();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
const char* uhost = as_simulator_parser_get_uhost();
|
|
const char* uport = as_simulator_parser_get_uport();
|
|
const char* mhost = as_simulator_parser_get_mhost();
|
|
const char* mport = as_simulator_parser_get_mport();
|
|
|
|
nas_log_init(0x2f);
|
|
|
|
/*
|
|
* Initialize the communication channel to the UE NAS process
|
|
*/
|
|
_as_simulator_ue_sid = socket_udp_open(SOCKET_SERVER, uhost, uport);
|
|
|
|
if (_as_simulator_ue_sid == NULL) {
|
|
const char* error = ( (errno < 0) ?
|
|
gai_strerror(errno) : strerror(errno) );
|
|
printf("ERROR\t: socket_udp_open() failed: %s\n", error);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
printf("INFO\t: %s - The RRC Simulator is now connected to %s/%s (%d)\n",
|
|
__FUNCTION__, uhost, uport, socket_get_fd(_as_simulator_ue_sid));
|
|
|
|
/*
|
|
* Initialize the communication channel to the MME NAS process
|
|
*/
|
|
_as_simulator_mme_sid = socket_udp_open(SOCKET_CLIENT, mhost, mport);
|
|
|
|
if (_as_simulator_mme_sid == NULL) {
|
|
const char* error = ( (errno < 0) ?
|
|
gai_strerror(errno) : strerror(errno) );
|
|
printf("ERROR\t: socket_udp_open() failed: %s\n", error);
|
|
socket_close(_as_simulator_ue_sid);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
printf("INFO\t: %s - The RRC Simulator is now connected to %s/%s (%d)\n",
|
|
__FUNCTION__, mhost, mport, socket_get_fd(_as_simulator_mme_sid));
|
|
|
|
printf("[%s][AS=%s]\n", getTime(), _as_id);
|
|
|
|
/*
|
|
* Set up signal handler
|
|
*/
|
|
(void) _set_signal_handler(SIGINT, _signal_handler);
|
|
(void) _set_signal_handler(SIGTERM, _signal_handler);
|
|
|
|
pthread_attr_t attr;
|
|
pthread_attr_init(&attr);
|
|
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
|
|
/*
|
|
* Start thread use to manage the connection endpoint with the
|
|
* UE NAS process
|
|
*/
|
|
pthread_t ue_mngr;
|
|
|
|
if ( pthread_create (&ue_mngr, &attr, _as_simulator_ue_mngr, NULL) != 0 ) {
|
|
perror("ERROR\t: Failed to create the UE management thread\n");
|
|
socket_close(_as_simulator_ue_sid);
|
|
socket_close(_as_simulator_mme_sid);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/*
|
|
* Start thread use to manage the connection endpoint with the
|
|
* MME NAS process
|
|
*/
|
|
pthread_t mme_mngr;
|
|
|
|
if ( pthread_create (&mme_mngr, &attr, _as_simulator_mme_mngr, NULL) != 0 ) {
|
|
perror("ERROR\t: Failed to create the MME management thread\n");
|
|
socket_close(_as_simulator_ue_sid);
|
|
socket_close(_as_simulator_mme_sid);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
pthread_attr_destroy(&attr);
|
|
|
|
/*
|
|
* Suspend execution of the main process until connection
|
|
* managers are running
|
|
*/
|
|
poll(NULL, 0, SLEEP_TIMEOUT);
|
|
|
|
while (_as_simulator_ue_is_running && _as_simulator_mme_is_running) {
|
|
poll(NULL, 0, SLEEP_TIMEOUT);
|
|
}
|
|
|
|
/*
|
|
* Termination cleanup
|
|
*/
|
|
printf("INFO\t: %s - Closing UE's connection endpoint %d\n",
|
|
__FUNCTION__, socket_get_fd(_as_simulator_ue_sid));
|
|
socket_close(_as_simulator_ue_sid);
|
|
printf("INFO\t: %s - Closing MME's connection endpoint %d\n",
|
|
__FUNCTION__, socket_get_fd(_as_simulator_mme_sid));
|
|
socket_close(_as_simulator_mme_sid);
|
|
|
|
printf("INFO\t: %s - RRC simulator exited\n", __FUNCTION__);
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/****************************************************************************/
|
|
/********************* L O C A L F U N C T I O N S *********************/
|
|
/****************************************************************************/
|
|
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* Signal handler setup function
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
static int _set_signal_handler(int signal, void (handler)(int))
|
|
{
|
|
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;
|
|
}
|
|
|
|
return RETURNok;
|
|
}
|
|
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* Signal handler
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
static void _signal_handler(int signal_number)
|
|
{
|
|
printf("\nWARNING\t: %s - Signal %d received\n", __FUNCTION__,
|
|
signal_number);
|
|
_as_simulator_ue_is_running = false;
|
|
_as_simulator_mme_is_running = false;
|
|
}
|
|
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* UE connection manager
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
static void* _as_simulator_ue_mngr(void* args)
|
|
{
|
|
int msg_id;
|
|
as_message_t msg;
|
|
|
|
_as_simulator_ue_is_running = true;
|
|
|
|
printf("INFO\t: %s - UE connection manager started\n", __FUNCTION__);
|
|
|
|
printf("[%s][NAS-UE=%s]\n", getTime(), _ue_id);
|
|
|
|
/* Receiving loop */
|
|
while (_as_simulator_ue_is_running) {
|
|
int rc, rbytes, sbytes;
|
|
|
|
/* Receive message from the UE NAS process */
|
|
rbytes = socket_recv(_as_simulator_ue_sid, _as_simulator_ue_buffer,
|
|
AS_SIMULATOR_UE_BUFFER_SIZE);
|
|
|
|
if (rbytes == RETURNerror) {
|
|
perror("ERROR\t: socket_recv() failed");
|
|
break;
|
|
}
|
|
|
|
/* Decode the received message */
|
|
msg_id = as_message_decode(_as_simulator_ue_buffer, &msg, rbytes);
|
|
|
|
if (msg_id == RETURNerror) {
|
|
printf("WARNING\t: %s - Failed to decode AS message\n",
|
|
__FUNCTION__);
|
|
continue;
|
|
}
|
|
|
|
/* Reset the size of the message to be transfered */
|
|
_as_simulator_ue_size = 0;
|
|
_as_simulator_mme_size = 0;
|
|
|
|
/* Process the received message */
|
|
rc = _as_simulator_ue_process(msg_id, &msg);
|
|
|
|
if (rc != RETURNok) {
|
|
printf("WARNING\t: %s - Failed to process AS message (0x%x)\n",
|
|
__FUNCTION__, msg_id);
|
|
continue;
|
|
}
|
|
|
|
if (_as_simulator_ue_size > 0) {
|
|
/* Return the response message to the UE NAS process */
|
|
sbytes = socket_send(_as_simulator_ue_sid,
|
|
_as_simulator_ue_buffer,
|
|
_as_simulator_ue_size);
|
|
|
|
if (sbytes == RETURNerror) {
|
|
perror("ERROR\t: socket_send() failed");
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (_as_simulator_mme_size > 0) {
|
|
/* Forward the received message to the MME NAS process */
|
|
sbytes = socket_send(_as_simulator_mme_sid,
|
|
_as_simulator_mme_buffer,
|
|
_as_simulator_mme_size);
|
|
|
|
if (sbytes == RETURNerror) {
|
|
perror("ERROR\t: socket_send() failed");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Close the connection to the network sublayer */
|
|
_as_simulator_ue_is_running = false;
|
|
printf("ERROR\t: The UE connection manager exited\n");
|
|
return (NULL);
|
|
}
|
|
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* MME connection manager
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
static void* _as_simulator_mme_mngr(void* args)
|
|
{
|
|
int msg_id;
|
|
as_message_t msg;
|
|
|
|
_as_simulator_mme_is_running = true;
|
|
|
|
printf("INFO\t: %s - MME connection manager started\n", __FUNCTION__);
|
|
|
|
printf("[%s][NAS-MME=%s]\n", getTime(), _mme_id);
|
|
|
|
/* Receiving loop */
|
|
while (_as_simulator_mme_is_running) {
|
|
int rc, rbytes, sbytes;
|
|
|
|
/* Receive message from the MME NAS process */
|
|
rbytes = socket_recv(_as_simulator_mme_sid, _as_simulator_mme_buffer,
|
|
AS_SIMULATOR_MME_BUFFER_SIZE);
|
|
|
|
if (rbytes == RETURNerror) {
|
|
perror("ERROR\t: socket_recv() failed");
|
|
break;
|
|
}
|
|
|
|
/* Decode the received message */
|
|
msg_id = as_message_decode(_as_simulator_mme_buffer, &msg, rbytes);
|
|
|
|
if (msg_id == RETURNerror) {
|
|
printf("ERROR\t: %s - as_message_decode() failed\n", __FUNCTION__);
|
|
continue;
|
|
}
|
|
|
|
/* Reset the size of the message to be transfered */
|
|
_as_simulator_ue_size = 0;
|
|
_as_simulator_mme_size = 0;
|
|
|
|
/* Process the received message */
|
|
rc = _as_simulator_mme_process(msg_id, &msg);
|
|
|
|
if (rc != RETURNok) {
|
|
printf("WARNING\t: %s - Failed to process AS message (0x%x)\n",
|
|
__FUNCTION__, msg_id);
|
|
continue;
|
|
}
|
|
|
|
if (_as_simulator_mme_size > 0) {
|
|
/* Return the response message to the MME NAS process */
|
|
sbytes = socket_send(_as_simulator_mme_sid,
|
|
_as_simulator_mme_buffer,
|
|
_as_simulator_mme_size);
|
|
|
|
if (sbytes == RETURNerror) {
|
|
perror("ERROR\t: socket_send() failed");
|
|
break;
|
|
}
|
|
}
|
|
|
|
if (_as_simulator_ue_size > 0) {
|
|
/* Forward the received message to the UE NAS process */
|
|
sbytes = socket_send(_as_simulator_ue_sid,
|
|
_as_simulator_ue_buffer,
|
|
_as_simulator_ue_size);
|
|
|
|
if (sbytes == RETURNerror) {
|
|
perror("ERROR\t: socket_send() failed");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Close the connection to the network sublayer */
|
|
_as_simulator_mme_is_running = false;
|
|
printf("ERROR\t: %s - The MME connection manager exited\n", __FUNCTION__);
|
|
return (NULL);
|
|
}
|
|
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* Functions used to process messages received from the UE NAS process
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
static int _as_simulator_ue_process(int msg_id, as_message_t* msg)
|
|
{
|
|
int rc = RETURNok;
|
|
|
|
as_message_t cnf;
|
|
as_message_t ind;
|
|
|
|
printf("\nINFO\t: %s - Received AS message 0x%x from UE NAS process\n",
|
|
__FUNCTION__, msg_id);
|
|
|
|
_as_simulator_ue_transfer = AS_SIMULATOR_NO_TRANSFER;
|
|
|
|
memset(&cnf, 0, sizeof(as_message_t));
|
|
memset(&ind, 0, sizeof(as_message_t));
|
|
|
|
switch (msg_id) {
|
|
case AS_CELL_INFO_REQ:
|
|
cnf.msgID = process_cell_info_req(msg_id,
|
|
&msg->msg.cell_info_req,
|
|
&cnf.msg.cell_info_cnf);
|
|
/* Return confirm message to the UE */
|
|
_as_simulator_ue_transfer |= AS_SIMULATOR_TRANSFER_TO_UE;
|
|
break;
|
|
|
|
case AS_NAS_ESTABLISH_REQ:
|
|
ind.msgID = process_nas_establish_req(msg_id,
|
|
&msg->msg.nas_establish_req,
|
|
&ind.msg.nas_establish_ind,
|
|
&cnf.msg.nas_establish_cnf);
|
|
|
|
if (ind.msgID) {
|
|
/* Forward indication message to the MME */
|
|
_as_simulator_ue_transfer |= AS_SIMULATOR_TRANSFER_TO_MME;
|
|
}
|
|
|
|
/* Return confirm message to the UE */
|
|
cnf.msgID = AS_NAS_ESTABLISH_CNF;
|
|
_as_simulator_ue_transfer |= AS_SIMULATOR_TRANSFER_TO_UE;
|
|
break;
|
|
|
|
case AS_UL_INFO_TRANSFER_REQ:
|
|
ind.msgID = process_ul_info_transfer_req(msg_id,
|
|
&msg->msg.ul_info_transfer_req,
|
|
&ind.msg.ul_info_transfer_ind,
|
|
&cnf.msg.ul_info_transfer_cnf);
|
|
|
|
if (ind.msgID) {
|
|
/* Forward indication message to the MME */
|
|
_as_simulator_ue_transfer |= AS_SIMULATOR_TRANSFER_TO_MME;
|
|
}
|
|
|
|
/* Return confirm message to the UE */
|
|
cnf.msgID = AS_UL_INFO_TRANSFER_CNF;
|
|
_as_simulator_ue_transfer |= AS_SIMULATOR_TRANSFER_TO_UE;
|
|
break;
|
|
|
|
case AS_NAS_RELEASE_REQ:
|
|
ind.msgID = process_nas_release_req(msg_id,
|
|
&msg->msg.nas_release_req);
|
|
break;
|
|
|
|
default:
|
|
printf("WARNING\t: %s - AS message is not valid (0x%x)\n",
|
|
__FUNCTION__, msg_id);
|
|
rc = RETURNerror;
|
|
break;
|
|
}
|
|
|
|
if (_as_simulator_ue_transfer & AS_SIMULATOR_TRANSFER_TO_UE) {
|
|
/* Encode the message confirmation returned to the NAS running
|
|
* at the UE side */
|
|
_as_simulator_ue_size = as_message_encode(_as_simulator_ue_buffer, &cnf,
|
|
AS_SIMULATOR_UE_BUFFER_SIZE);
|
|
|
|
if (_as_simulator_ue_size == RETURNerror) {
|
|
_as_simulator_ue_size = 0;
|
|
rc = RETURNerror;
|
|
}
|
|
}
|
|
|
|
if (_as_simulator_ue_transfer & AS_SIMULATOR_TRANSFER_TO_MME) {
|
|
/* Encode the message indication forwarded to the NAS running
|
|
* at the MME side */
|
|
_as_simulator_mme_size = as_message_encode(_as_simulator_mme_buffer, &ind,
|
|
AS_SIMULATOR_MME_BUFFER_SIZE);
|
|
|
|
if (_as_simulator_mme_size == RETURNerror) {
|
|
_as_simulator_mme_size = 0;
|
|
rc = RETURNerror;
|
|
}
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|
|
/*
|
|
* -----------------------------------------------------------------------------
|
|
* Functions used to process messages received from the MME NAS process
|
|
* -----------------------------------------------------------------------------
|
|
*/
|
|
static int _as_simulator_mme_process(int msg_id, as_message_t* msg)
|
|
{
|
|
int rc = RETURNok;
|
|
|
|
as_message_t cnf;
|
|
as_message_t ind;
|
|
|
|
printf("\nINFO\t: %s - Received AS message 0x%x from MME NAS process\n",
|
|
__FUNCTION__, msg_id);
|
|
|
|
_as_simulator_mme_transfer = AS_SIMULATOR_NO_TRANSFER;
|
|
|
|
memset(&cnf, 0, sizeof(as_message_t));
|
|
memset(&ind, 0, sizeof(as_message_t));
|
|
|
|
switch (msg_id) {
|
|
case AS_NAS_ESTABLISH_RSP:
|
|
cnf.msgID = process_nas_establish_rsp(msg_id,
|
|
&msg->msg.nas_establish_rsp,
|
|
&cnf.msg.nas_establish_cnf);
|
|
|
|
if (cnf.msgID) {
|
|
/* Forward confirm message to the UE */
|
|
_as_simulator_mme_transfer |= AS_SIMULATOR_TRANSFER_TO_UE;
|
|
}
|
|
|
|
break;
|
|
|
|
case AS_DL_INFO_TRANSFER_REQ:
|
|
ind.msgID = process_dl_info_transfer_req(msg_id,
|
|
&msg->msg.dl_info_transfer_req,
|
|
&ind.msg.dl_info_transfer_ind,
|
|
&cnf.msg.dl_info_transfer_cnf);
|
|
|
|
if (ind.msgID) {
|
|
/* Forward indication message to the UE */
|
|
_as_simulator_mme_transfer |= AS_SIMULATOR_TRANSFER_TO_UE;
|
|
}
|
|
|
|
/* Return confirm message to the MME */
|
|
cnf.msgID = AS_DL_INFO_TRANSFER_CNF;
|
|
_as_simulator_mme_transfer |= AS_SIMULATOR_TRANSFER_TO_MME;
|
|
break;
|
|
|
|
case AS_NAS_RELEASE_REQ:
|
|
ind.msgID = process_nas_release_ind(msg_id,
|
|
&msg->msg.nas_release_req,
|
|
&ind.msg.nas_release_ind);
|
|
/* Forward indication message to the UE */
|
|
_as_simulator_mme_transfer |= AS_SIMULATOR_TRANSFER_TO_UE;
|
|
break;
|
|
|
|
default:
|
|
printf("WARNING\t: %s - AS message is not valid (0x%x)\n",
|
|
__FUNCTION__, msg_id);
|
|
rc = RETURNerror;
|
|
break;
|
|
}
|
|
|
|
if (_as_simulator_mme_transfer & AS_SIMULATOR_TRANSFER_TO_UE) {
|
|
if (ind.msgID > 0) {
|
|
/* Encode the message indication forwarded to the NAS running
|
|
* at the UE side */
|
|
_as_simulator_ue_size = as_message_encode(_as_simulator_ue_buffer,
|
|
&ind, AS_SIMULATOR_UE_BUFFER_SIZE);
|
|
} else if (cnf.msgID > 0) {
|
|
/* Encode the message confirmation forwarded to the NAS running
|
|
* at the UE side */
|
|
_as_simulator_ue_size = as_message_encode(_as_simulator_ue_buffer,
|
|
&cnf, AS_SIMULATOR_UE_BUFFER_SIZE);
|
|
}
|
|
|
|
if (_as_simulator_ue_size == RETURNerror) {
|
|
_as_simulator_ue_size = 0;
|
|
rc = RETURNerror;
|
|
}
|
|
}
|
|
|
|
if (_as_simulator_mme_transfer & AS_SIMULATOR_TRANSFER_TO_MME) {
|
|
/* Encode the message confirmation returned to the NAS running
|
|
* at the MME side */
|
|
_as_simulator_mme_size = as_message_encode(_as_simulator_mme_buffer,
|
|
&cnf, AS_SIMULATOR_MME_BUFFER_SIZE);
|
|
|
|
if (_as_simulator_mme_size == RETURNerror) {
|
|
_as_simulator_mme_size = 0;
|
|
rc = RETURNerror;
|
|
}
|
|
}
|
|
|
|
return (rc);
|
|
}
|
|
|