- all RAN code, CI code, configuration files, dockerfiles, in CSSL v1.0
- all deployment code (openshift, charts, ancillary files like shell
scripts), in MIT
- documentation in CC-BY-4.0
- exceptions might apply and are listed in NOTICE
- there is a new LICENSES folder with all licenses
- CONTRIBUTIONS.md has been updated accordingly
For automated changes based on OAI PL v1.1:
perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.{c,h,cpp}
perl -i~ -0pe 's/\/\*.*Licensed to the OpenAirInterface.*openairinterface.org\n#?/\/*\n * SPDX-License-Identifier: LicenseRef-CSSL-1.0\n/s' **/*.ts
perl -i~ -0pe 's/<!--.*Licensed to the OpenAirInterface.*openairinterface.org\n.*-->/<!-- SPDX-License-Identifier: LicenseRef-CSSL-1.0 -->/s' **/*.xml
The rest (cmake, files with missing license, cmake) manually.
295 lines
8.3 KiB
C
295 lines
8.3 KiB
C
/*
|
|
* SPDX-License-Identifier: LicenseRef-CSSL-1.0
|
|
*/
|
|
|
|
/*****************************************************************************
|
|
Source user_simulator.c
|
|
|
|
Version 0.1
|
|
|
|
Date 2012/10/09
|
|
|
|
Product User simulator
|
|
|
|
Subsystem User simulator main process
|
|
|
|
Description Implements the user simulator running at the user application
|
|
layer for NAS testing purpose.
|
|
|
|
*****************************************************************************/
|
|
|
|
#include "user_parser.h"
|
|
|
|
#include "include/commonDef.h"
|
|
#include "util/socket.h"
|
|
#include "util/device.h"
|
|
|
|
#include <stdio.h> // printf, perror
|
|
#include <errno.h> // errno
|
|
#include <netdb.h> // gai_strerror
|
|
#include <ctype.h> // isspace
|
|
#include <stdlib.h> // exit
|
|
#include <signal.h> // sigaction
|
|
#include <string.h> // memset
|
|
#include <pthread.h>
|
|
#include <poll.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 USER_SIMULATOR_BUFFER_SIZE 1024
|
|
|
|
/*
|
|
* String buffer used to send AT commands to the NAS sublayer
|
|
*/
|
|
static char _user_simulator_send_buffer [USER_SIMULATOR_BUFFER_SIZE];
|
|
|
|
/*
|
|
* String buffer used to receive responses from the NAS sublayer
|
|
*/
|
|
static char _user_simulator_recv_buffer [USER_SIMULATOR_BUFFER_SIZE];
|
|
|
|
/*
|
|
* The connection endpoint used for communication with the
|
|
* NAS sublayer (see src/api/user/user_api.c)
|
|
*/
|
|
static struct {
|
|
void* endpoint;
|
|
void* (*open) (int, const char*, const char*);
|
|
int (*getfd)(const void*);
|
|
ssize_t (*recv) (void*, char*, size_t);
|
|
ssize_t (*send) (const void*, const char*, size_t);
|
|
void (*close)(void*);
|
|
} _user_simulator_id;
|
|
//static socket_id_t * _user_simulator_sid;
|
|
|
|
#define USER_OPEN(a, b, c) _user_simulator_id.open(a, b, c)
|
|
#define USER_GETFD() _user_simulator_id.getfd(_user_simulator_id.endpoint)
|
|
#define USER_RECV(a, b) _user_simulator_id.recv(_user_simulator_id.endpoint, a, b)
|
|
#define USER_SEND(a, b) _user_simulator_id.send(_user_simulator_id.endpoint, a, b)
|
|
#define USER_CLOSE() _user_simulator_id.close(_user_simulator_id.endpoint)
|
|
|
|
static int _set_signal_handler(int signal, void (handler)(int));
|
|
static void _signal_handler(int signal_number);
|
|
static void* _receive_thread(void* arg);
|
|
|
|
/****************************************************************************/
|
|
/****************** E X P O R T E D F U N C T I O N S ******************/
|
|
/****************************************************************************/
|
|
|
|
/****************************************************************************/
|
|
int main (int argc, const char* argv[])
|
|
{
|
|
/*
|
|
* Get the command line options
|
|
*/
|
|
if ( user_parser_get_options(argc, argv) != RETURNok ) {
|
|
user_parser_print_usage();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
const char* host = user_parser_get_host();
|
|
const char* port = user_parser_get_port();
|
|
const char* devpath = user_parser_get_devpath();
|
|
const char* devattr = user_parser_get_devattr();
|
|
|
|
printf("%s -host %s -port %s -dev %s -params %s\n",
|
|
argv[0], host, port, devpath, devattr);
|
|
|
|
/*
|
|
* Initialize the communication channel to the NAS sublayer
|
|
*/
|
|
if (devpath) {
|
|
/* Initialize device handlers */
|
|
_user_simulator_id.open = device_open;
|
|
_user_simulator_id.getfd = device_get_fd;
|
|
_user_simulator_id.recv = device_read;
|
|
_user_simulator_id.send = device_write;
|
|
_user_simulator_id.close = device_close;
|
|
|
|
/* Initialize communication channel */
|
|
_user_simulator_id.endpoint = USER_OPEN(DEVICE, devpath, devattr);
|
|
|
|
if (_user_simulator_id.endpoint == NULL) {
|
|
perror("ERROR\t: Failed to open connection endpoint");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
printf("INFO\t: The User Simulator is now connected to %s (%d)\n",
|
|
devpath, (int)USER_GETFD());
|
|
} else {
|
|
/* Initialize network socket handlers */
|
|
_user_simulator_id.open = socket_udp_open;
|
|
_user_simulator_id.getfd = socket_get_fd;
|
|
_user_simulator_id.recv = socket_recv;
|
|
_user_simulator_id.send = socket_send;
|
|
_user_simulator_id.close = socket_close;
|
|
|
|
/* Initialize communication channel */
|
|
_user_simulator_id.endpoint = USER_OPEN(SOCKET_CLIENT, host, port);
|
|
|
|
if (_user_simulator_id.endpoint == NULL) {
|
|
const char* error = ( (errno < 0) ?
|
|
gai_strerror(errno) : strerror(errno) );
|
|
printf("ERROR\t: Failed to open connection endpoint: %s\n", error);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
printf("INFO\t: The User Simulator is now connected to %s/%s (%d)\n",
|
|
host, port, (int)USER_GETFD());
|
|
}
|
|
|
|
|
|
/*
|
|
* Set up signal handler
|
|
*/
|
|
(void) _set_signal_handler(SIGINT, _signal_handler);
|
|
(void) _set_signal_handler(SIGTERM, _signal_handler);
|
|
|
|
/*
|
|
* Create the receiving thread
|
|
*/
|
|
pthread_attr_t attr;
|
|
pthread_t thread_id;
|
|
pthread_attr_init(&attr);
|
|
pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
|
|
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
int rc = pthread_create (&thread_id, &attr, _receive_thread, NULL);
|
|
|
|
if (rc != 0) {
|
|
perror("ERROR\t: pthread_create() failed");
|
|
USER_CLOSE();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/*
|
|
* User simulator main loop
|
|
*/
|
|
while (true) {
|
|
char c;
|
|
int len;
|
|
|
|
/* Get the AT command */
|
|
printf("AT command (q to quit) > ");
|
|
c = getchar();
|
|
|
|
if (c == 'q') break;
|
|
|
|
if (c == '\n') continue;
|
|
|
|
len = 0;
|
|
|
|
while ( (len < USER_SIMULATOR_BUFFER_SIZE - 1) && (c != '\n') ) {
|
|
if (!isspace(c)) {
|
|
_user_simulator_send_buffer[len++] = c;
|
|
}
|
|
|
|
c = getchar();
|
|
}
|
|
|
|
_user_simulator_send_buffer[len++] = '\r';
|
|
_user_simulator_send_buffer[len] = '\0';
|
|
|
|
/* Send the AT command to the NAS sublayer */
|
|
int sbytes = USER_SEND(_user_simulator_send_buffer, len);
|
|
|
|
if (sbytes == RETURNerror) {
|
|
perror("ERROR\t: Failed to send data to the NAS sublayer");
|
|
break;
|
|
}
|
|
|
|
(void)poll(0, 0, 100);
|
|
}
|
|
|
|
/*
|
|
* Termination cleanup
|
|
*/
|
|
printf("INFO\t: Closing user endpoint descriptor %d\n", (int)USER_GETFD());
|
|
USER_CLOSE();
|
|
|
|
printf("INFO\t: User simulator exited\n");
|
|
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: Signal %d received\n", signal_number);
|
|
printf("INFO\t: Closing user socket %d\n", (int)USER_GETFD());
|
|
USER_CLOSE();
|
|
printf("INFO\t: User simulator exited\n");
|
|
exit(EXIT_SUCCESS);
|
|
}
|
|
|
|
/*
|
|
* Receiving thread
|
|
*/
|
|
static void* _receive_thread(void* arg)
|
|
{
|
|
while (true) {
|
|
/* Receive AT response from the NAS sublayer */
|
|
int rbytes = USER_RECV(_user_simulator_recv_buffer,
|
|
USER_SIMULATOR_BUFFER_SIZE);
|
|
|
|
if (rbytes != 0) {
|
|
if (rbytes == RETURNerror) {
|
|
perror("ERROR\t: Failed to receive data from the NAS sublayer");
|
|
break;
|
|
}
|
|
|
|
_user_simulator_recv_buffer[rbytes] = '\0';
|
|
|
|
/* Display AT response */
|
|
printf("%s\n", _user_simulator_recv_buffer);
|
|
}
|
|
}
|
|
|
|
return (NULL);
|
|
}
|
|
|