Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
O
OpenXG-RAN
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wangjie
OpenXG-RAN
Commits
5c0098e2
Commit
5c0098e2
authored
Dec 15, 2015
by
Navid Nikaein
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
* add async interface support for eNB agent and create a lib
parent
37d7fa8d
Changes
7
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
1026 additions
and
1 deletion
+1026
-1
cmake_targets/CMakeLists.txt
cmake_targets/CMakeLists.txt
+14
-1
openair2/UTIL/ASYNC_IF/link_manager.c
openair2/UTIL/ASYNC_IF/link_manager.c
+247
-0
openair2/UTIL/ASYNC_IF/link_manager.h
openair2/UTIL/ASYNC_IF/link_manager.h
+69
-0
openair2/UTIL/ASYNC_IF/message_queue.c
openair2/UTIL/ASYNC_IF/message_queue.c
+211
-0
openair2/UTIL/ASYNC_IF/message_queue.h
openair2/UTIL/ASYNC_IF/message_queue.h
+71
-0
openair2/UTIL/ASYNC_IF/socket_link.c
openair2/UTIL/ASYNC_IF/socket_link.c
+349
-0
openair2/UTIL/ASYNC_IF/socket_link.h
openair2/UTIL/ASYNC_IF/socket_link.h
+65
-0
No files found.
cmake_targets/CMakeLists.txt
View file @
5c0098e2
...
...
@@ -473,6 +473,9 @@ add_list_string_option(PACKAGE_NAME "NotDefined" "As per attribute name")
add_boolean_option
(
MESSAGE_CHART_GENERATOR False
"For generating sequence diagrams"
)
add_boolean_option
(
MESSAGE_CHART_GENERATOR_RLC_MAC False
"trace RLC-MAC exchanges in sequence diagrams"
)
add_boolean_option
(
MESSAGE_CHART_GENERATOR_PHY False
"trace some PHY exchanges in sequence diagrams"
)
add_boolean_option
(
ENB_AGENT True
"enable eNB agent to inteface with a SDN contrller"
)
########################
# Include order
##########################
...
...
@@ -687,6 +690,16 @@ include_directories("${OPENAIR_DIR}")
# Utilities Library
################
if
(
ENB_AGENT
)
add_library
(
ASYNC_IF
${
OPENAIR2_DIR
}
/UTIL/ASYNC_IF/socket_link.c
${
OPENAIR2_DIR
}
/UTIL/ASYNC_IF/link_manager.c
${
OPENAIR2_DIR
}
/UTIL/ASYNC_IF/message_queue.c
)
set
(
ASYNC_IF_LIB ASYNC_IF
)
endif
()
include_directories
(
${
OPENAIR2_DIR
}
/UTIL/ASYNC_IF
)
add_library
(
HASHTABLE
${
OPENAIR_DIR
}
/common/utils/collection/hashtable/hashtable.c
${
OPENAIR_DIR
}
/common/utils/collection/hashtable/obj_hashtable.c
...
...
@@ -1591,7 +1604,7 @@ add_executable(oaisim_nos1
target_include_directories
(
oaisim_nos1 PUBLIC
${
OPENAIR_TARGETS
}
/SIMU/USER
)
target_link_libraries
(
oaisim_nos1
-Wl,--start-group
RRC_LIB X2AP_LIB SECU_CN UTIL HASHTABLE SCHED_LIB PHY LFDS
${
MSC_LIB
}
L2
${
RAL_LIB
}
SIMU SIMU_ETH SECU_OSA
${
ITTI_LIB
}
${
MIH_LIB
}
RRC_LIB X2AP_LIB SECU_CN UTIL HASHTABLE SCHED_LIB PHY LFDS
${
MSC_LIB
}
L2
${
RAL_LIB
}
SIMU SIMU_ETH SECU_OSA
${
ITTI_LIB
}
${
MIH_LIB
}
${
ASYNC_IF_LIB
}
-Wl,--end-group
)
target_link_libraries
(
oaisim_nos1
${
LIBXML2_LIBRARIES
}
${
LAPACK_LIBRARIES
}
)
...
...
openair2/UTIL/ASYNC_IF/link_manager.c
0 → 100644
View file @
5c0098e2
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2015 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file link_manager.c
* \brief this is the implementation of a link manager
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#include "link_manager.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
/* that thread reads messages in the queue and sends them to the link */
static
void
*
link_manager_sender_thread
(
void
*
_manager
)
{
link_manager_t
*
manager
=
_manager
;
void
*
data
;
int
size
;
int
priority
;
LOG_D
(
MAC
,
"starting link manager sender thread
\n
"
);
while
(
manager
->
run
)
{
if
(
message_get
(
manager
->
send_queue
,
&
data
,
&
size
,
&
priority
))
goto
error
;
if
(
link_send_packet
(
manager
->
socket_link
,
data
,
size
))
goto
error
;
free
(
data
);
}
LOG_D
(
MAC
,
"link manager sender thread quits
\n
"
);
return
NULL
;
error:
LOG_E
(
MAC
,
"%s: error
\n
"
,
__FUNCTION__
);
return
NULL
;
}
/* that thread receives messages from the link and puts them in the queue */
static
void
*
link_manager_receiver_thread
(
void
*
_manager
)
{
link_manager_t
*
manager
=
_manager
;
void
*
data
;
int
size
;
LOG_D
(
MAC
,
"starting link manager receiver thread
\n
"
);
while
(
manager
->
run
)
{
if
(
link_receive_packet
(
manager
->
socket_link
,
&
data
,
&
size
))
goto
error
;
/* todo: priority */
if
(
message_put
(
manager
->
receive_queue
,
data
,
size
,
0
))
goto
error
;
}
LOG_D
(
MAC
,
"link manager receiver thread quits
\n
"
);
return
NULL
;
error:
LOG_E
(
MAC
,
"%s: error
\n
"
,
__FUNCTION__
);
return
NULL
;
}
link_manager_t
*
create_link_manager
(
message_queue_t
*
send_queue
,
message_queue_t
*
receive_queue
,
socket_link_t
*
link
)
{
link_manager_t
*
ret
=
NULL
;
pthread_attr_t
attr
;
pthread_t
t
;
LOG_D
(
MAC
,
"create new link manager
\n
"
);
ret
=
calloc
(
1
,
sizeof
(
link_manager_t
));
if
(
ret
==
NULL
)
goto
error
;
ret
->
send_queue
=
send_queue
;
ret
->
receive_queue
=
receive_queue
;
ret
->
socket_link
=
link
;
ret
->
run
=
1
;
if
(
pthread_attr_init
(
&
attr
))
goto
error
;
if
(
pthread_attr_setdetachstate
(
&
attr
,
PTHREAD_CREATE_DETACHED
))
goto
error
;
if
(
pthread_create
(
&
t
,
&
attr
,
link_manager_sender_thread
,
ret
))
goto
error
;
ret
->
sender
=
t
;
if
(
pthread_create
(
&
t
,
&
attr
,
link_manager_receiver_thread
,
ret
))
/* we should destroy the other thread here */
goto
error
;
ret
->
receiver
=
t
;
if
(
pthread_attr_destroy
(
&
attr
))
/* to be clean we should destroy the threads at this point,
* even if in practice we never reach it */
goto
error
;
return
ret
;
error:
LOG_E
(
MAC
,
"%s: an error occured
\n
"
,
__FUNCTION__
);
free
(
ret
);
return
NULL
;
}
void
destroy_link_manager
(
link_manager_t
*
manager
)
{
LOG_D
(
MAC
,
"destroying link manager
\n
"
);
manager
->
run
=
0
;
/* todo: force threads to stop (using a dummy message?) */
}
#ifdef SERVER_TEST
#include <string.h>
int
main
(
void
)
{
socket_link_t
*
link
;
message_queue_t
*
send_queue
;
message_queue_t
*
receive_queue
;
link_manager_t
*
manager
;
void
*
data
;
int
size
;
int
priority
;
printf
(
"starting server
\n
"
);
link
=
new_link_server
(
2210
);
if
(
link
==
NULL
)
goto
error
;
send_queue
=
new_message_queue
();
if
(
send_queue
==
NULL
)
goto
error
;
receive_queue
=
new_message_queue
();
if
(
receive_queue
==
NULL
)
goto
error
;
manager
=
create_link_manager
(
send_queue
,
receive_queue
,
link
);
if
(
manager
==
NULL
)
goto
error
;
data
=
strdup
(
"hello"
);
if
(
data
==
NULL
)
goto
error
;
if
(
message_put
(
send_queue
,
data
,
6
,
100
))
goto
error
;
if
(
message_get
(
receive_queue
,
&
data
,
&
size
,
&
priority
))
goto
error
;
printf
(
"received message:
\n
"
);
printf
(
" data: %s
\n
"
,
(
char
*
)
data
);
printf
(
" size: %d
\n
"
,
size
);
printf
(
" priority: %d
\n
"
,
priority
);
printf
(
"server ends
\n
"
);
return
0
;
error:
printf
(
"there was an error
\n
"
);
return
1
;
}
#endif
#ifdef CLIENT_TEST
#include <string.h>
#include <unistd.h>
int
main
(
void
)
{
socket_link_t
*
link
;
message_queue_t
*
send_queue
;
message_queue_t
*
receive_queue
;
link_manager_t
*
manager
;
void
*
data
;
int
size
;
int
priority
;
printf
(
"starting client
\n
"
);
link
=
new_link_client
(
"127.0.0.1"
,
2210
);
if
(
link
==
NULL
)
goto
error
;
send_queue
=
new_message_queue
();
if
(
send_queue
==
NULL
)
goto
error
;
receive_queue
=
new_message_queue
();
if
(
receive_queue
==
NULL
)
goto
error
;
manager
=
create_link_manager
(
send_queue
,
receive_queue
,
link
);
if
(
manager
==
NULL
)
goto
error
;
if
(
message_get
(
receive_queue
,
&
data
,
&
size
,
&
priority
))
goto
error
;
printf
(
"received message:
\n
"
);
printf
(
" data: %s
\n
"
,
(
char
*
)
data
);
printf
(
" size: %d
\n
"
,
size
);
printf
(
" priority: %d
\n
"
,
priority
);
data
=
strdup
(
"world"
);
if
(
data
==
NULL
)
goto
error
;
if
(
message_put
(
send_queue
,
data
,
6
,
200
))
goto
error
;
/* let's wait for the message to be sent (unreliable sleep, but does it for the test) */
sleep
(
1
);
printf
(
"client ends
\n
"
);
return
0
;
error:
printf
(
"there was an error
\n
"
);
return
1
;
}
#endif
openair2/UTIL/ASYNC_IF/link_manager.h
0 → 100644
View file @
5c0098e2
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2015 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file link_manager.h
* \brief this is the implementation of a link manager
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#ifndef LINK_MANAGER_H
#define LINK_MANAGER_H
#include "message_queue.h"
#include "socket_link.h"
#include <pthread.h>
#ifdef __cplusplus
extern
"C"
{
#endif
typedef
struct
{
message_queue_t
*
send_queue
;
message_queue_t
*
receive_queue
;
socket_link_t
*
socket_link
;
pthread_t
sender
;
pthread_t
receiver
;
volatile
int
run
;
}
link_manager_t
;
link_manager_t
*
create_link_manager
(
message_queue_t
*
send_queue
,
message_queue_t
*
receive_queue
,
socket_link_t
*
link
);
void
destroy_link_manager
(
link_manager_t
*
);
#ifdef __cplusplus
}
#endif
#endif
/* LINK_MANAGER_H */
openair2/UTIL/ASYNC_IF/message_queue.c
0 → 100644
View file @
5c0098e2
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2015 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file message_queue.c
* \brief this is the implementation of a message queue
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#include "message_queue.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
message_queue_t
*
new_message_queue
(
void
)
{
message_queue_t
*
ret
=
NULL
;
ret
=
calloc
(
1
,
sizeof
(
message_queue_t
));
if
(
ret
==
NULL
)
goto
error
;
ret
->
mutex
=
calloc
(
1
,
sizeof
(
pthread_mutex_t
));
if
(
ret
->
mutex
==
NULL
)
goto
error
;
if
(
pthread_mutex_init
(
ret
->
mutex
,
NULL
))
goto
error
;
ret
->
cond
=
calloc
(
1
,
sizeof
(
pthread_cond_t
));
if
(
ret
->
cond
==
NULL
)
goto
error
;
if
(
pthread_cond_init
(
ret
->
cond
,
NULL
))
goto
error
;
return
ret
;
error:
LOG_E
(
MAC
,
"%s: an error occured
\n
"
,
__FUNCTION__
);
if
(
ret
!=
NULL
)
{
free
(
ret
->
mutex
);
free
(
ret
->
cond
);
memset
(
ret
,
0
,
sizeof
(
message_queue_t
));
free
(
ret
);
}
return
NULL
;
}
int
message_put
(
message_queue_t
*
queue
,
void
*
data
,
int
size
,
int
priority
)
{
message_t
*
m
=
NULL
;
m
=
calloc
(
1
,
sizeof
(
message_t
));
if
(
m
==
NULL
)
goto
error
;
m
->
data
=
data
;
m
->
size
=
size
;
m
->
priority
=
priority
;
m
->
next
=
NULL
;
if
(
pthread_mutex_lock
(
queue
->
mutex
))
goto
error
;
if
(
queue
->
count
==
0
)
queue
->
head
=
m
;
else
queue
->
tail
->
next
=
m
;
queue
->
tail
=
m
;
queue
->
count
++
;
if
(
pthread_cond_signal
(
queue
->
cond
))
{
LOG_E
(
MAC
,
"%s:%d:%s: fatal error
\n
"
,
__FILE__
,
__LINE__
,
__FUNCTION__
);
pthread_mutex_unlock
(
queue
->
mutex
);
exit
(
1
);
}
if
(
pthread_mutex_unlock
(
queue
->
mutex
))
{
LOG_E
(
MAC
,
"%s:%d:%s: fatal error
\n
"
,
__FILE__
,
__LINE__
,
__FUNCTION__
);
exit
(
1
);
}
return
0
;
error:
free
(
m
);
LOG_E
(
MAC
,
"%s: an error occured
\n
"
,
__FUNCTION__
);
return
-
1
;
}
int
message_get
(
message_queue_t
*
queue
,
void
**
data
,
int
*
size
,
int
*
priority
)
{
message_t
*
m
;
if
(
pthread_mutex_lock
(
queue
->
mutex
))
goto
error
;
while
(
queue
->
count
==
0
)
{
if
(
pthread_cond_wait
(
queue
->
cond
,
queue
->
mutex
))
{
pthread_mutex_unlock
(
queue
->
mutex
);
goto
error
;
}
}
m
=
queue
->
head
;
queue
->
head
=
queue
->
head
->
next
;
if
(
queue
->
head
==
NULL
)
queue
->
tail
=
NULL
;
queue
->
count
--
;
if
(
pthread_mutex_unlock
(
queue
->
mutex
))
goto
error
;
*
data
=
m
->
data
;
*
size
=
m
->
size
;
*
priority
=
m
->
priority
;
free
(
m
);
return
0
;
error:
LOG_E
(
MAC
,
"%s: an error occured
\n
"
,
__FUNCTION__
);
return
-
1
;
}
/* when calling this function, the queue must not be used anymore (we don't lock it) */
/* we suppose that the data pointer in messages was allocated by malloc/calloc/realloc */
void
destroy_message_queue
(
message_queue_t
*
queue
)
{
while
(
queue
->
head
)
{
message_t
*
m
=
queue
->
head
;
queue
->
head
=
queue
->
head
->
next
;
free
(
m
->
data
);
memset
(
m
,
0
,
sizeof
(
message_t
));
free
(
m
);
}
free
(
queue
->
mutex
);
free
(
queue
->
cond
);
memset
(
queue
,
0
,
sizeof
(
message_queue_t
));
free
(
queue
);
}
#ifdef TEST
/* some very basic tests */
int
main
(
void
)
{
void
*
data
;
int
size
;
int
priority
;
message_queue_t
*
q
;
char
*
s
;
q
=
new_message_queue
();
if
(
q
==
NULL
)
goto
error
;
if
(
message_put
(
q
,
"hello"
,
6
,
0
))
goto
error
;
if
(
message_put
(
q
,
"world"
,
6
,
1
))
goto
error
;
if
(
message_get
(
q
,
&
data
,
&
size
,
&
priority
))
goto
error
;
printf
(
"message:
\n
data: '%s'
\n
size: %d
\n
priority: %d
\n
"
,
(
char
*
)
data
,
size
,
priority
);
if
(
message_get
(
q
,
&
data
,
&
size
,
&
priority
))
goto
error
;
printf
(
"message:
\n
data: '%s'
\n
size: %d
\n
priority: %d
\n
"
,
(
char
*
)
data
,
size
,
priority
);
/* let's put a message before destroying the queue */
s
=
malloc
(
10
);
if
(
s
==
NULL
)
goto
error
;
sprintf
(
s
,
"hello"
);
if
(
message_put
(
q
,
s
,
6
,
0
))
goto
error
;
destroy_message_queue
(
q
);
return
0
;
error:
printf
(
"error
\n
"
);
return
1
;
}
#endif
openair2/UTIL/ASYNC_IF/message_queue.h
0 → 100644
View file @
5c0098e2
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2015 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file message_queue.h
* \brief this is the implementation of a message queue
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#ifndef MESSAGE_QUEUE_H
#define MESSAGE_QUEUE_H
#include <pthread.h>
#ifdef __cplusplus
extern
"C"
{
#endif
typedef
struct
message_t
{
void
*
data
;
int
size
;
int
priority
;
struct
message_t
*
next
;
}
message_t
;
typedef
struct
{
message_t
*
head
;
message_t
*
tail
;
volatile
int
count
;
pthread_mutex_t
*
mutex
;
pthread_cond_t
*
cond
;
}
message_queue_t
;
message_queue_t
*
new_message_queue
(
void
);
int
message_put
(
message_queue_t
*
queue
,
void
*
data
,
int
size
,
int
priority
);
int
message_get
(
message_queue_t
*
queue
,
void
**
data
,
int
*
size
,
int
*
priority
);
void
destroy_message_queue
(
message_queue_t
*
queue
);
#ifdef __cplusplus
}
#endif
#endif
/* MESSAGE_QUEUE_H */
openair2/UTIL/ASYNC_IF/socket_link.c
0 → 100644
View file @
5c0098e2
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2015 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file socket_link.c
* \brief this is the implementation of a TCP socket ASYNC IF
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#include "socket_link.h"
#include "log.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/ip.h>
#include <arpa/inet.h>
#include <stdint.h>
socket_link_t
*
new_link_server
(
int
port
)
{
socket_link_t
*
ret
=
NULL
;
int
reuse
;
struct
sockaddr_in
addr
;
socklen_t
addrlen
;
int
socket_server
=
-
1
;
ret
=
calloc
(
1
,
sizeof
(
socket_link_t
));
if
(
ret
==
NULL
)
{
LOG_E
(
MAC
,
"%s:%d: out of memory
\n
"
,
__FILE__
,
__LINE__
);
goto
error
;
}
ret
->
socket_fd
=
-
1
;
LOG_D
(
MAC
,
"create a new link server socket at port %d
\n
"
,
port
);
socket_server
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
socket_server
==
-
1
)
{
LOG_E
(
MAC
,
"%s:%d: socket: %s
\n
"
,
__FILE__
,
__LINE__
,
strerror
(
errno
));
goto
error
;
}
reuse
=
1
;
if
(
setsockopt
(
socket_server
,
SOL_SOCKET
,
SO_REUSEADDR
,
&
reuse
,
sizeof
(
reuse
))
==
-
1
)
{
LOG_E
(
MAC
,
"%s:%d: setsockopt: %s
\n
"
,
__FILE__
,
__LINE__
,
strerror
(
errno
));
goto
error
;
}
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
port
);
addr
.
sin_addr
.
s_addr
=
INADDR_ANY
;
if
(
bind
(
socket_server
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
==
-
1
)
{
LOG_E
(
MAC
,
"%s:%d: bind: %s
\n
"
,
__FILE__
,
__LINE__
,
strerror
(
errno
));
goto
error
;
}
if
(
listen
(
socket_server
,
5
))
{
LOG_E
(
MAC
,
"%s:%d: listen: %s
\n
"
,
__FILE__
,
__LINE__
,
strerror
(
errno
));
goto
error
;
}
addrlen
=
sizeof
(
addr
);
ret
->
socket_fd
=
accept
(
socket_server
,
(
struct
sockaddr
*
)
&
addr
,
&
addrlen
);
if
(
ret
->
socket_fd
==
-
1
)
{
LOG_E
(
MAC
,
"%s:%d: accept: %s
\n
"
,
__FILE__
,
__LINE__
,
strerror
(
errno
));
goto
error
;
}
close
(
socket_server
);
LOG_D
(
MAC
,
"connection from %s:%d
\n
"
,
inet_ntoa
(
addr
.
sin_addr
),
ntohs
(
addr
.
sin_port
));
return
ret
;
error:
close
(
socket_server
);
if
(
ret
!=
NULL
)
close
(
ret
->
socket_fd
);
free
(
ret
);
LOG_E
(
MAC
,
"ERROR in new_link_server (see above), returning NULL
\n
"
);
return
NULL
;
}
socket_link_t
*
new_link_client
(
char
*
server
,
int
port
)
{
socket_link_t
*
ret
=
NULL
;
struct
sockaddr_in
addr
;
ret
=
calloc
(
1
,
sizeof
(
socket_link_t
));
if
(
ret
==
NULL
)
{
LOG_E
(
MAC
,
"%s:%d: out of memory
\n
"
,
__FILE__
,
__LINE__
);
goto
error
;
}
ret
->
socket_fd
=
-
1
;
LOG_D
(
MAC
,
"create a new link client socket connecting to %s:%d
\n
"
,
server
,
port
);
ret
->
socket_fd
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
ret
->
socket_fd
==
-
1
)
{
LOG_E
(
MAC
,
"%s:%d: socket: %s
\n
"
,
__FILE__
,
__LINE__
,
strerror
(
errno
));
goto
error
;
}
addr
.
sin_family
=
AF_INET
;
addr
.
sin_port
=
htons
(
port
);
if
(
inet_aton
(
server
,
&
addr
.
sin_addr
)
==
0
)
{
LOG_E
(
MAC
,
"invalid IP address '%s', use a.b.c.d notation
\n
"
,
server
);
goto
error
;
}
if
(
connect
(
ret
->
socket_fd
,
(
struct
sockaddr
*
)
&
addr
,
sizeof
(
addr
))
==
-
1
)
{
LOG_E
(
MAC
,
"%s:%d: connect: %s
\n
"
,
__FILE__
,
__LINE__
,
strerror
(
errno
));
goto
error
;
}
LOG_D
(
MAC
,
"connection to %s:%d established
\n
"
,
inet_ntoa
(
addr
.
sin_addr
),
ntohs
(
addr
.
sin_port
));
return
ret
;
error:
if
(
ret
!=
NULL
)
close
(
ret
->
socket_fd
);
free
(
ret
);
LOG_E
(
MAC
,
"ERROR in new_link_client (see above), returning NULL
\n
"
);
return
NULL
;
}
/*
* return -1 on error and 0 if the sending was fine
*/
static
int
socket_send
(
int
socket_fd
,
void
*
buf
,
int
size
)
{
char
*
s
=
buf
;
int
l
;
while
(
size
)
{
l
=
send
(
socket_fd
,
s
,
size
,
MSG_NOSIGNAL
);
if
(
l
==
-
1
)
goto
error
;
if
(
l
==
0
)
{
LOG_E
(
MAC
,
"%s:%d: this cannot happen, normally...
\n
"
,
__FILE__
,
__LINE__
);
abort
();
}
size
-=
l
;
s
+=
l
;
}
return
0
;
error:
LOG_E
(
MAC
,
"socket_send: ERROR: %s
\n
"
,
strerror
(
errno
));
return
-
1
;
}
/*
* return -1 on error and 0 if the receiving was fine
*/
static
int
socket_receive
(
int
socket_fd
,
void
*
buf
,
int
size
)
{
char
*
s
=
buf
;
int
l
;
while
(
size
)
{
l
=
read
(
socket_fd
,
s
,
size
);
if
(
l
==
-
1
)
goto
error
;
if
(
l
==
0
)
goto
socket_closed
;
size
-=
l
;
s
+=
l
;
}
return
0
;
error:
LOG_E
(
MAC
,
"socket_receive: ERROR: %s
\n
"
,
strerror
(
errno
));
return
-
1
;
socket_closed:
LOG_E
(
MAC
,
"socket_receive: socket closed
\n
"
);
return
-
1
;
}
/*
* return -1 on error and 0 if the sending was fine
*/
int
link_send_packet
(
socket_link_t
*
link
,
void
*
data
,
int
size
)
{
char
sizebuf
[
4
];
int32_t
s
=
size
;
/* send the size first, maximum is 2^31 bytes */
sizebuf
[
0
]
=
(
s
>>
24
)
&
255
;
sizebuf
[
1
]
=
(
s
>>
16
)
&
255
;
sizebuf
[
2
]
=
(
s
>>
8
)
&
255
;
sizebuf
[
3
]
=
s
&
255
;
if
(
socket_send
(
link
->
socket_fd
,
sizebuf
,
4
)
==
-
1
)
goto
error
;
link
->
bytes_sent
+=
4
;
if
(
socket_send
(
link
->
socket_fd
,
data
,
size
)
==
-
1
)
goto
error
;
link
->
bytes_sent
+=
size
;
link
->
packets_sent
++
;
return
0
;
error:
return
-
1
;
}
/*
* return -1 on error and 0 if the sending was fine
*/
int
link_receive_packet
(
socket_link_t
*
link
,
void
**
ret_data
,
int
*
ret_size
)
{
unsigned
char
sizebuf
[
4
];
int32_t
size
;
void
*
data
=
NULL
;
/* received the size first, maximum is 2^31 bytes */
if
(
socket_receive
(
link
->
socket_fd
,
sizebuf
,
4
)
==
-
1
)
goto
error
;
size
=
(
sizebuf
[
0
]
<<
24
)
|
(
sizebuf
[
1
]
<<
16
)
|
(
sizebuf
[
2
]
<<
8
)
|
sizebuf
[
3
];
link
->
bytes_received
+=
4
;
data
=
malloc
(
size
);
if
(
data
==
NULL
)
{
LOG_E
(
MAC
,
"%s:%d: out of memory
\n
"
,
__FILE__
,
__LINE__
);
goto
error
;
}
if
(
socket_receive
(
link
->
socket_fd
,
data
,
size
)
==
-
1
)
goto
error
;
link
->
bytes_received
+=
size
;
link
->
packets_received
++
;
*
ret_data
=
data
;
*
ret_size
=
size
;
return
0
;
error:
free
(
data
);
*
ret_data
=
NULL
;
*
ret_size
=
0
;
return
-
1
;
}
/*
* return -1 on error, 0 if all is fine
*/
int
close_link
(
socket_link_t
*
link
)
{
close
(
link
->
socket_fd
);
memset
(
link
,
0
,
sizeof
(
socket_link_t
));
free
(
link
);
return
0
;
}
#ifdef SERVER_TEST
#include <inttypes.h>
int
main
(
void
)
{
void
*
data
;
int
size
;
socket_link_t
*
l
=
new_link_server
(
2210
);
if
(
l
==
NULL
)
{
printf
(
"no link created
\n
"
);
return
1
;
}
printf
(
"link is up
\n
"
);
printf
(
"server starts sleeping...
\n
"
);
/* this sleep is here to test for broken pipe. You can run "nc localhost 2210"
* and interrupt it quickly so that the server gets a 'broken' pipe on the
* following link_send_packet.
*/
sleep
(
1
);
printf
(
"... done
\n
"
);
if
(
link_send_packet
(
l
,
"hello
\n
"
,
6
+
1
)
||
link_send_packet
(
l
,
"world
\n
"
,
6
+
1
))
return
1
;
if
(
link_receive_packet
(
l
,
&
data
,
&
size
))
return
1
;
printf
(
"%s"
,
(
char
*
)
data
);
free
(
data
);
if
(
link_receive_packet
(
l
,
&
data
,
&
size
))
return
1
;
printf
(
"%s"
,
(
char
*
)
data
);
free
(
data
);
printf
(
"stats:
\n
"
);
printf
(
" sent packets %"
PRIu64
"
\n
"
,
l
->
packets_sent
);
printf
(
" sent bytes %"
PRIu64
"
\n
"
,
l
->
bytes_sent
);
printf
(
" received packets %"
PRIu64
"
\n
"
,
l
->
packets_received
);
printf
(
" received bytes %"
PRIu64
"
\n
"
,
l
->
bytes_received
);
if
(
close_link
(
l
))
return
1
;
printf
(
"link is down
\n
"
);
return
0
;
}
#endif
#ifdef CLIENT_TEST
#include <inttypes.h>
int
main
(
void
)
{
void
*
data
;
int
size
;
socket_link_t
*
l
=
new_link_client
(
"127.0.0.1"
,
2210
);
if
(
l
==
NULL
)
{
printf
(
"no link created
\n
"
);
return
1
;
}
printf
(
"link is up
\n
"
);
if
(
link_receive_packet
(
l
,
&
data
,
&
size
))
return
1
;
printf
(
"%s"
,
(
char
*
)
data
);
free
(
data
);
if
(
link_receive_packet
(
l
,
&
data
,
&
size
))
return
1
;
printf
(
"%s"
,
(
char
*
)
data
);
free
(
data
);
if
(
link_send_packet
(
l
,
"bye
\n
"
,
4
+
1
)
||
link_send_packet
(
l
,
"server
\n
"
,
7
+
1
))
return
1
;
printf
(
"stats:
\n
"
);
printf
(
" sent packets %"
PRIu64
"
\n
"
,
l
->
packets_sent
);
printf
(
" sent bytes %"
PRIu64
"
\n
"
,
l
->
bytes_sent
);
printf
(
" received packets %"
PRIu64
"
\n
"
,
l
->
packets_received
);
printf
(
" received bytes %"
PRIu64
"
\n
"
,
l
->
bytes_received
);
if
(
close_link
(
l
))
return
1
;
printf
(
"link is down
\n
"
);
return
0
;
}
#endif
openair2/UTIL/ASYNC_IF/socket_link.h
0 → 100644
View file @
5c0098e2
/*******************************************************************************
OpenAirInterface
Copyright(c) 1999 - 2015 Eurecom
OpenAirInterface is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenAirInterface is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenAirInterface.The full GNU General Public License is
included in this distribution in the file called "COPYING". If not,
see <http://www.gnu.org/licenses/>.
Contact Information
OpenAirInterface Admin: openair_admin@eurecom.fr
OpenAirInterface Tech : openair_tech@eurecom.fr
OpenAirInterface Dev : openair4g-devel@eurecom.fr
Address : Eurecom, Campus SophiaTech, 450 Route des Chappes, CS 50193 - 06904 Biot Sophia Antipolis cedex, FRANCE
*******************************************************************************/
/*! \file socket_link.h
* \brief this is the implementation of a TCP socket ASYNC IF
* \author Cedric Roux
* \date November 2015
* \version 1.0
* \email: cedric.roux@eurecom.fr
* @ingroup _mac
*/
#ifndef SOCKET_LINK_H
#define SOCKET_LINK_H
#include <stdint.h>
#ifdef __cplusplus
extern
"C"
{
#endif
typedef
struct
{
int
socket_fd
;
uint64_t
bytes_sent
;
uint64_t
packets_sent
;
uint64_t
bytes_received
;
uint64_t
packets_received
;
}
socket_link_t
;
socket_link_t
*
new_link_server
(
int
port
);
socket_link_t
*
new_link_client
(
char
*
server
,
int
port
);
int
link_send_packet
(
socket_link_t
*
link
,
void
*
data
,
int
size
);
int
link_receive_packet
(
socket_link_t
*
link
,
void
**
data
,
int
*
size
);
int
close_link
(
socket_link_t
*
link
);
#ifdef __cplusplus
}
#endif
#endif
/* SOCKET_LINK_H */
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment