renamed openair-cn to openair3
git-svn-id: http://svn.eurecom.fr/openair4G/trunk@7886 818b1a75-f10b-46b9-bf7c-635c3b92a50f
This commit is contained in:
@@ -0,0 +1,312 @@
|
||||
/*****************************************************************************
|
||||
Eurecom OpenAirInterface 3
|
||||
Copyright(c) 2012 Eurecom
|
||||
|
||||
Source user_simulator.c
|
||||
|
||||
Version 0.1
|
||||
|
||||
Date 2012/10/09
|
||||
|
||||
Product User simulator
|
||||
|
||||
Subsystem User simulator main process
|
||||
|
||||
Author Frederic Maurel
|
||||
|
||||
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, 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, 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;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Send the AT command one byte at a time (serial port simulation) */
|
||||
const char* pbuffer = _user_simulator_send_buffer;
|
||||
|
||||
while (*pbuffer) {
|
||||
int sbytes = USER_SEND(pbuffer++, 1);
|
||||
|
||||
if (sbytes == RETURNerror) {
|
||||
perror("ERROR\t: Failed to send data to the NAS sublayer");
|
||||
break;
|
||||
}
|
||||
|
||||
(void)poll(0, 0, 10);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
(void)poll(0, 0, 100);
|
||||
}
|
||||
|
||||
/*
|
||||
* Termination cleanup
|
||||
*/
|
||||
printf("INFO\t: Closing user endpoint descriptor %d\n", 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", 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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user